Index: pgadmin/ctl/explainShape.cpp =================================================================== --- pgadmin/ctl/explainShape.cpp (revision 7597) +++ pgadmin/ctl/explainShape.cpp (working copy) @@ -41,6 +41,10 @@ #include "images/ex_seek.xpm" #include "images/ex_setop.xpm" #include "images/ex_result.xpm" +// Greenplum images +#include "images/ex_broadcast_motion.xpm" +#include "images/ex_redistribute_motion.xpm" +#include "images/ex_gather_motion.xpm" #define BMP_BORDER 3 @@ -178,6 +182,9 @@ if (token == wxT("Total")) return 0; else if (token == wxT("Trigger")) return 0; + else if (token == wxT("Settings:")) return 0; /* Greenplum */ + else if (token == wxT("Slice")) return 0; /* Greenplum */ + else if (token.Mid(0,6) == wxT("(slice")) return 0; /* Greenplum */ else if (token == wxT("Result")) s = new ExplainShape(ex_result_xpm, descr); else if (token == wxT("Append")) s = new ExplainShape(ex_append_xpm, descr); else if (token == wxT("Nested")) @@ -319,12 +326,20 @@ s = new ExplainShape(ex_scan_xpm, descr, 3, 2); } else if (token2 == wxT("Seek")) s = new ExplainShape(ex_seek_xpm, descr, 3, 2); - // Recursive Union + // Recursive Union else if (token == wxT("Recursive") && token2 == wxT("Union")) s = new ExplainShape(ex_recursive_union_xpm, descr); else if (token == wxT("WindowAgg")) s = new ExplainShape(ex_windowagg_xpm, descr); + // Greenplum additions + else if (token == wxT("Gather") && token2 ==wxT("Motion")) + s = new ExplainShape(ex_gather_motion_xpm, descr); + else if (token == wxT("Broadcast") && token2 ==wxT("Motion")) + s = new ExplainShape(ex_broadcast_motion_xpm, descr); + else if (token == wxT("Redistribute") && token2 ==wxT("Motion")) + s = new ExplainShape(ex_redistribute_motion_xpm, descr); + if (!s) s = new ExplainShape(ex_unknown_xpm, descr); Index: pgadmin/include/ctl/explainCanvas.h =================================================================== --- pgadmin/include/ctl/explainCanvas.h (revision 7597) +++ pgadmin/include/ctl/explainCanvas.h (working copy) @@ -47,7 +47,7 @@ ExplainShape(const char *bmp[], const wxString &description, long tokenNo=-1, long detailNo=-1); static ExplainShape *Create(long level, ExplainShape *last, const wxString &str); - void SetCondition(const wxString &str) { condition = str; } + void SetCondition(const wxString &str) { if (condition.Length()==0) condition = str; else condition += wxT(" ") + str; } long GetLevel() { return level; } wxRealPoint GetStartPoint(); wxRealPoint GetEndPoint(int kidNo); Index: pgadmin/include/frm/frmMain.h =================================================================== --- pgadmin/include/frm/frmMain.h (revision 7597) +++ pgadmin/include/frm/frmMain.h (working copy) @@ -90,12 +90,12 @@ ctlListView *GetDependenciesCtl(); ctlListView *GetReferencedBy(); ctlListView *GetReferencedByCtl(); - void SelectStatisticsTab() { listViews->SetSelection(1); }; + void SelectStatisticsTab() { listViews->SetSelection(1); }; void StoreServers(); int ReconnectServer(pgServer *server, bool restore = true); void ReportConnError(pgServer *server); pgServerCollection *GetServerCollection() { return serversObj; } - pgServer *ConnectToServer(const wxString& servername, bool restore = false); + pgServer *ConnectToServer(const wxString& servername, bool restore = false); void SetLastPluginUtility(pluginUtilityFactory *pluginFactory) { lastPluginUtility = pluginFactory; } pluginUtilityFactory *GetLastPluginUtility() { return lastPluginUtility; } @@ -123,8 +123,8 @@ actionFactory *newMenuFactory; actionFactory *debuggingMenuFactory; actionFactory *reportMenuFactory; - actionFactory *scriptingMenuFactory; - actionFactory *viewdataMenuFactory; + actionFactory *scriptingMenuFactory; + actionFactory *viewdataMenuFactory; wxStopWatch stopwatch; wxString timermsg; @@ -223,6 +223,13 @@ wxWindow *StartDialog(frmMain *form, pgObject *obj); }; +class greenplumHelpFactory : public actionFactory +{ +public: + greenplumHelpFactory(menuFactoryList *list, wxMenu *mnu, ctlMenuToolbar *toolbar, bool bigTool); + wxWindow *StartDialog(frmMain *form, pgObject *obj); +}; + class slonyHelpFactory : public actionFactory { public: Index: pgadmin/include/frm/frmOptions.h =================================================================== --- pgadmin/include/frm/frmOptions.h (revision 7597) +++ pgadmin/include/frm/frmOptions.h (working copy) @@ -39,6 +39,7 @@ void OnSlonyPathSelect(wxCommandEvent &ev); void OnPostgresqlPathSelect(wxCommandEvent &ev); void OnEnterprisedbPathSelect(wxCommandEvent &ev); + void OnGPDBPathSelect(wxCommandEvent &ev); void OnFontSelect(wxCommandEvent &ev); void OnOK(wxCommandEvent &ev); void OnCancel(wxCommandEvent &ev); Index: pgadmin/include/debugger/dbgPgConn.h =================================================================== --- pgadmin/include/debugger/dbgPgConn.h (revision 7597) +++ pgadmin/include/debugger/dbgPgConn.h (working copy) @@ -66,6 +66,7 @@ bool BackendMinimumVersion(int major, int minor); bool EdbMinimumVersion(int major, int minor); bool GetIsEdb(); + bool GetIsGreenplum(); DebuggerApiVersions DebuggerApiVersion(); wxString GetVersionString(); bool isConnected() const; // Returns true if the connection attempt succeeded @@ -89,6 +90,7 @@ frmDebugger *m_frame; int m_minorVersion, m_majorVersion; bool m_isEdb; + bool m_isGreenplum; DebuggerApiVersions m_debuggerApiVersion; }; Index: pgadmin/include/db/pgConn.h =================================================================== --- pgadmin/include/db/pgConn.h (revision 7597) +++ pgadmin/include/db/pgConn.h (working copy) @@ -87,14 +87,16 @@ bool HasPrivilege(const wxString &objTyp, const wxString &objName, const wxString &priv); bool HasFeature(int feature=0); bool BackendMinimumVersion(int major, int minor); + bool BackendMinimumVersion(int major, int minor, int patch); bool EdbMinimumVersion(int major, int minor); wxString SystemNamespaceRestriction(const wxString &nsp); int GetMajorVersion() const { return majorVersion; } int GetMinorVersion() const { return minorVersion; } bool GetIsEdb(); + bool GetIsGreenplum(); wxString EncryptPassword(const wxString &user, const wxString &password); - wxString qtDbString(const wxString& value); - pgConn *Duplicate(); + wxString qtDbString(const wxString& value); + pgConn *Duplicate(); static void ExamineLibpqVersion(); static double GetLibpqVersion() { return libpqVersion; } @@ -109,13 +111,13 @@ wxString GetHostName() const { return dbHostName; } wxString GetHostAddress() const { return dbHostAddress; } wxString GetDbname() const { return dbname; } - wxString GetName() const; + wxString GetName() const; bool GetNeedUtfConnectString() { return utfConnectString; } int GetPort() const { return atoi(PQport(conn)); }; wxString GetTTY() const { return wxString(PQtty(conn), *conv); } wxString GetOptions() const { return wxString(PQoptions(conn), *conv); } int GetSslMode() const { return save_sslmode; } - wxString GetSslModeName(); + wxString GetSslModeName(); int GetBackendPID() const { return PQbackendPID(conn); } int GetStatus() const; int GetLastResultStatus() const { return lastResultStatus; } @@ -163,14 +165,15 @@ wxString qtString(const wxString& value); bool features[32]; - int minorVersion, majorVersion; + int minorVersion, majorVersion, patchVersion; bool isEdb; + bool isGreenplum; wxString reservedNamespaces; - wxString save_server, save_database, save_username, save_password; - int save_port, save_sslmode; - OID save_oid; + wxString save_server, save_database, save_username, save_password; + int save_port, save_sslmode; + OID save_oid; }; #endif Index: pgadmin/include/pgAdmin3.h =================================================================== --- pgadmin/include/pgAdmin3.h (revision 7597) +++ pgadmin/include/pgAdmin3.h (working copy) @@ -98,6 +98,11 @@ extern wxString edbBackupAllExecutable; extern wxString edbRestoreExecutable; +// Helper app paths - Greenplum +extern wxString gpBackupExecutable; +extern wxString gpBackupAllExecutable; +extern wxString gpRestoreExecutable; + // // Support for additional functions included in the EnterpriseDB // version of libpq. These are enable via runtime loading of the Index: pgadmin/include/precomp.h =================================================================== --- pgadmin/include/precomp.h (revision 7597) +++ pgadmin/include/precomp.h (working copy) @@ -105,6 +105,7 @@ #include "dlg/dlgType.h" #include "dlg/dlgUser.h" #include "dlg/dlgView.h" +#include "dlg/dlgExtTable.h" #include "frm/frmAbout.h" #include "frm/frmBackup.h" @@ -187,6 +188,8 @@ #include "schema/pgType.h" #include "schema/pgUser.h" #include "schema/pgView.h" +#include "schema/pgExtTable.h" +#include "schema/pgResQueue.h" #include "slony/dlgRepCluster.h" #include "slony/dlgRepListen.h" Index: pgadmin/include/parser/keywords.h =================================================================== --- pgadmin/include/parser/keywords.h (revision 7597) +++ pgadmin/include/parser/keywords.h (working copy) @@ -34,9 +34,9 @@ typedef struct ScanKeyword { - const char *name; /* in lower case */ - int value; /* grammar's token code */ - int category; /* see codes above */ + const char *name; /* in lower case */ + int value; /* grammar's token code */ + int category; /* see codes above */ } ScanKeyword; extern const ScanKeyword *ScanKeywordLookup(const char *text); @@ -472,7 +472,12 @@ RAW_EDB = 815, RETURN_EDB = 816, SYSDATE_EDB = 817, - SYSTIMESTAMP_EDB = 818 + SYSTIMESTAMP_EDB = 818, + + /* The following additions are keywords in Greenplum Database */ + DISTRIBUTED_GP = 900, + LOG_P_GP = 901 + }; #endif /* KEYWORDS_H */ Index: pgadmin/include/schema/module.mk =================================================================== --- pgadmin/include/schema/module.mk (revision 7597) +++ pgadmin/include/schema/module.mk (working copy) @@ -49,7 +49,10 @@ $(srcdir)/include/schema/pgTrigger.h \ $(srcdir)/include/schema/pgType.h \ $(srcdir)/include/schema/pgUser.h \ - $(srcdir)/include/schema/pgView.h + $(srcdir)/include/schema/pgView.h \ + $(srcdir)/include/schema/pgExtTable.h \ + $(srcdir)/include/schema/pgResQueue.h \ + $(srcdir)/include/schema/pgPartition.h EXTRA_DIST += \ $(srcdir)/include/schema/module.mk Index: pgadmin/include/schema/pgTable.h =================================================================== --- pgadmin/include/schema/pgTable.h (revision 7597) +++ pgadmin/include/schema/pgTable.h (working copy) @@ -62,6 +62,9 @@ void iSetPrimaryKeyColNumbers(const wxString& s) {primaryKeyColNumbers = s; } wxString GetPrimaryKeyName() const { return primaryKeyName; } void iSetPrimaryKeyName(const wxString& s) {primaryKeyName = s; } + wxString GetDistributionColNumbers() const { return distributionColNumbers; } // for Greenplum + void iSetDistributionColNumbers(const wxString& s) { distributionColNumbers = s; if (s.Length() > 0) distributionIsRandom = false; } // for Greenplum + void iSetDistributionIsRandom() { distributionIsRandom = true; } double GetEstimatedRows() const { return estimatedRows; } void iSetEstimatedRows(const double d) { estimatedRows=d; } wxString GetTablespace() const { return tablespace; }; @@ -95,6 +98,14 @@ void iSetShowExtendedStatistics(bool b) { showExtendedStatistics = b; } wxString GetFillFactor() { return fillFactor; } void iSetFillFactor(const wxString& s) { fillFactor = s; } + wxString GetAppendOnly() { return appendOnly; } + void iSetAppendOnly(const wxString& s) { appendOnly = s; } + wxString GetCompressLevel() { return compressLevel; } + void iSetCompressLevel(const wxString& s) { compressLevel = s; } + wxString GetPartitionDef() { return partitionDef; } + void iSetPartitionDef(const wxString& s) { partitionDef = s; } + bool GetIsPartitioned() const { return isPartitioned || partitionDef.Length() > 0; } + void iSetIsPartitioned(bool b) { isPartitioned = b; } void iSetCustomAutoVacuumEnabled(bool b) { custom_autovacuum_enabled = b; } bool GetCustomAutoVacuumEnabled() { return custom_autovacuum_enabled; } @@ -132,14 +143,15 @@ wxString GetDeleteSql(ctlTree *browser); wxString GetHelpPage(bool forCreate) const; pgObject *Refresh(ctlTree *browser, const wxTreeItemId item); - void iSetTriggersEnabled(ctlTree *browser, bool enable); + void iSetTriggersEnabled(ctlTree *browser, bool enable); private: void UpdateInheritance(); bool GetVacuumHint(); - wxString GetCols(ctlTree *browser, size_t indent, wxString &QMs, bool withQM); - + wxString GetCols(ctlTree *browser, size_t indent, wxString &QMs, bool withQM); void AppendStuff(wxString &sql, ctlTree *browser, pgaFactory &factory); + void AppendStuffNoSql(wxString &sql, ctlTree *browser, pgaFactory &factory); + wxULongLong rows; double estimatedRows; wxString fillFactor, autovacuum_vacuum_threshold, @@ -147,15 +159,19 @@ autovacuum_analyze_scale_factor, autovacuum_vacuum_cost_delay, autovacuum_vacuum_cost_limit, autovacuum_freeze_min_age, autovacuum_freeze_max_age, autovacuum_freeze_table_age; - bool hasOids, hasSubclass, rowsCounted, isReplicated, showExtendedStatistics; + wxString appendOnly; + wxString compressLevel; + wxString partitionDef; + bool isPartitioned; + bool hasOids, hasSubclass, rowsCounted, isReplicated, showExtendedStatistics, distributionIsRandom; bool autovacuum_enabled, custom_autovacuum_enabled; long inheritedTableCount; wxString quotedInheritedTables, inheritedTables, primaryKey, quotedPrimaryKey, - primaryKeyName, primaryKeyColNumbers, tablespace; + primaryKeyName, primaryKeyColNumbers, tablespace, distributionColNumbers; wxArrayString quotedInheritedTablesList, inheritedTablesOidList; slSet *replicationSet; - OID tablespaceOid; + OID tablespaceOid; }; @@ -215,7 +231,7 @@ executePgstattupleFactory(menuFactoryList *list, wxMenu *mnu, ctlMenuToolbar *toolbar); wxWindow *StartDialog(frmMain *form, pgObject *obj); bool CheckEnable(pgObject *obj); - bool CheckChecked(pgObject *obj); + bool CheckChecked(pgObject *obj); }; class disableAllTriggersFactory : public contextActionFactory Index: pgadmin/include/schema/pgDatabase.h =================================================================== --- pgadmin/include/schema/pgDatabase.h (revision 7597) +++ pgadmin/include/schema/pgDatabase.h (working copy) @@ -40,6 +40,7 @@ pgDatabase *GetDatabase() const { return (pgDatabase*)this; } bool BackendMinimumVersion(int major, int minor) { return connection()->BackendMinimumVersion(major, minor); } + bool BackendMinimumVersion(int major, int minor, int patch) { return connection()->BackendMinimumVersion(major, minor, patch); } void ShowTreeDetail(ctlTree *browser, frmMain *form=0, ctlListView *properties=0, ctlSQLBox *sqlPane=0); void ShowHint(frmMain *form, bool force); @@ -80,7 +81,7 @@ wxString GetSearchPath() const { return searchPath; } wxString GetSchemaPrefix(const wxString &schemaname) const; wxString GetQuotedSchemaPrefix(const wxString &schemaname) const; - wxString GetDefaultSchema() { return defaultSchema; }; + wxString GetDefaultSchema() { return defaultSchema; }; bool GetConnected() { return connected; } bool GetSystemObject() const; long GetMissingFKs() const { return missingFKs; } @@ -129,7 +130,7 @@ int canDebugPlpgsql, canDebugEdbspl; - OID tablespaceOid; + OID tablespaceOid; }; class pgDatabaseCollection : public pgServerObjCollection Index: pgadmin/include/schema/pgRole.h =================================================================== --- pgadmin/include/schema/pgRole.h (revision 7597) +++ pgadmin/include/schema/pgRole.h (working copy) @@ -73,6 +73,8 @@ void iSetSuperuser(const bool b) { superuser=b; } bool GetUpdateCatalog() const { return updateCatalog; } void iSetUpdateCatalog(const bool b) { updateCatalog=b; } + wxString GetRolQueueName() const { return rolqueuename; } + void iSetRolQueueName(const wxString& newVal) { rolqueuename = newVal; } long GetConnectionLimit() const { return connectionLimit; } void iSetConnectionLimit(long newVal) { connectionLimit=newVal; } wxArrayString& GetRolesIn() { return rolesIn; } @@ -94,6 +96,7 @@ bool HasReferences() { return true; } private: wxString password; + wxString rolqueuename; wxDateTime accountExpires; bool superuser, createDatabase, createRole, updateCatalog, inherits, canLogin; long connectionLimit; Index: pgadmin/include/utils/misc.h =================================================================== --- pgadmin/include/utils/misc.h (revision 7597) +++ pgadmin/include/utils/misc.h (working copy) @@ -160,6 +160,7 @@ HELP_PGADMIN, HELP_POSTGRESQL, HELP_ENTERPRISEDB, + HELP_GREENPLUM, HELP_SLONY } HelpType; @@ -184,26 +185,27 @@ bool pgAppMinimumVersion(const wxString &cmd, const int majorVer, const int minorVer); bool isPgApp(const wxString &app); bool isEdbApp(const wxString &app); +bool isGpApp(const wxString &app); enum { EDB_PACKAGE, EDB_PACKAGEFUNCTION, - EDB_PACKAGEVARIABLE, + EDB_PACKAGEVARIABLE, - PGM_CATALOG, - PGM_CATALOGOBJECT, + PGM_CATALOG, + PGM_CATALOGOBJECT, PGM_CHECK, PGM_COLUMN, - PGM_CONSTRAINT, - PGM_DATABASE, + PGM_CONSTRAINT, + PGM_DATABASE, PGM_FOREIGNKEY, PGM_FUNCTION, PGM_INDEX, - PGM_OPCLASS, - PGM_OPFAMILY, + PGM_OPCLASS, + PGM_OPFAMILY, PGM_PRIMARYKEY, - PGM_ROLE, + PGM_ROLE, PGM_RULE, PGM_SCHEMA, PGM_SERVER, @@ -212,8 +214,10 @@ PGM_TABLESPACE, PGM_TRIGGER, PGM_UNKNOWN, - PGM_UNIQUE, + PGM_UNIQUE, PGM_VIEW, + PGM_EXTTABLE, + PGM_RESOURCE_QUEUE, PGM_JOB, PGM_SCHEDULE, Index: pgadmin/include/utils/sysSettings.h =================================================================== --- pgadmin/include/utils/sysSettings.h (revision 7597) +++ pgadmin/include/utils/sysSettings.h (working copy) @@ -56,6 +56,8 @@ void SetPostgresqlPath(const wxString &newval) { Write(wxT("PostgreSQLPath"), newval); } wxString GetEnterprisedbPath() const { wxString s; Read(wxT("EnterpriseDBPath"), &s, wxEmptyString); return s; } void SetEnterprisedbPath(const wxString &newval) { Write(wxT("EnterpriseDBPath"), newval); } + wxString GetGPDBPath() const { wxString s; Read(wxT("GreenplumDBPath"), &s, wxEmptyString); return s; } + void SetGPDBPath(const wxString &newval) { Write(wxT("GreenplumDBPath"), newval); } // Help paths wxString GetSlonyHelpPath(); @@ -64,6 +66,8 @@ void SetPgHelpPath(const wxString &newval) { Write(wxT("PostgreSQLHelpPath"), newval); } wxString GetEdbHelpPath(); void SetEdbHelpPath(const wxString &newval) { Write(wxT("EnterpriseDBHelpPath"), newval); } + wxString GetGpHelpPath(); + void SetGpHelpPath(const wxString &newval) { Write(wxT("GreenplumDBHelpPath"), newval); } // Copy options wxString GetCopyQuoteChar() const { wxString s; Read(wxT("Copy/QuoteChar"), &s, wxT("\"")); return s; } Index: pgadmin/include/images/module.mk =================================================================== --- pgadmin/include/images/module.mk (revision 7597) +++ pgadmin/include/images/module.mk (working copy) @@ -204,7 +204,13 @@ $(srcdir)/include/images/view.xpm \ $(srcdir)/include/images/viewdata.xpm \ $(srcdir)/include/images/viewfiltereddata.xpm \ - $(srcdir)/include/images/views.xpm + $(srcdir)/include/images/views.xpm \ + $(srcdir)/include/images/ex_broadcast_motion.xpm \ + $(srcdir)/include/images/ex_redistribute_motion.xpm \ + $(srcdir)/include/images/ex_gather_motion.xpm \ + $(srcdir)/include/images/exttable-sm.xpm \ + $(srcdir)/include/images/exttables.xpm \ + $(srcdir)/include/images/exttable.xpm EXTRA_DIST += \ $(srcdir)/include/images/module.mk \ Index: pgadmin/include/dlg/dlgView.h =================================================================== --- pgadmin/include/dlg/dlgView.h (revision 7597) +++ pgadmin/include/dlg/dlgView.h (working copy) @@ -30,11 +30,11 @@ pgObject *CreateObject(pgCollection *collection); pgObject *GetObject(); - void SetObject(pgObject *obj) { view = (pgView*)obj; } + void SetObject(pgObject *obj) { view = (pgView*)obj; } private: - virtual bool IsUpToDate(); + virtual bool IsUpToDate(); pgSchema *schema; pgView *view; Index: pgadmin/include/dlg/module.mk =================================================================== --- pgadmin/include/dlg/module.mk (revision 7597) +++ pgadmin/include/dlg/module.mk (working copy) @@ -53,6 +53,7 @@ $(srcdir)/include/dlg/dlgUser.h \ $(srcdir)/include/dlg/dlgView.h \ $(srcdir)/include/dlg/dlgManageMacros.h \ + $(srcdir)/include/dlg/dlgExtTable.h \ $(srcdir)/include/dlg/dlgSelectDatabase.h EXTRA_DIST += \ Index: pgadmin/pgAdmin3.cpp =================================================================== --- pgadmin/pgAdmin3.cpp (revision 7597) +++ pgadmin/pgAdmin3.cpp (working copy) @@ -91,6 +91,10 @@ wxString edbBackupAllExecutable; wxString edbRestoreExecutable; +wxString gpBackupExecutable; // complete filename of Greenplum's pg_dump, pg_dumpall and pg_restore, if available +wxString gpBackupAllExecutable; +wxString gpRestoreExecutable; + wxString loadPath; // Where the program is loaded from wxString dataDir; // The program data directory wxString docPath; // Where docs are stored @@ -283,6 +287,10 @@ wxLogInfo(wxT("EDB pg_dumpall: %s"), edbBackupAllExecutable.c_str()); wxLogInfo(wxT("EDB pg_restore: %s"), edbRestoreExecutable.c_str()); + wxLogInfo(wxT("Greenplum pg_dump : %s"), gpBackupExecutable.c_str()); + wxLogInfo(wxT("Greenplum pg_dumpall: %s"), gpBackupAllExecutable.c_str()); + wxLogInfo(wxT("Greenplum pg_restore: %s"), gpRestoreExecutable.c_str()); + #ifdef __WXGTK__ static pgRendererNative *renderer=new pgRendererNative(); wxRendererNative::Get(); @@ -381,6 +389,7 @@ InitHelp(); wxLogInfo(wxT("PG Help : %s"), settings->GetPgHelpPath().c_str()); wxLogInfo(wxT("EDB Help : %s"), settings->GetEdbHelpPath().c_str()); + wxLogInfo(wxT("Greenplum Help: %s"), settings->GetGpHelpPath().c_str()); wxLogInfo(wxT("Slony Help : %s"), settings->GetSlonyHelpPath().c_str()); #ifndef __WXDEBUG__ @@ -696,12 +705,18 @@ if (!isEdbApp(settings->GetEnterprisedbPath() + wxT("\\pg_dump.exe"))) settings->SetEnterprisedbPath(wxEmptyString); + + if (!isGpApp(settings->GetGPDBPath() + wxT("\\pg_dump.exe"))) + settings->SetGPDBPath(wxEmptyString); #else if (!isPgApp(settings->GetPostgresqlPath() + wxT("/pg_dump"))) settings->SetPostgresqlPath(wxEmptyString); if (!isEdbApp(settings->GetEnterprisedbPath() + wxT("/pg_dump"))) settings->SetEnterprisedbPath(wxEmptyString); + + if (!isGpApp(settings->GetGPDBPath() + wxT("/pg_dump"))) + settings->SetGPDBPath(wxEmptyString); #endif // Now, if either path is empty, start a search for helpers @@ -751,6 +766,8 @@ settings->SetPostgresqlPath(tmp.GetPath()); else if (isEdbApp(tmp.GetFullPath()) && settings->GetEnterprisedbPath().IsEmpty()) settings->SetEnterprisedbPath(tmp.GetPath()); + else if (isGpApp(tmp.GetFullPath()) && settings->GetGPDBPath().IsEmpty()) + settings->SetGPDBPath(tmp.GetPath()); } } @@ -761,6 +778,11 @@ { wxPathList path; + // The Windows code should really look at the %ProgramFiles% and %ProgramFiles(x86)% environment + // variables, and use their values if they exist instead of hard-coding "C:\\Program Files". + // if %ProgramFiles(x86)% is set, we are on 64 bit windows, and we should prefer this over %ProgramFiles% + // because it is where 32-bit apps get installed. + #ifdef __WXMSW__ path.Add(wxT("C:\\PostgresPlus\\8.4\\dbserver\\bin")); path.Add(wxT("C:\\PostgresPlus\\8.3\\dbserver\\bin")); @@ -838,6 +860,59 @@ } } + // Greenplum + if (settings->GetGPDBPath().IsEmpty()) + { + wxPathList path; + + // We should use $GPHOME_CLIENTS if it is set, but it rarely is. +#ifdef __WXMSW__ + // Ugly... Greenplum client releases have no predictable numbers, because the path is the server version + path.Add(wxT("c:\\Program Files\\Greenplum\\greenplum-clients-3.3\\bin")); + path.Add(wxT("c:\\Program Files (x86)\\Greenplum\\greenplum-clients-3.3\\bin")); + path.Add(wxT("c:\\Program Files\\Greenplum\\greenplum-clients-3.2\\bin")); + path.Add(wxT("c:\\Program Files (x86)\\Greenplum\\greenplum-clients-3.2\\bin")); + path.Add(wxT("c:\\Program Files\\Greenplum\\greenplum-clients-3.1.1.1\\bin")); + path.Add(wxT("c:\\Program Files (x86)\\Greenplum\\greenplum-clients-3.1.1.1\\bin")); + + path.Add(wxT("c:\\Program Files\\Greenplum\\greenplum-clients-3.3\\lib")); + path.Add(wxT("c:\\Program Files (x86)\\Greenplum\\greenplum-clients-3.3\\lib")); + path.Add(wxT("c:\\Program Files\\Greenplum\\greenplum-clients-3.2\\bin")); + path.Add(wxT("c:\\Program Files (x86)\\Greenplum\\greenplum-clients-3.2\\lib")); + path.Add(wxT("c:\\Program Files\\Greenplum\\greenplum-clients-3.1.1.1\\lib")); + path.Add(wxT("c:\\Program Files (x86)\\Greenplum\\greenplum-clients-3.1.1.1\\lib")); + + wxFileName tmp = path.FindValidPath(wxT("pg_dump.exe")); +#else + // Mac paths + + // Generic Unix paths + + path.Add(wxT("/usr/local/greenplum-clients-3.3\bin")); + path.Add(wxT("/opt/local/greenplum-clients-3.3\bin")); + path.Add(wxT("/usr/local/greenplum-clients-3.2\bin")); + path.Add(wxT("/opt/local/greenplum-clients-3.2\bin")); + path.Add(wxT("/usr/local/greenplum-clients-3.1.1.1\bin")); + path.Add(wxT("/opt/local/greenplum-clients-3.1.1.1\bin")); + + path.Add(wxT("/usr/local/greenplum-clients-3.3\lib")); + path.Add(wxT("/opt/local/greenplum-clients-3.3\lib")); + path.Add(wxT("/usr/local/greenplum-clients-3.2\lib")); + path.Add(wxT("/opt/local/greenplum-clients-3.2\lib")); + path.Add(wxT("/usr/local/greenplum-clients-3.1.1.1\lib")); + path.Add(wxT("/opt/local/greenplum-clients-3.1.1.1\lib")); + + + wxFileName tmp = path.FindValidPath(wxT("pg_dump")); +#endif + + if (tmp.FileExists()) + { + if (isGpApp(tmp.GetFullPath())) + settings->SetGPDBPath(tmp.GetPath()); + } + } + // Now setup and verify the paths for each individual helper #if defined(__WXMSW__) pgBackupExecutable = settings->GetPostgresqlPath() + wxT("\\pg_dump.exe"); @@ -847,6 +922,10 @@ edbBackupExecutable = settings->GetEnterprisedbPath() + wxT("\\pg_dump.exe"); edbBackupAllExecutable = settings->GetEnterprisedbPath() + wxT("\\pg_dumpall.exe"); edbRestoreExecutable = settings->GetEnterprisedbPath() + wxT("\\pg_restore.exe"); + + gpBackupExecutable = settings->GetGPDBPath() + wxT("\\pg_dump.exe"); + gpBackupAllExecutable = settings->GetGPDBPath() + wxT("\\pg_dumpall.exe"); + gpRestoreExecutable = settings->GetGPDBPath() + wxT("\\pg_restore.exe"); #else pgBackupExecutable = settings->GetPostgresqlPath() + wxT("/pg_dump"); pgBackupAllExecutable = settings->GetPostgresqlPath() + wxT("/pg_dumpall"); @@ -855,6 +934,10 @@ edbBackupExecutable = settings->GetEnterprisedbPath() + wxT("/pg_dump"); edbBackupAllExecutable = settings->GetEnterprisedbPath() + wxT("/pg_dumpall"); edbRestoreExecutable = settings->GetEnterprisedbPath() + wxT("/pg_restore"); + + gpBackupExecutable = settings->GetGPDBPath() + wxT("/pg_dump"); + gpBackupAllExecutable = settings->GetGPDBPath() + wxT("/pg_dumpall"); + gpRestoreExecutable = settings->GetGPDBPath() + wxT("/pg_restore"); #endif if (!isPgApp(pgBackupExecutable)) @@ -870,6 +953,13 @@ edbBackupAllExecutable = wxEmptyString; if (!isEdbApp(edbRestoreExecutable)) edbRestoreExecutable = wxEmptyString; + + if (!isGpApp(gpBackupExecutable)) + gpBackupExecutable = wxEmptyString; + if (!isGpApp(gpBackupAllExecutable)) + gpBackupAllExecutable = wxEmptyString; + if (!isGpApp(gpRestoreExecutable)) + gpRestoreExecutable = wxEmptyString; } wxString pgAdmin3::LocatePath(const wxString &pathToFind, const bool isFile) @@ -978,7 +1068,7 @@ { // Search for external docs. As Windows and *nix etc // are likely to be very different, we'll #ifdef them all. - wxPathList stdPaths, noPaths, pgPaths, edbPaths, slonyPaths; + wxPathList stdPaths, noPaths, pgPaths, edbPaths, gpPaths, slonyPaths; wxString sep = wxFileName::GetPathSeparator(); stdPaths.Add(docPath + sep + settings->GetCanonicalLanguageName()); @@ -1003,6 +1093,16 @@ edbPaths.Add(wxT("C:\\EnterpriseDB\\8.1\\dbserver\\doc\\html")); edbPaths.Add(wxT("C:\\EnterpriseDB\\8.0\\dbserver\\doc")); edbPaths.Add(wxT("C:\\EnterpriseDB\\8.0\\dbserver\\doc\\html")); + + gpPaths.Add(wxT("c:\\Program Files (x86)\\Greenplum\\greenplum-clients-3.3\\docs")); + gpPaths.Add(wxT("c:\\Program Files\\Greenplum\\greenplum-clients-3.3\\docs")); + gpPaths.Add(wxT("c:\\Program Files (x86)\\Greenplum\\greenplum-clients-3.2\\docs")); + gpPaths.Add(wxT("c:\\Program Files\\Greenplum\\greenplum-clients-3.2\\docs")); + gpPaths.Add(wxT("c:\\Program Files (x86)\\Greenplum\\greenplum-clients-3.1.1.1\\docs")); + gpPaths.Add(wxT("c:\\Program Files\\Greenplum\\greenplum-clients-3.1.1.1\\docs")); +; + + #else pgPaths.Add(wxT("/usr/local/pgsql/doc")); pgPaths.Add(wxT("/usr/local/pgsql/doc/html")); @@ -1029,11 +1129,26 @@ edbPaths.Add(wxT("/opt/local/enterprisedb/doc/html")); edbPaths.Add(wxT("/opt/local/edb/doc")); edbPaths.Add(wxT("/opt/local/edb/doc/html")); + + pgPaths.Add(wxT("/usr/local/greenplum-clients-3.3")); + pgPaths.Add(wxT("/usr/local/greenplum-clients-3.3\html")); + pgPaths.Add(wxT("/usr/local/greenplum-clients-3.3\docs")); + pgPaths.Add(wxT("/opt/local/greenplum-clients-3.3\docs")); + pgPaths.Add(wxT("/usr/local/greenplum-clients-3.3")); + pgPaths.Add(wxT("/usr/local/greenplum-clients-3.2\html")); + pgPaths.Add(wxT("/usr/local/greenplum-clients-3.2\docs")); + pgPaths.Add(wxT("/opt/local/greenplum-clients-3.2\docs")); + pgPaths.Add(wxT("/usr/local/greenplum-clients-3.1.1.1")); + pgPaths.Add(wxT("/usr/local/greenplum-clients-3.1.1.1\html")); + pgPaths.Add(wxT("/usr/local/greenplum-clients-3.1.1.1\docs")); + pgPaths.Add(wxT("/opt/local/greenplum-clients-3.1.1.1\docs")); + #endif // Slony will be installed into one of the DBMS directories slonyPaths.Add(pgPaths); slonyPaths.Add(edbPaths); + slonyPaths.Add(gpPaths); // First look for a chm, then a zip, then an hhp file. For PostgreSQL // and EnterpriseDB we'll then look for an index.html. No point for @@ -1041,6 +1156,7 @@ wxString pgHelpPath = settings->GetPgHelpPath(); wxString edbHelpPath = settings->GetEdbHelpPath(); + wxString gpHelpPath = settings->GetGpHelpPath(); wxString slonyHelpPath = settings->GetSlonyHelpPath(); #if defined (__WXMSW__) || wxUSE_LIBMSPACK @@ -1053,6 +1169,10 @@ edbHelpPath = GenerateHelpPath(wxT("enterprisedb.chm"), edbHelpPath, stdPaths, edbPaths); edbHelpPath = GenerateHelpPath(wxT("edb.chm"), edbHelpPath, stdPaths, edbPaths); + gpHelpPath = GenerateHelpPath(wxT("Greenplum.chm"), gpHelpPath, stdPaths, gpPaths); + gpHelpPath = GenerateHelpPath(wxT("GPDB.chm"), gpHelpPath, stdPaths, gpPaths); + gpHelpPath = GenerateHelpPath(wxT("GPClientTools.pdf"), gpHelpPath, stdPaths, gpPaths); + slonyHelpPath = GenerateHelpPath(wxT("Slony-I.chm"), slonyHelpPath, stdPaths, slonyPaths); slonyHelpPath = GenerateHelpPath(wxT("slony-i.chm"), slonyHelpPath, stdPaths, slonyPaths); slonyHelpPath = GenerateHelpPath(wxT("slony1.chm"), slonyHelpPath, stdPaths, slonyPaths); @@ -1068,6 +1188,8 @@ edbHelpPath = GenerateHelpPath(wxT("enterprisedb.zip"), edbHelpPath, stdPaths, edbPaths); edbHelpPath = GenerateHelpPath(wxT("edb.zip"), edbHelpPath, stdPaths, edbPaths); + gpHelpPath = GenerateHelpPath(wxT("Greenplum.zip"), gpHelpPath, stdPaths, gpPaths); + slonyHelpPath = GenerateHelpPath(wxT("Slony-I.zip"), slonyHelpPath, stdPaths, slonyPaths); slonyHelpPath = GenerateHelpPath(wxT("slony-i.zip"), slonyHelpPath, stdPaths, slonyPaths); slonyHelpPath = GenerateHelpPath(wxT("slony1.zip"), slonyHelpPath, stdPaths, slonyPaths); @@ -1082,6 +1204,8 @@ edbHelpPath = GenerateHelpPath(wxT("enterprisedb.hhp"), edbHelpPath, stdPaths, edbPaths); edbHelpPath = GenerateHelpPath(wxT("edb.hhp"), edbHelpPath, stdPaths, edbPaths); + gpHelpPath = GenerateHelpPath(wxT("Greenplum.hhp"), gpHelpPath, stdPaths, gpPaths); + slonyHelpPath = GenerateHelpPath(wxT("Slony-I.hhp"), slonyHelpPath, stdPaths, slonyPaths); slonyHelpPath = GenerateHelpPath(wxT("slony-i.hhp"), slonyHelpPath, stdPaths, slonyPaths); slonyHelpPath = GenerateHelpPath(wxT("slony1.hhp"), slonyHelpPath, stdPaths, slonyPaths); @@ -1096,6 +1220,8 @@ edbHelpPath = GenerateHelpPath(wxT("index.html"), edbHelpPath, noPaths, edbPaths); edbHelpPath = GenerateHelpPath(wxT("index.html"), edbHelpPath, noPaths, edbPaths); + gpHelpPath = GenerateHelpPath(wxT("index.html"), gpHelpPath, noPaths, gpPaths); + // If either path ends in index.html, remove the filename because we // just want the path. In this case, we should also add file:/// on // non-Windows platforms. @@ -1115,11 +1241,21 @@ #endif } + if (gpHelpPath.EndsWith(wxT("index.html"))) + { + gpHelpPath = gpHelpPath.Left(gpHelpPath.Length() - 10); +#ifndef __WXMSW__ + gpHelpPath = wxT("file:///") + gpHelpPath; +#endif + } + // Last resorts - if we still have no help by now, use the websites! if (pgHelpPath.IsEmpty()) pgHelpPath = wxT("http://www.postgresql.org/docs/current/static/"); if (edbHelpPath.IsEmpty()) edbHelpPath = wxT("http://www.enterprisedb.com/docs/en/8.3/server/"); + if (gpHelpPath.IsEmpty()) + gpHelpPath = wxT("http://www.postgresql.org/docs/8.2/static/"); // Greenplum doesn't have help on web site yet, use closest PostgreSQL help if (slonyHelpPath.IsEmpty()) slonyHelpPath = wxT("http://www.slony.info/documentation/"); @@ -1128,6 +1264,8 @@ settings->SetPgHelpPath(pgHelpPath); if (settings->GetEdbHelpPath().IsEmpty()) settings->SetEdbHelpPath(edbHelpPath); + if (settings->GetGpHelpPath().IsEmpty()) + settings->SetGpHelpPath(gpHelpPath); if (settings->GetSlonyHelpPath().IsEmpty()) settings->SetSlonyHelpPath(slonyHelpPath); } Index: pgadmin/frm/frmOptions.cpp =================================================================== --- pgadmin/frm/frmOptions.cpp (revision 7597) +++ pgadmin/frm/frmOptions.cpp (working copy) @@ -32,10 +32,12 @@ #define nbOptions CTRL_NOTEBOOK("nbOptions") #define txtPgHelpPath CTRL_TEXT("txtPgHelpPath") #define txtEdbHelpPath CTRL_TEXT("txtEdbHelpPath") +#define txtGpHelpPath CTRL_TEXT("txtGpHelpPath") #define txtSlonyHelpPath CTRL_TEXT("txtSlonyHelpPath") #define txtSlonyPath CTRL_TEXT("txtSlonyPath") #define txtPostgresqlPath CTRL_TEXT("txtPostgresqlPath") #define txtEnterprisedbPath CTRL_TEXT("txtEnterprisedbPath") +#define txtGPDBPath CTRL_TEXT("txtGPDBPath") #define txtSystemSchemas CTRL_TEXT("txtSystemSchemas") #define txtLogfile CTRL_TEXT("txtLogfile") #define radLoglevel CTRL_RADIOBOX("radLoglevel") @@ -72,6 +74,7 @@ EVT_BUTTON (XRCID("btnSlonyPath"), frmOptions::OnSlonyPathSelect) EVT_BUTTON (XRCID("btnPostgresqlPath"), frmOptions::OnPostgresqlPathSelect) EVT_BUTTON (XRCID("btnEnterprisedbPath"), frmOptions::OnEnterprisedbPathSelect) + EVT_BUTTON (XRCID("btnGPDBPath"), frmOptions::OnGPDBPathSelect) EVT_BUTTON (XRCID("btnDefault"), frmOptions::OnDefault) EVT_CHECKBOX(XRCID("chkSuppressHints"), frmOptions::OnSuppressHints) EVT_CHECKBOX(XRCID("chkResetHints"), frmOptions::OnResetHints) @@ -114,21 +117,22 @@ txtAutoRowCount->SetValue(NumToStr(settings->GetAutoRowCountThreshold())); txtIndent->SetValue(NumToStr(settings->GetIndentSpaces())); chkSpacesForTabs->SetValue(settings->GetSpacesForTabs()); - cbCopyQuote->SetSelection(settings->GetCopyQuoting()); - cbCopyQuoteChar->SetValue(settings->GetCopyQuoteChar()); + cbCopyQuote->SetSelection(settings->GetCopyQuoting()); + cbCopyQuoteChar->SetValue(settings->GetCopyQuoteChar()); wxString copySeparator = settings->GetCopyColSeparator(); if (copySeparator == wxT("\t")) copySeparator = _("Tab"); cbCopySeparator->SetValue(copySeparator); - chkTabForCompletion->SetValue(settings->GetTabForCompletion()); + chkTabForCompletion->SetValue(settings->GetTabForCompletion()); chkStickySql->SetValue(settings->GetStickySql()); chkIndicateNull->SetValue(settings->GetIndicateNull()); chkDoubleClickProperties->SetValue(settings->GetDoubleClickProperties()); txtPgHelpPath->SetValue(settings->GetPgHelpPath()); txtEdbHelpPath->SetValue(settings->GetEdbHelpPath()); + txtGpHelpPath->SetValue(settings->GetGpHelpPath()); txtSlonyHelpPath->SetValue(settings->GetSlonyHelpPath()); txtSystemSchemas->SetValue(settings->GetSystemSchemas()); @@ -137,7 +141,8 @@ txtSlonyPath->SetValue(settings->GetSlonyPath()); txtPostgresqlPath->SetValue(settings->GetPostgresqlPath()); txtEnterprisedbPath->SetValue(settings->GetEnterprisedbPath()); - chkIgnoreVersion->SetValue(settings->GetIgnoreVersion()); + txtGPDBPath->SetValue(settings->GetGPDBPath()); + chkIgnoreVersion->SetValue(settings->GetIgnoreVersion()); cbLanguage->Append(_("Default")); int sel=0; @@ -164,45 +169,48 @@ currentSqlFont=settings->GetSQLFont(); txtSqlFont->SetValue(currentSqlFont.GetNativeFontInfoUserDesc()); - // Load the display options - lstDisplay->Append(_("Databases")); - lstDisplay->Append(_("Tablespaces")); - lstDisplay->Append(_("pgAgent jobs")); - lstDisplay->Append(_("Groups/group roles")); - lstDisplay->Append(_("Users/login roles")); - lstDisplay->Append(_("Catalogs")); - lstDisplay->Append(_("Casts")); - lstDisplay->Append(_("Languages")); - lstDisplay->Append(_("Public synonyms")); - lstDisplay->Append(_("Schemas")); - lstDisplay->Append(_("Slony-I clusters")); - lstDisplay->Append(_("Aggregates")); - lstDisplay->Append(_("Conversions")); - lstDisplay->Append(_("Domains")); - lstDisplay->Append(_("Functions")); - lstDisplay->Append(_("Trigger functions")); - lstDisplay->Append(_("Packages")); - lstDisplay->Append(_("Procedures")); - lstDisplay->Append(_("Operators")); - lstDisplay->Append(_("Operator classes")); - lstDisplay->Append(_("Operator families")); - lstDisplay->Append(_("Rules")); - lstDisplay->Append(_("Sequences")); - lstDisplay->Append(_("Tables")); - lstDisplay->Append(_("FTS Configurations")); - lstDisplay->Append(_("FTS Dictionaries")); - lstDisplay->Append(_("FTS Parsers")); - lstDisplay->Append(_("FTS Templates")); - lstDisplay->Append(_("Types")); - lstDisplay->Append(_("Views")); + // Load the display options + lstDisplay->Append(_("Databases")); + lstDisplay->Append(_("Tablespaces")); + lstDisplay->Append(_("pgAgent jobs")); + lstDisplay->Append(_("Groups/group roles")); + lstDisplay->Append(_("Users/login roles")); + lstDisplay->Append(_("ResQueues/resource queues")); + lstDisplay->Append(_("Catalogs")); + lstDisplay->Append(_("Casts")); + lstDisplay->Append(_("Languages")); + lstDisplay->Append(_("Public synonyms")); + lstDisplay->Append(_("Schemas")); + lstDisplay->Append(_("Slony-I clusters")); + lstDisplay->Append(_("Aggregates")); + lstDisplay->Append(_("Conversions")); + lstDisplay->Append(_("Domains")); + lstDisplay->Append(_("Functions")); + lstDisplay->Append(_("Trigger functions")); + lstDisplay->Append(_("Packages")); + lstDisplay->Append(_("Procedures")); + lstDisplay->Append(_("Operators")); + lstDisplay->Append(_("Operator classes")); + lstDisplay->Append(_("Operator families")); + lstDisplay->Append(_("Rules")); + lstDisplay->Append(_("Sequences")); + lstDisplay->Append(_("Tables")); + lstDisplay->Append(_("External Tables")); + lstDisplay->Append(_("FTS Configurations")); + lstDisplay->Append(_("FTS Dictionaries")); + lstDisplay->Append(_("FTS Parsers")); + lstDisplay->Append(_("FTS Templates")); + lstDisplay->Append(_("Types")); + lstDisplay->Append(_("Views")); + lstDisplay->Append(_("Partitions")); - for (unsigned int x=0; x < lstDisplay->GetCount(); x++) - lstDisplay->Check(x, settings->GetDisplayOption(lstDisplay->GetString(x))); + for (unsigned int x=0; x < lstDisplay->GetCount(); x++) + lstDisplay->Check(x, settings->GetDisplayOption(lstDisplay->GetString(x))); chkSystemObjects->SetValue(settings->GetShowSystemObjects()); - wxCommandEvent e; - OnChangeCopyQuote(e); + wxCommandEvent e; + OnChangeCopyQuote(e); } @@ -222,7 +230,7 @@ // Reset the display options to the defaults. // Clear them all first for (unsigned int x=0; x < lstDisplay->GetCount(); x++) - lstDisplay->Check(x, settings->GetDisplayOption(lstDisplay->GetString(x), true)); + lstDisplay->Check(x, settings->GetDisplayOption(lstDisplay->GetString(x), true)); } void frmOptions::OnSlonyPathSelect(wxCommandEvent &ev) @@ -246,6 +254,13 @@ txtEnterprisedbPath->SetValue(dlg.GetPath()); } +void frmOptions::OnGPDBPathSelect(wxCommandEvent &ev) +{ + wxDirDialog dlg(this, _("Select directory with GreenplumDB utilities"), txtGPDBPath->GetValue()); + if (dlg.ShowModal() == wxID_OK) + txtGPDBPath->SetValue(dlg.GetPath()); +} + void frmOptions::OnSuppressHints(wxCommandEvent &ev) { if (chkSuppressHints->GetValue()) @@ -285,6 +300,17 @@ return; } +#ifdef __WXMSW__ + if (!txtGPDBPath->GetValue().IsEmpty() && !isGpApp(txtGPDBPath->GetValue() + wxT("\\pg_dump.exe"))) +#else + if (!txtGPDBPath->GetValue().IsEmpty() && !isGpApp(txtGPDBPath->GetValue() + wxT("/pg_dump"))) +#endif + { + wxMessageBox(_("The Greenplum bin path specified is not valid or does not contain a Greenplum pg_dump executable.\n\nPlease select another directory, or leave the path blank."), _("Error"), wxICON_ERROR); + txtGPDBPath->SetFocus(); + return; + } + // Clean and check the help paths txtPgHelpPath->SetValue(CleanHelpPath(txtPgHelpPath->GetValue())); if (!HelpPathValid(txtPgHelpPath->GetValue())) @@ -302,6 +328,14 @@ return; } + txtGpHelpPath->SetValue(CleanHelpPath(txtGpHelpPath->GetValue())); + if (!HelpPathValid(txtGpHelpPath->GetValue())) + { + wxMessageBox(_("An invalid GreenplumDB help path was specified.\n\nPlease enter another filename, directory or URL, or leave the path blank."), _("Error"), wxICON_ERROR); + txtGpHelpPath->SetFocus(); + return; + } + txtSlonyHelpPath->SetValue(CleanHelpPath(txtSlonyHelpPath->GetValue())); if (!HelpPathValid(txtSlonyHelpPath->GetValue())) { @@ -351,15 +385,15 @@ settings->SetAutoRowCountThreshold(StrToLong(txtAutoRowCount->GetValue())); settings->SetIndentSpaces(StrToLong(txtIndent->GetValue())); settings->SetSpacesForTabs(chkSpacesForTabs->GetValue()); - settings->SetCopyQuoting(cbCopyQuote->GetCurrentSelection()); - settings->SetCopyQuoteChar(cbCopyQuoteChar->GetValue()); - + settings->SetCopyQuoting(cbCopyQuote->GetCurrentSelection()); + settings->SetCopyQuoteChar(cbCopyQuoteChar->GetValue()); + wxString copySeparator = cbCopySeparator->GetValue(); if (copySeparator == _("Tab")) copySeparator = wxT("\t"); settings->SetCopyColSeparator(copySeparator); - settings->SetTabForCompletion(chkTabForCompletion->GetValue()); + settings->SetTabForCompletion(chkTabForCompletion->GetValue()); settings->SetStickySql(chkStickySql->GetValue()); settings->SetIndicateNull(chkIndicateNull->GetValue()); settings->SetDoubleClickProperties(chkDoubleClickProperties->GetValue()); @@ -370,6 +404,7 @@ settings->SetSlonyPath(txtSlonyPath->GetValue()); settings->SetPostgresqlPath(txtPostgresqlPath->GetValue()); settings->SetEnterprisedbPath(txtEnterprisedbPath->GetValue()); + settings->SetGPDBPath(txtGPDBPath->GetValue()); // Setup PostgreSQL/EnterpriseDB working paths #if defined(__WXMSW__) @@ -380,14 +415,22 @@ edbBackupExecutable = settings->GetEnterprisedbPath() + wxT("\\pg_dump.exe"); edbBackupAllExecutable = settings->GetEnterprisedbPath() + wxT("\\pg_dumpall.exe"); edbRestoreExecutable = settings->GetEnterprisedbPath() + wxT("\\pg_restore.exe"); + + gpBackupExecutable = settings->GetGPDBPath() + wxT("\\pg_dump.exe"); + gpBackupAllExecutable = settings->GetGPDBPath() + wxT("\\pg_dumpall.exe"); + gpRestoreExecutable = settings->GetGPDBPath() + wxT("\\pg_restore.exe"); #else pgBackupExecutable = settings->GetPostgresqlPath() + wxT("/pg_dump"); - pgBackupAllExecutable = settings->GetPostgresqlPath() + wxT("/pg_dumpall"); + pgBackupAllExecutable = settings->GetPostgresqlPath() + wxT("/pg_dumpall"); pgRestoreExecutable = settings->GetPostgresqlPath() + wxT("/pg_restore"); edbBackupExecutable = settings->GetEnterprisedbPath() + wxT("/pg_dump"); - edbBackupAllExecutable = settings->GetEnterprisedbPath() + wxT("/pg_dumpall"); + edbBackupAllExecutable = settings->GetEnterprisedbPath() + wxT("/pg_dumpall"); edbRestoreExecutable = settings->GetEnterprisedbPath() + wxT("/pg_restore"); + + gpBackupExecutable = settings->GetGPDBPath() + wxT("/pg_dump"); + gpBackupAllExecutable = settings->GetGPDBPath() + wxT("/pg_dumpall"); + gpRestoreExecutable = settings->GetGPDBPath() + wxT("/pg_restore"); #endif if (!wxFile::Exists(pgBackupExecutable)) @@ -404,28 +447,37 @@ if (!wxFile::Exists(edbRestoreExecutable)) edbRestoreExecutable = wxEmptyString; - settings->SetIgnoreVersion(chkIgnoreVersion->GetValue()); + if (!wxFile::Exists(gpBackupExecutable)) + gpBackupExecutable = wxEmptyString; + if (!wxFile::Exists(gpBackupAllExecutable)) + gpBackupAllExecutable = wxEmptyString; + if (!wxFile::Exists(gpRestoreExecutable)) + gpRestoreExecutable = wxEmptyString; + + settings->SetIgnoreVersion(chkIgnoreVersion->GetValue()); + if (chkResetHints->GetValue()) frmHint::ResetHints(); // Set the help paths settings->SetPgHelpPath(txtPgHelpPath->GetValue()); settings->SetEdbHelpPath(txtEdbHelpPath->GetValue()); + settings->SetGpHelpPath(txtGpHelpPath->GetValue()); settings->SetSlonyHelpPath(txtSlonyHelpPath->GetValue()); settings->SetSystemSchemas(txtSystemSchemas->GetValue()); - // Save the display options - int changed = false; - for (unsigned int x=0; x < lstDisplay->GetCount(); x++) - { - if (lstDisplay->IsChecked(x) != settings->GetDisplayOption(lstDisplay->GetString(x))) + // Save the display options + int changed = false; + for (unsigned int x=0; x < lstDisplay->GetCount(); x++) + { + if (lstDisplay->IsChecked(x) != settings->GetDisplayOption(lstDisplay->GetString(x))) { - changed = true; - settings->SetDisplayOption(lstDisplay->GetString(x), lstDisplay->IsChecked(x)); + changed = true; + settings->SetDisplayOption(lstDisplay->GetString(x), lstDisplay->IsChecked(x)); } - } + } if (chkSystemObjects->GetValue() != settings->GetShowSystemObjects()) { @@ -433,8 +485,8 @@ settings->SetShowSystemObjects(chkSystemObjects->GetValue()); } - // Change the language last, as it will affect our tests for changes - // in the display object types. + // Change the language last, as it will affect our tests for changes + // in the display object types. int langNo=cbLanguage->GetCurrentSelection(); if (langNo >= 0) { @@ -447,13 +499,13 @@ langId = (wxLanguage) langInfo->Language; } - settings->SetCanonicalLanguage(langId); + settings->SetCanonicalLanguage(langId); } - // Did any display options change? Display this message last, so it's - // in the selected language. - if (changed) - wxMessageBox(_("Changes to the display options may not be visible until the browser tree is refreshed."), _("Display options"), wxICON_INFORMATION); + // Did any display options change? Display this message last, so it's + // in the selected language. + if (changed) + wxMessageBox(_("Changes to the display options may not be visible until the browser tree is refreshed."), _("Display options"), wxICON_INFORMATION); Destroy(); } @@ -517,8 +569,8 @@ // Enable/disable the copy quote option as required. void frmOptions::OnChangeCopyQuote(wxCommandEvent& WXUNUSED(ev)) { - if (cbCopyQuote->GetValue() == _("None")) - cbCopyQuoteChar->Disable(); - else - cbCopyQuoteChar->Enable(); + if (cbCopyQuote->GetValue() == _("None")) + cbCopyQuoteChar->Disable(); + else + cbCopyQuoteChar->Enable(); } Index: pgadmin/frm/frmEditGrid.cpp =================================================================== --- pgadmin/frm/frmEditGrid.cpp (revision 7597) +++ pgadmin/frm/frmEditGrid.cpp (working copy) @@ -36,6 +36,7 @@ #include "schema/pgCatalogObject.h" #include "schema/pgTable.h" #include "schema/pgView.h" +#include "schema/pgExtTable.h" // wxAUI #include @@ -100,7 +101,7 @@ mainForm=form; thread=0; relkind=0; - limit=0; + limit=0; relid=(Oid)obj->GetOid(); editorCell = new sqlCell(); @@ -185,19 +186,19 @@ viewMenu->AppendSeparator(); viewMenu->Append(MNU_DEFAULTVIEW, _("&Default view\tCtrl-Alt-V"), _("Restore the default view.")); - + // Tools menu toolsMenu = new wxMenu(); toolsMenu->Append(MNU_OPTIONS, _("&Sort / Filter ..."),_("Sort / Filter options.")); toolsMenu->AppendSeparator(); toolsMenu->Append(MNU_INCLUDEFILTER, _("Filter By &Selection"),_("Display only those rows that have this value in this column.")); - toolsMenu->Append(MNU_EXCLUDEFILTER, _("Filter E&xcluding Selection"),_("Display only those rows that do not have this value in this column.")); - toolsMenu->Append(MNU_REMOVEFILTERS, _("&Remove Filter"),_("Remove all filters on this table")); - toolsMenu->AppendSeparator(); - toolsMenu->Append(MNU_ASCSORT, _("Sort &Ascending"),_("Append an ASCENDING sort condition based on this column")); - toolsMenu->Append(MNU_DESCSORT, _("Sort &Descending"),_("Append a DESCENDING sort condition based on this column")); - toolsMenu->Append(MNU_REMOVESORT, _("&Remove Sort"),_("Remove all sort conditions")); - + toolsMenu->Append(MNU_EXCLUDEFILTER, _("Filter E&xcluding Selection"),_("Display only those rows that do not have this value in this column.")); + toolsMenu->Append(MNU_REMOVEFILTERS, _("&Remove Filter"),_("Remove all filters on this table")); + toolsMenu->AppendSeparator(); + toolsMenu->Append(MNU_ASCSORT, _("Sort &Ascending"),_("Append an ASCENDING sort condition based on this column")); + toolsMenu->Append(MNU_DESCSORT, _("Sort &Descending"),_("Append a DESCENDING sort condition based on this column")); + toolsMenu->Append(MNU_REMOVESORT, _("&Remove Sort"),_("Remove all sort conditions")); + // Help menu helpMenu = new wxMenu(); helpMenu->Append(MNU_CONTENTS, _("&Help contents"),_("Open the helpfile.")); @@ -273,6 +274,14 @@ hasOids=false; tableName = view->GetSchema()->GetQuotedFullIdentifier() + wxT(".") + view->GetQuotedIdentifier(); } + else if (obj->GetMetaType() == PGM_EXTTABLE) + { + pgExtTable *exttable=(pgExtTable*)obj; + + relkind = 'x'; + hasOids=false; + tableName = exttable->GetSchema()->GetQuotedFullIdentifier() + wxT(".") + exttable->GetQuotedIdentifier(); + } else if (obj->GetMetaType() == PGM_CATALOGOBJECT) { pgCatalogObject *catobj=(pgCatalogObject*)obj; @@ -358,82 +367,82 @@ void frmEditGrid::SetSortCols(const wxString &cols) { - if (orderBy != cols) { - orderBy = cols; - } + if (orderBy != cols) { + orderBy = cols; + } } void frmEditGrid::SetFilter(const wxString &filter) { - if (rowFilter != filter) { - rowFilter = filter; - } + if (rowFilter != filter) { + rowFilter = filter; + } } void frmEditGrid::SetLimit(const int rowlimit) { - if (rowlimit != limit) { - limit = rowlimit; + if (rowlimit != limit) { + limit = rowlimit; - if (limit <= 0) - cbLimit->SetValue(_("No limit")); - else + if (limit <= 0) + cbLimit->SetValue(_("No limit")); + else cbLimit->SetValue(wxString::Format(_("%i rows"), limit)); - } + } } void frmEditGrid::OnLabelRightClick(wxGridEvent& event) { - wxMenu *xmenu = new wxMenu(); - wxArrayInt rows=sqlGrid->GetSelectedRows(); - xmenu->Append(MNU_COPY, _("&Copy"),_("Copy selected cells to clipboard.")); - xmenu->Append(MNU_PASTE, _("&Paste"),_("Paste data from the clipboard.")); - xmenu->Append(MNU_DELETE, _("&Delete"),_("Delete selected rows.")); + wxMenu *xmenu = new wxMenu(); + wxArrayInt rows=sqlGrid->GetSelectedRows(); + xmenu->Append(MNU_COPY, _("&Copy"),_("Copy selected cells to clipboard.")); + xmenu->Append(MNU_PASTE, _("&Paste"),_("Paste data from the clipboard.")); + xmenu->Append(MNU_DELETE, _("&Delete"),_("Delete selected rows.")); - if ((rows.GetCount()) && (!sqlGrid->IsCurrentCellReadOnly())) - { - xmenu->Enable(MNU_COPY, true); - xmenu->Enable(MNU_DELETE, true); - xmenu->Enable(MNU_PASTE, true); - } - else - { - xmenu->Enable(MNU_COPY, false); - xmenu->Enable(MNU_DELETE, false); - xmenu->Enable(MNU_PASTE, false); - } - sqlGrid->PopupMenu(xmenu); + if ((rows.GetCount()) && (!sqlGrid->IsCurrentCellReadOnly())) + { + xmenu->Enable(MNU_COPY, true); + xmenu->Enable(MNU_DELETE, true); + xmenu->Enable(MNU_PASTE, true); + } + else + { + xmenu->Enable(MNU_COPY, false); + xmenu->Enable(MNU_DELETE, false); + xmenu->Enable(MNU_PASTE, false); + } + sqlGrid->PopupMenu(xmenu); } void frmEditGrid::OnCellRightClick(wxGridEvent& event) { - wxMenu *xmenu = new wxMenu(); - - // If we cannot refresh, assume there is a data thread running. We cannot - // check thread->IsRunning() as it can crash if the thread is in some - // states :-( + wxMenu *xmenu = new wxMenu(); + + // If we cannot refresh, assume there is a data thread running. We cannot + // check thread->IsRunning() as it can crash if the thread is in some + // states :-( if (!toolBar->GetToolEnabled(MNU_REFRESH)) return; - sqlGrid->SetGridCursor(event.GetRow(), event.GetCol()); - - xmenu->Append(MNU_INCLUDEFILTER, _("Filter By &Selection"),_("Display only those rows that have this value in this column.")); - xmenu->Append(MNU_EXCLUDEFILTER, _("Filter E&xcluding Selection"),_("Display only those rows that do not have this value in this column.")); - xmenu->Append(MNU_REMOVEFILTERS, _("&Remove Filter"),_("Remove all filters on this table")); - xmenu->InsertSeparator(3); - xmenu->Append(MNU_ASCSORT, _("Sort &Ascending"),_("Append an ASCENDING sort condition based on this column")); - xmenu->Append(MNU_DESCSORT, _("Sort &Descending"),_("Append a DESCENDING sort condition based on this column")); - xmenu->Append(MNU_REMOVESORT, _("&Remove Sort"),_("Remove all sort conditions")); - - xmenu->Enable(MNU_INCLUDEFILTER, true); - xmenu->Enable(MNU_EXCLUDEFILTER, true); - xmenu->Enable(MNU_REMOVEFILTERS, true); - xmenu->Enable(MNU_ASCSORT, true); - xmenu->Enable(MNU_DESCSORT, true); - xmenu->Enable(MNU_REMOVESORT, true); - - sqlGrid->PopupMenu(xmenu); + sqlGrid->SetGridCursor(event.GetRow(), event.GetCol()); + + xmenu->Append(MNU_INCLUDEFILTER, _("Filter By &Selection"),_("Display only those rows that have this value in this column.")); + xmenu->Append(MNU_EXCLUDEFILTER, _("Filter E&xcluding Selection"),_("Display only those rows that do not have this value in this column.")); + xmenu->Append(MNU_REMOVEFILTERS, _("&Remove Filter"),_("Remove all filters on this table")); + xmenu->InsertSeparator(3); + xmenu->Append(MNU_ASCSORT, _("Sort &Ascending"),_("Append an ASCENDING sort condition based on this column")); + xmenu->Append(MNU_DESCSORT, _("Sort &Descending"),_("Append a DESCENDING sort condition based on this column")); + xmenu->Append(MNU_REMOVESORT, _("&Remove Sort"),_("Remove all sort conditions")); + + xmenu->Enable(MNU_INCLUDEFILTER, true); + xmenu->Enable(MNU_EXCLUDEFILTER, true); + xmenu->Enable(MNU_REMOVEFILTERS, true); + xmenu->Enable(MNU_ASCSORT, true); + xmenu->Enable(MNU_DESCSORT, true); + xmenu->Enable(MNU_REMOVESORT, true); + + sqlGrid->PopupMenu(xmenu); } @@ -467,174 +476,174 @@ void frmEditGrid::OnIncludeFilter(wxCommandEvent &event) { - int curcol=sqlGrid->GetGridCursorCol(); - int currow=sqlGrid->GetGridCursorRow(); - - sqlTable *table=sqlGrid->GetTable(); - wxString column_label = qtIdent(table->GetColLabelValueUnformatted(curcol)); - wxString new_filter_string; - - size_t old_filter_string_length = GetFilter().Trim().Len(); - - if (old_filter_string_length > 0) { - new_filter_string = GetFilter().Trim() + wxT(" \n AND "); - } - - if (table->IsColText(curcol)) { + int curcol=sqlGrid->GetGridCursorCol(); + int currow=sqlGrid->GetGridCursorRow(); + + sqlTable *table=sqlGrid->GetTable(); + wxString column_label = qtIdent(table->GetColLabelValueUnformatted(curcol)); + wxString new_filter_string; + + size_t old_filter_string_length = GetFilter().Trim().Len(); + + if (old_filter_string_length > 0) { + new_filter_string = GetFilter().Trim() + wxT(" \n AND "); + } + + if (table->IsColText(curcol)) { - if (sqlGrid->GetCellValue(currow, curcol).IsNull()) { - new_filter_string += column_label + wxT(" IS NULL "); - } else { - - if (sqlGrid->GetCellValue(currow, curcol) == wxT("\'\'")) { - new_filter_string += column_label + wxT(" = ''"); - } else { - new_filter_string += column_label + wxT(" = ") + connection->qtDbString(sqlGrid->GetCellValue(currow, curcol)) + wxT(" "); - } - } - } else { - - if (sqlGrid->GetCellValue(currow, curcol).IsNull()) { - new_filter_string += column_label + wxT(" IS NULL "); - } else { - new_filter_string += column_label + wxT(" = ") + sqlGrid->GetCellValue(currow, curcol); - } - } - - SetFilter(new_filter_string); - - Go(); + if (sqlGrid->GetCellValue(currow, curcol).IsNull()) { + new_filter_string += column_label + wxT(" IS NULL "); + } else { + + if (sqlGrid->GetCellValue(currow, curcol) == wxT("\'\'")) { + new_filter_string += column_label + wxT(" = ''"); + } else { + new_filter_string += column_label + wxT(" = ") + connection->qtDbString(sqlGrid->GetCellValue(currow, curcol)) + wxT(" "); + } + } + } else { + + if (sqlGrid->GetCellValue(currow, curcol).IsNull()) { + new_filter_string += column_label + wxT(" IS NULL "); + } else { + new_filter_string += column_label + wxT(" = ") + sqlGrid->GetCellValue(currow, curcol); + } + } + + SetFilter(new_filter_string); + + Go(); } void frmEditGrid::OnExcludeFilter(wxCommandEvent &event) { - int curcol=sqlGrid->GetGridCursorCol(); - int currow=sqlGrid->GetGridCursorRow(); - - sqlTable *table=sqlGrid->GetTable(); - wxString column_label = qtIdent(table->GetColLabelValueUnformatted(curcol)); - wxString new_filter_string; - - size_t old_filter_string_length = GetFilter().Trim().Len(); - - if (old_filter_string_length > 0) { - new_filter_string = GetFilter().Trim() + wxT(" \n AND "); - } - - if (table->IsColText(curcol)) { - if (sqlGrid->GetCellValue(currow, curcol).IsNull()) { - new_filter_string += column_label + wxT(" IS NOT NULL "); - } else { - - if (sqlGrid->GetCellValue(currow, curcol) == wxT("\'\'")) { - new_filter_string += column_label + wxString::Format(_(" IS DISTINCT FROM '' ")) ; - } else { - new_filter_string += column_label + wxT(" IS DISTINCT FROM ") + connection->qtDbString(sqlGrid->GetCellValue(currow, curcol)) + wxT(" "); - } - } - } else { - - if (sqlGrid->GetCellValue(currow, curcol).IsNull()) { - new_filter_string += column_label + wxT(" IS NOT NULL ") ; - } else { - new_filter_string += column_label + wxT(" IS DISTINCT FROM ") + sqlGrid->GetCellValue(currow, curcol); - } - } + int curcol=sqlGrid->GetGridCursorCol(); + int currow=sqlGrid->GetGridCursorRow(); + + sqlTable *table=sqlGrid->GetTable(); + wxString column_label = qtIdent(table->GetColLabelValueUnformatted(curcol)); + wxString new_filter_string; + + size_t old_filter_string_length = GetFilter().Trim().Len(); + + if (old_filter_string_length > 0) { + new_filter_string = GetFilter().Trim() + wxT(" \n AND "); + } + + if (table->IsColText(curcol)) { + if (sqlGrid->GetCellValue(currow, curcol).IsNull()) { + new_filter_string += column_label + wxT(" IS NOT NULL "); + } else { + + if (sqlGrid->GetCellValue(currow, curcol) == wxT("\'\'")) { + new_filter_string += column_label + wxString::Format(_(" IS DISTINCT FROM '' ")) ; + } else { + new_filter_string += column_label + wxT(" IS DISTINCT FROM ") + connection->qtDbString(sqlGrid->GetCellValue(currow, curcol)) + wxT(" "); + } + } + } else { + + if (sqlGrid->GetCellValue(currow, curcol).IsNull()) { + new_filter_string += column_label + wxT(" IS NOT NULL ") ; + } else { + new_filter_string += column_label + wxT(" IS DISTINCT FROM ") + sqlGrid->GetCellValue(currow, curcol); + } + } - SetFilter(new_filter_string); - - Go(); + SetFilter(new_filter_string); + + Go(); } void frmEditGrid::OnRemoveFilters(wxCommandEvent &event) { - SetFilter(wxT("")); - - Go(); + SetFilter(wxT("")); + + Go(); } void frmEditGrid::OnAscSort(wxCommandEvent &ev) { - int curcol=sqlGrid->GetGridCursorCol(); - - sqlTable *table=sqlGrid->GetTable(); - wxString column_label = qtIdent(table->GetColLabelValueUnformatted(curcol)); - wxString old_sort_string = GetSortCols().Trim(); - wxString new_sort_string; - - if (old_sort_string.Find(column_label) == wxNOT_FOUND) - { - if (old_sort_string.Len() > 0) - new_sort_string = old_sort_string + wxT(" , "); + int curcol=sqlGrid->GetGridCursorCol(); + + sqlTable *table=sqlGrid->GetTable(); + wxString column_label = qtIdent(table->GetColLabelValueUnformatted(curcol)); + wxString old_sort_string = GetSortCols().Trim(); + wxString new_sort_string; + + if (old_sort_string.Find(column_label) == wxNOT_FOUND) + { + if (old_sort_string.Len() > 0) + new_sort_string = old_sort_string + wxT(" , "); - new_sort_string += column_label + wxT(" ASC "); - } - else - { - if (old_sort_string.Find(column_label + wxT(" ASC")) == wxNOT_FOUND) - { - // Previous occurrence was for DESCENDING sort - new_sort_string = old_sort_string; - new_sort_string.Replace(column_label + wxT(" DESC"), column_label + wxT(" ASC")); - } - else - { - // Previous occurrence was for ASCENDING sort. Nothing to do - new_sort_string = old_sort_string; - } - } + new_sort_string += column_label + wxT(" ASC "); + } + else + { + if (old_sort_string.Find(column_label + wxT(" ASC")) == wxNOT_FOUND) + { + // Previous occurrence was for DESCENDING sort + new_sort_string = old_sort_string; + new_sort_string.Replace(column_label + wxT(" DESC"), column_label + wxT(" ASC")); + } + else + { + // Previous occurrence was for ASCENDING sort. Nothing to do + new_sort_string = old_sort_string; + } + } - SetSortCols(new_sort_string); - - Go(); + SetSortCols(new_sort_string); + + Go(); } void frmEditGrid::OnDescSort(wxCommandEvent &ev) { - int curcol=sqlGrid->GetGridCursorCol(); - - sqlTable *table=sqlGrid->GetTable(); - wxString column_label = qtIdent(table->GetColLabelValueUnformatted(curcol)); - wxString old_sort_string = GetSortCols().Trim(); - wxString new_sort_string; - - if (old_sort_string.Find(column_label) == wxNOT_FOUND) - { - if (old_sort_string.Len() > 0) - new_sort_string = old_sort_string + wxT(" , "); - - new_sort_string += column_label + wxT(" DESC "); - } - else - { - if (old_sort_string.Find(column_label + wxT(" DESC")) == wxNOT_FOUND) - { - // Previous occurrence was for ASCENDING sort - new_sort_string = old_sort_string; - new_sort_string.Replace(column_label + wxT(" ASC"), column_label + wxT(" DESC")); - } - else - { - // Previous occurrence was for DESCENDING sort. Nothing to do - new_sort_string = old_sort_string; - } - } + int curcol=sqlGrid->GetGridCursorCol(); + + sqlTable *table=sqlGrid->GetTable(); + wxString column_label = qtIdent(table->GetColLabelValueUnformatted(curcol)); + wxString old_sort_string = GetSortCols().Trim(); + wxString new_sort_string; + + if (old_sort_string.Find(column_label) == wxNOT_FOUND) + { + if (old_sort_string.Len() > 0) + new_sort_string = old_sort_string + wxT(" , "); + + new_sort_string += column_label + wxT(" DESC "); + } + else + { + if (old_sort_string.Find(column_label + wxT(" DESC")) == wxNOT_FOUND) + { + // Previous occurrence was for ASCENDING sort + new_sort_string = old_sort_string; + new_sort_string.Replace(column_label + wxT(" ASC"), column_label + wxT(" DESC")); + } + else + { + // Previous occurrence was for DESCENDING sort. Nothing to do + new_sort_string = old_sort_string; + } + } - SetSortCols(new_sort_string); + SetSortCols(new_sort_string); - Go(); + Go(); } void frmEditGrid::OnRemoveSort(wxCommandEvent &ev) { - SetSortCols(wxT("")); - - Go(); + SetSortCols(wxT("")); + + Go(); } @@ -647,7 +656,7 @@ } else { - if (editorCell->IsSet()) + if (editorCell->IsSet()) { if (wxTheClipboard->Open()) { @@ -655,12 +664,12 @@ wxTheClipboard->Close(); } } - else if(sqlGrid->GetNumberRows() > 0) - { - int copied; + else if(sqlGrid->GetNumberRows() > 0) + { + int copied; copied = sqlGrid->Copy(); SetStatusText(wxString::Format(_("Data from %d rows copied to clipboard."), copied)); - } + } } } @@ -758,31 +767,31 @@ { case WXK_DELETE: { - if (editorCell->IsSet() || !toolBar->GetToolEnabled(MNU_DELETE)) - { - if (!sqlGrid->IsCurrentCellReadOnly()) - { - sqlGrid->EnableCellEditControl(); - sqlGrid->ShowCellEditControl(); + if (editorCell->IsSet() || !toolBar->GetToolEnabled(MNU_DELETE)) + { + if (!sqlGrid->IsCurrentCellReadOnly()) + { + sqlGrid->EnableCellEditControl(); + sqlGrid->ShowCellEditControl(); - wxGridCellEditor *edit=sqlGrid->GetCellEditor(currow, curcol); - if (edit) - { - wxControl *ctl=edit->GetControl(); - if (ctl) - { - wxTextCtrl *txt=wxDynamicCast(ctl, wxTextCtrl); - if (txt) - txt->SetValue(wxEmptyString); - } - edit->DecRef(); - } - } - } - else - { - OnDelete(ev); - } + wxGridCellEditor *edit=sqlGrid->GetCellEditor(currow, curcol); + if (edit) + { + wxControl *ctl=edit->GetControl(); + if (ctl) + { + wxTextCtrl *txt=wxDynamicCast(ctl, wxTextCtrl); + if (txt) + txt->SetValue(wxEmptyString); + } + edit->DecRef(); + } + } + } + else + { + OnDelete(ev); + } return; } case WXK_RETURN: @@ -1004,31 +1013,31 @@ dlgEditGridOptions *winOptions = new dlgEditGridOptions(this, connection, tableName, sqlGrid); if (winOptions->ShowModal()) - Go(); + Go(); } template < class T > int ArrayCmp(T *a, T *b) { - if (*a == *b) - return 0; + if (*a == *b) + return 0; - if (*a > *b) - return 1; - else - return -1; + if (*a > *b) + return 1; + else + return -1; } void frmEditGrid::OnDelete(wxCommandEvent& event) { // Don't bugger about with keypresses to the scratch pad. if (FindFocus() == scratchPad) - { - event.Skip(); - return; - } - + { + event.Skip(); + return; + } + if (editorCell->IsSet()) { if (sqlGrid->GetTable()->IsColBoolean(sqlGrid->GetGridCursorCol())) @@ -1058,17 +1067,17 @@ else prompt.Printf(_("Are you sure you wish to delete the %d selected rows?"), i); - wxMessageDialog msg(this, prompt, _("Delete rows?"), wxYES_NO | wxICON_QUESTION); + wxMessageDialog msg(this, prompt, _("Delete rows?"), wxYES_NO | wxICON_QUESTION); if (msg.ShowModal() != wxID_YES) return; sqlGrid->BeginBatch(); - // Sort the grid so we always delete last->first, otherwise we - // could end up deleting anything because the array returned by - // GetSelectedRows is in the order that rows were selected by - // the user. - delrows.Sort(ArrayCmp); + // Sort the grid so we always delete last->first, otherwise we + // could end up deleting anything because the array returned by + // GetSelectedRows is in the order that rows were selected by + // the user. + delrows.Sort(ArrayCmp); // don't care a lot about optimizing here; doing it line by line // just as sqlTable::DeleteRows does @@ -1079,9 +1088,9 @@ i > 0 && show_continue_message) { - wxMessageDialog msg(this, wxString::Format(_("There was an error deleting the previous record.\nAre you sure you wish to delete the remaining %d rows ?"), i), _("Delete more records ?"), wxYES_NO | wxICON_QUESTION); - if (msg.ShowModal() != wxID_YES) - break; + wxMessageDialog msg(this, wxString::Format(_("There was an error deleting the previous record.\nAre you sure you wish to delete the remaining %d rows ?"), i), _("Delete more records ?"), wxYES_NO | wxICON_QUESTION); + if (msg.ShowModal() != wxID_YES) + break; else show_continue_message = false; } @@ -1164,25 +1173,25 @@ void frmEditGrid::ShowForm(bool filter) { - bool abort = false; + bool abort = false; if (relkind == 'r' || relkind == 'v') - { - if (filter) - { - dlgEditGridOptions *winOptions = new dlgEditGridOptions(this, connection, tableName, sqlGrid); - abort = !(winOptions->ShowModal()); - } - if (abort) { + { + if (filter) + { + dlgEditGridOptions *winOptions = new dlgEditGridOptions(this, connection, tableName, sqlGrid); + abort = !(winOptions->ShowModal()); + } + if (abort) { // Hack to ensure there's a table for ~wxGrid() to delete sqlGrid->CreateGrid(0, 0); - Close(); - Destroy(); - } else { + Close(); + Destroy(); + } else { Show(true); - Go(); - } - } + Go(); + } + } else { wxLogError(__("No Table or view.")); @@ -1203,7 +1212,7 @@ !cbLimit->GetValue().BeforeFirst(' ').ToLong(&templong)) { wxLogError(_("The row limit must be an integer number or 'No limit'")); - return; + return; } if (cbLimit->GetValue() == _("No limit")) @@ -1229,7 +1238,7 @@ toolsMenu->Enable(MNU_REMOVEFILTERS, false); toolsMenu->Enable(MNU_ASCSORT, false); toolsMenu->Enable(MNU_DESCSORT, false); - toolsMenu->Enable(MNU_REMOVESORT, false); + toolsMenu->Enable(MNU_REMOVESORT, false); // Stash the column sizes so we can reset them wxArrayInt colWidths; @@ -1250,8 +1259,8 @@ { qry += wxT("\n ORDER BY ") + orderBy; } - if (limit > 0) - qry += wxT(" LIMIT ") + wxString::Format(wxT("%i"), limit); + if (limit > 0) + qry += wxT(" LIMIT ") + wxString::Format(wxT("%i"), limit); thread=new pgQueryThread(connection, qry); if (thread->Create() != wxTHREAD_NO_ERROR) @@ -1262,13 +1271,13 @@ toolBar->EnableTool(MNU_OPTIONS, true); toolsMenu->Enable(MNU_OPTIONS, true); toolsMenu->Enable(MNU_INCLUDEFILTER, true); - toolsMenu->Enable(MNU_EXCLUDEFILTER, true); - toolsMenu->Enable(MNU_REMOVEFILTERS, true); - toolsMenu->Enable(MNU_ASCSORT, true); - toolsMenu->Enable(MNU_DESCSORT, true); - toolsMenu->Enable(MNU_REMOVESORT, true); + toolsMenu->Enable(MNU_EXCLUDEFILTER, true); + toolsMenu->Enable(MNU_REMOVEFILTERS, true); + toolsMenu->Enable(MNU_ASCSORT, true); + toolsMenu->Enable(MNU_DESCSORT, true); + toolsMenu->Enable(MNU_REMOVESORT, true); - return; + return; } thread->Run(); @@ -1278,19 +1287,19 @@ wxTheApp->Yield(true); wxMilliSleep(10); } - + if (!thread) { toolBar->EnableTool(MNU_REFRESH, true); viewMenu->Enable(MNU_REFRESH, true); toolBar->EnableTool(MNU_OPTIONS, true); toolsMenu->Enable(MNU_OPTIONS, true); - toolsMenu->Enable(MNU_INCLUDEFILTER, true); - toolsMenu->Enable(MNU_EXCLUDEFILTER, true); - toolsMenu->Enable(MNU_REMOVEFILTERS, true); - toolsMenu->Enable(MNU_ASCSORT, true); - toolsMenu->Enable(MNU_DESCSORT, true); - toolsMenu->Enable(MNU_REMOVESORT, true); + toolsMenu->Enable(MNU_INCLUDEFILTER, true); + toolsMenu->Enable(MNU_EXCLUDEFILTER, true); + toolsMenu->Enable(MNU_REMOVEFILTERS, true); + toolsMenu->Enable(MNU_ASCSORT, true); + toolsMenu->Enable(MNU_DESCSORT, true); + toolsMenu->Enable(MNU_REMOVESORT, true); return; } @@ -1301,12 +1310,12 @@ viewMenu->Enable(MNU_REFRESH, true); toolBar->EnableTool(MNU_OPTIONS, true); toolsMenu->Enable(MNU_OPTIONS, true); - toolsMenu->Enable(MNU_INCLUDEFILTER, true); - toolsMenu->Enable(MNU_EXCLUDEFILTER, true); - toolsMenu->Enable(MNU_REMOVEFILTERS, true); - toolsMenu->Enable(MNU_ASCSORT, true); - toolsMenu->Enable(MNU_DESCSORT, true); - toolsMenu->Enable(MNU_REMOVESORT, true); + toolsMenu->Enable(MNU_INCLUDEFILTER, true); + toolsMenu->Enable(MNU_EXCLUDEFILTER, true); + toolsMenu->Enable(MNU_REMOVEFILTERS, true); + toolsMenu->Enable(MNU_ASCSORT, true); + toolsMenu->Enable(MNU_DESCSORT, true); + toolsMenu->Enable(MNU_REMOVESORT, true); return; } SetStatusText(wxString::Format(_("%d rows."), thread->DataSet()->NumRows()), 0); @@ -1333,13 +1342,13 @@ viewMenu->Enable(MNU_REFRESH, true); toolBar->EnableTool(MNU_OPTIONS, true); toolsMenu->Enable(MNU_OPTIONS, true); - toolsMenu->Enable(MNU_INCLUDEFILTER, true); - toolsMenu->Enable(MNU_EXCLUDEFILTER, true); - toolsMenu->Enable(MNU_REMOVEFILTERS, true); - toolsMenu->Enable(MNU_ASCSORT, true); - toolsMenu->Enable(MNU_DESCSORT, true); - toolsMenu->Enable(MNU_REMOVESORT, true); - + toolsMenu->Enable(MNU_INCLUDEFILTER, true); + toolsMenu->Enable(MNU_EXCLUDEFILTER, true); + toolsMenu->Enable(MNU_REMOVEFILTERS, true); + toolsMenu->Enable(MNU_ASCSORT, true); + toolsMenu->Enable(MNU_DESCSORT, true); + toolsMenu->Enable(MNU_REMOVESORT, true); + manager.Update(); if (!hasOids && primaryKeyColNumbers.IsEmpty() && relkind == 'r') @@ -2021,29 +2030,29 @@ savedLine.cols = new wxString[nCols]; // Get the "real" column list, including any dropped columns, as - // key positions etc do not ignore these. - pgSet *allColsSet=connection->ExecuteSet( - wxT("SELECT attisdropped FROM pg_attribute") - wxT(" WHERE attnum > 0 AND attrelid=") + NumToStr(relid) + wxT("::oid\n") + // key positions etc do not ignore these. + pgSet *allColsSet=connection->ExecuteSet( + wxT("SELECT attisdropped FROM pg_attribute") + wxT(" WHERE attnum > 0 AND attrelid=") + NumToStr(relid) + wxT("::oid\n") wxT(" ORDER BY attnum")); - int x = 1; - if (allColsSet) - { - for (i=0; i < allColsSet->NumRows(); i++) - { - if (allColsSet->GetVal(wxT("attisdropped")) == wxT("t")) - { - colMap.Add(0); - } - else - { - colMap.Add(x); - x++; - } - allColsSet->MoveNext(); - } - } + int x = 1; + if (allColsSet) + { + for (i=0; i < allColsSet->NumRows(); i++) + { + if (allColsSet->GetVal(wxT("attisdropped")) == wxT("t")) + { + colMap.Add(0); + } + else + { + colMap.Add(x); + x++; + } + allColsSet->MoveNext(); + } + } pgSet *colSet=connection->ExecuteSet( wxT("SELECT n.nspname AS nspname, relname, format_type(t.oid,NULL) AS typname, format_type(t.oid, att.atttypmod) AS displaytypname, ") @@ -2090,11 +2099,11 @@ if ((columns[i].type == PGOID_TYPE_INT4 || columns[i].type == PGOID_TYPE_INT8) && colSet->GetBool(wxT("atthasdef"))) { - wxString adsrc = colSet->GetVal(wxT("adsrc")); + wxString adsrc = colSet->GetVal(wxT("adsrc")); if (adsrc == wxT("nextval('") + colSet->GetVal(wxT("relname")) + wxT("_") + columns[i].name + wxT("_seq'::text)") || - adsrc == wxT("nextval('") + colSet->GetVal(wxT("nspname")) + wxT(".") + colSet->GetVal(wxT("relname")) + wxT("_") + columns[i].name + wxT("_seq'::text)") || - adsrc == wxT("nextval('") + colSet->GetVal(wxT("relname")) + wxT("_") + columns[i].name + wxT("_seq'::regclass)") || - adsrc == wxT("nextval('") + colSet->GetVal(wxT("nspname")) + wxT(".") + colSet->GetVal(wxT("relname")) + wxT("_") + columns[i].name + wxT("_seq'::regclass)")) + adsrc == wxT("nextval('") + colSet->GetVal(wxT("nspname")) + wxT(".") + colSet->GetVal(wxT("relname")) + wxT("_") + columns[i].name + wxT("_seq'::text)") || + adsrc == wxT("nextval('") + colSet->GetVal(wxT("relname")) + wxT("_") + columns[i].name + wxT("_seq'::regclass)") || + adsrc == wxT("nextval('") + colSet->GetVal(wxT("nspname")) + wxT(".") + colSet->GetVal(wxT("relname")) + wxT("_") + columns[i].name + wxT("_seq'::regclass)")) { if (columns[i].type == PGOID_TYPE_INT4) columns[i].type = (Oid)PGOID_TYPE_SERIAL; @@ -2237,11 +2246,11 @@ delete dataPool; delete addPool; - + delete[] columns; - - if (lineIndex) - delete[] lineIndex; + + if (lineIndex) + delete[] lineIndex; } @@ -2357,19 +2366,19 @@ { wxStringTokenizer collist(primaryKeyColNumbers, wxT(",")); long cn; - int offset; - - if (hasOids) - offset = 0; - else - offset = 1; + int offset; + + if (hasOids) + offset = 0; + else + offset = 1; while (collist.HasMoreTokens()) { cn=StrToLong(collist.GetNextToken()); - // Translate the column location to the real location in the actual columns still present - cn = colMap[cn-1]; + // Translate the column location to the real location in the actual columns still present + cn = colMap[cn-1]; wxString colval=line->cols[cn-offset]; if (colval.IsEmpty()) @@ -2620,20 +2629,20 @@ int i; for (i=0 ; i < nCols ; i++) { - wxString val; - if (thread->DataSet()->ColType(i) == wxT("bytea")) - val = _(""); - else - { - val = thread->DataSet()->GetVal(i); - if (val.IsEmpty()) - { - if (!thread->DataSet()->IsNull(i)) - val = wxT("''"); - } - else if (val == wxT("''")) - val = wxT("\\'\\'"); - } + wxString val; + if (thread->DataSet()->ColType(i) == wxT("bytea")) + val = _(""); + else + { + val = thread->DataSet()->GetVal(i); + if (val.IsEmpty()) + { + if (!thread->DataSet()->IsNull(i)) + val = wxT("''"); + } + else if (val == wxT("''")) + val = wxT("\\'\\'"); + } line->cols[i] = val; } rowsCached++; @@ -2677,11 +2686,11 @@ cacheLine *line=GetLine(pos); if (!line) break; - + // If line->cols is null, it probably means we need to force the cacheline to be populated. if (!line->cols) { - GetValue(pos, 0); + GetValue(pos, 0); line=GetLine(pos); } @@ -2876,9 +2885,9 @@ str = wxT("''"); else if (type == PGOID_TYPE_BOOL) str = value; - else if (type == PGOID_TYPE_BIT) - // Don't cast this one - return wxT("B'") + value + wxT("'"); + else if (type == PGOID_TYPE_BIT) + // Don't cast this one + return wxT("B'") + value + wxT("'"); else str = conn->qtDbString(value); @@ -3013,7 +3022,7 @@ if (obj) { pgaFactory *factory=obj->GetFactory(); - return factory == &tableFactory || factory == &viewFactory || factory == &catalogObjectFactory; + return factory == &tableFactory || factory == &viewFactory || factory == &extTableFactory || factory == &catalogObjectFactory; } return false; } @@ -3035,7 +3044,7 @@ + wxT(" - ") + obj->GetFullIdentifier(); frmEditGrid *eg= new frmEditGrid(form, txt, conn, (pgSchemaObject*)obj); - eg->SetLimit(rowlimit); + eg->SetLimit(rowlimit); eg->ShowForm(filter); return eg; } @@ -3047,7 +3056,7 @@ { mnu->Append(id, _("View &All Rows\tCtrl-D"), _("View the data in the selected object.")); toolbar->AddTool(id, _("View All Rows\tCtrl-D"), wxBitmap(viewdata_xpm), _("View the data in the selected object."), wxITEM_NORMAL); - context = false; + context = false; } @@ -3062,7 +3071,7 @@ { mnu->Append(id, _("View F&iltered Rows...\tCtrl-G"), _("Apply a filter and view the data in the selected object.")); toolbar->AddTool(id, _("View Filtered Rows\tCtrl-G"), wxBitmap(viewfiltereddata_xpm), _("Apply a filter and view the data in the selected object."), wxITEM_NORMAL); - context = false; + context = false; } @@ -3073,12 +3082,12 @@ editGridLimitedFactory::editGridLimitedFactory(menuFactoryList *list, wxMenu *mnu, ctlMenuToolbar *toolbar, int limit) : editGridFactoryBase(list) { - mnu->Append(id, wxString::Format(_("View Top %i Rows"), limit), _("View a limited number of rows in the selected object.")); - rowlimit = limit; - context = false; + mnu->Append(id, wxString::Format(_("View Top %i Rows"), limit), _("View a limited number of rows in the selected object.")); + rowlimit = limit; + context = false; } wxWindow *editGridLimitedFactory::StartDialog(frmMain *form, pgObject *obj) { - return ViewData(form, obj, false); + return ViewData(form, obj, false); } Index: pgadmin/frm/frmGrantWizard.cpp =================================================================== --- pgadmin/frm/frmGrantWizard.cpp (revision 7597) +++ pgadmin/frm/frmGrantWizard.cpp (working copy) @@ -25,6 +25,7 @@ #include "schema/pgSequence.h" #include "schema/pgTable.h" #include "schema/pgView.h" +#include "schema/pgExtTable.h" // Icons #include "images/index.xpm" @@ -135,6 +136,7 @@ !factory->IsCollectionFor(triggerFunctionFactory) && !factory->IsCollectionFor(procedureFactory) && !factory->IsCollectionFor(viewFactory) && + !factory->IsCollectionFor(extTableFactory) && !factory->IsCollectionFor(sequenceFactory)) return; } @@ -150,11 +152,11 @@ AddObjects((pgCollection*)obj); else { - if (obj->CanEdit()) - { - objectArray.Add(obj); - chkList->Append(obj->GetTypeName() + wxT(" ") + obj->GetFullIdentifier()); // no translation! - } + if (obj->CanEdit()) + { + objectArray.Add(obj); + chkList->Append(obj->GetTypeName() + wxT(" ") + obj->GetFullIdentifier()); // no translation! + } } } item=mainForm->GetBrowser()->GetNextChild(collection->GetId(), cookie); @@ -180,6 +182,9 @@ privList = wxT("EXECUTE"); privChar = "X"; break; + case PGM_EXTTABLE: + privList = wxT("SELECT,RULE"); + privChar = "r"; default: break; } @@ -253,26 +258,33 @@ { case PGM_FUNCTION: { - if (((pgFunction*)obj)->GetIsProcedure()) - { - tmp = securityPage->GetGrant(wxT("X"), wxT("PROCEDURE ") - + obj->GetQuotedFullIdentifier() + wxT("(") - + ((pgProcedure*)obj)->GetArgSigList() + wxT(")")); - } - else - { - tmp = securityPage->GetGrant(wxT("X"), wxT("FUNCTION ") - + obj->GetQuotedFullIdentifier() + wxT("(") - + ((pgFunction*)obj)->GetArgSigList() + wxT(")")); - } + if (((pgFunction*)obj)->GetIsProcedure()) + { + tmp = securityPage->GetGrant(wxT("X"), wxT("PROCEDURE ") + + obj->GetQuotedFullIdentifier() + wxT("(") + + ((pgProcedure*)obj)->GetArgSigList() + wxT(")")); + } + else + { + tmp = securityPage->GetGrant(wxT("X"), wxT("FUNCTION ") + + obj->GetQuotedFullIdentifier() + wxT("(") + + ((pgFunction*)obj)->GetArgSigList() + wxT(")")); + } break; } case PGM_VIEW: case PGM_SEQUENCE: tmp = securityPage->GetGrant(wxT("arwdRxt"), wxT("TABLE ") + obj->GetQuotedFullIdentifier()); break; + case PGM_EXTTABLE: + tmp = securityPage->GetGrant(wxT("r"), wxT("TABLE ") + obj->GetQuotedFullIdentifier()); default: - tmp = securityPage->GetGrant(wxT("arwdRxt"), obj->GetTypeName().Upper() + wxT(" ") + obj->GetQuotedFullIdentifier()); + if (obj->GetTypeName().Upper() == wxT("EXTERNAL TABLE")) // somewhat of a hack + { + tmp = securityPage->GetGrant(wxT("r"), wxT("TABLE ") + obj->GetQuotedFullIdentifier()); + } + else + tmp = securityPage->GetGrant(wxT("arwdRxt"), obj->GetTypeName().Upper() + wxT(" ") + obj->GetQuotedFullIdentifier()); break; } @@ -308,12 +320,13 @@ case PGM_FUNCTION: case PGM_SEQUENCE: case PGM_VIEW: - if (obj->IsCollection() && obj->GetSchema()->GetMetaType() != PGM_CATALOG) - return obj->GetSchema()->CanEdit(); - break; + case PGM_EXTTABLE: + if (obj->IsCollection() && obj->GetSchema()->GetMetaType() != PGM_CATALOG) + return obj->GetSchema()->CanEdit(); + break; - case PGM_SCHEMA: - return obj->CanEdit(); + case PGM_SCHEMA: + return obj->CanEdit(); default: break; } Index: pgadmin/frm/frmBackupServer.cpp =================================================================== --- pgadmin/frm/frmBackupServer.cpp (revision 7597) +++ pgadmin/frm/frmBackupServer.cpp (working copy) @@ -134,6 +134,8 @@ wxString cmd; if (server->GetConnection()->EdbMinimumVersion(8,0)) cmd=edbBackupAllExecutable; + else if (server->GetConnection()->GetIsGreenplum()) + cmd=gpBackupAllExecutable; else cmd=pgBackupAllExecutable; @@ -208,6 +210,8 @@ if (obj->GetConnection()->EdbMinimumVersion(8, 0)) return !edbBackupExecutable.IsEmpty() && pgAppMinimumVersion(edbBackupExecutable, 8, 3); + else if (obj->GetConnection()->GetIsGreenplum()) + return !gpBackupExecutable.IsEmpty() && pgAppMinimumVersion(gpBackupExecutable, 8, 3); else return !pgBackupExecutable.IsEmpty() && pgAppMinimumVersion(pgBackupExecutable, 8, 3); } Index: pgadmin/frm/frmBackup.cpp =================================================================== --- pgadmin/frm/frmBackup.cpp (revision 7597) +++ pgadmin/frm/frmBackup.cpp (working copy) @@ -78,17 +78,17 @@ if (!object->GetDatabase()->GetServer()->GetPasswordIsStored()) environment.Add(wxT("PGPASSWORD=") + object->GetServer()->GetPassword()); - // Pass the SSL mode via the environment - environment.Add(wxT("PGSSLMODE=") + object->GetServer()->GetConnection()->GetSslModeName()); + // Pass the SSL mode via the environment + environment.Add(wxT("PGSSLMODE=") + object->GetServer()->GetConnection()->GetSslModeName()); // Icon SetIcon(wxIcon(backup_xpm)); - // fix translation problem - wxString dollarLabel=wxGetTranslation(_("Disable $$ quoting")); - dollarLabel.Replace(wxT("$$"), wxT("$")); - chkDisableDollar->SetLabel(dollarLabel); - chkDisableDollar->SetSize(chkDisableDollar->GetBestSize()); + // fix translation problem + wxString dollarLabel=wxGetTranslation(_("Disable $$ quoting")); + dollarLabel.Replace(wxT("$$"), wxT("$")); + chkDisableDollar->SetLabel(dollarLabel); + chkDisableDollar->SetSize(chkDisableDollar->GetBestSize()); txtMessages = CTRL_TEXT("txtMessages"); txtMessages->SetMaxLength(0L); @@ -189,6 +189,8 @@ wxString cmd; if (object->GetConnection()->EdbMinimumVersion(8,0)) cmd=edbBackupExecutable; + else if (object->GetConnection()->GetIsGreenplum()) + cmd=gpBackupExecutable; else cmd=pgBackupExecutable; @@ -197,6 +199,9 @@ cmd += wxT(" -p ") + NumToStr((long)server->GetPort()) + wxT(" -U ") + server->GetUsername(); + + if (object->GetConnection()->GetIsGreenplum()) + cmd += wxT(" --gp-syntax "); return cmd; } @@ -206,6 +211,8 @@ wxString backupExecutable; if (object->GetConnection()->EdbMinimumVersion(8,0)) backupExecutable=edbBackupExecutable; + else if (object->GetConnection()->GetIsGreenplum()) + backupExecutable=gpBackupExecutable; else backupExecutable=pgBackupExecutable; @@ -261,7 +268,7 @@ cmd.Append(wxT(" --disable-dollar-quoting")); if (settings->GetIgnoreVersion()) cmd.Append(wxT(" -i")); - if (chkVerbose->GetValue()) + if (chkVerbose->GetValue()) cmd.Append(wxT(" -v")); cmd.Append(wxT(" -f \"") + txtFilename->GetValue() + wxT("\"")); @@ -270,27 +277,27 @@ #ifdef WIN32 cmd.Append(wxT(" -n \\\"") + ((pgSchema*)object)->GetIdentifier() + wxT("\\\"")); #else - cmd.Append(wxT(" -n '") + ((pgSchema*)object)->GetQuotedIdentifier() + wxT("'")); + cmd.Append(wxT(" -n '") + ((pgSchema*)object)->GetQuotedIdentifier() + wxT("'")); #endif else if (object->GetMetaType() == PGM_TABLE) { - // The syntax changed in 8.2 :-( - if (pgAppMinimumVersion(backupExecutable, 8, 2)) - { + // The syntax changed in 8.2 :-( + if (pgAppMinimumVersion(backupExecutable, 8, 2)) + { #ifdef WIN32 - cmd.Append(wxT(" -t \"\\\"") + ((pgTable*)object)->GetSchema()->GetIdentifier() + - wxT("\\\".\\\"") + ((pgTable*)object)->GetIdentifier() + wxT("\\\"\"")); + cmd.Append(wxT(" -t \"\\\"") + ((pgTable*)object)->GetSchema()->GetIdentifier() + + wxT("\\\".\\\"") + ((pgTable*)object)->GetIdentifier() + wxT("\\\"\"")); #else - cmd.Append(wxT(" -t '") + ((pgTable*)object)->GetSchema()->GetQuotedIdentifier() + - wxT(".") + ((pgTable*)object)->GetQuotedIdentifier() + wxT("'")); + cmd.Append(wxT(" -t '") + ((pgTable*)object)->GetSchema()->GetQuotedIdentifier() + + wxT(".") + ((pgTable*)object)->GetQuotedIdentifier() + wxT("'")); #endif - } - else - { - cmd.Append(wxT(" -t ") + ((pgTable*)object)->GetQuotedIdentifier()); - cmd.Append(wxT(" -n ") + ((pgTable*)object)->GetSchema()->GetQuotedIdentifier()); - } + } + else + { + cmd.Append(wxT(" -t ") + ((pgTable*)object)->GetQuotedIdentifier()); + cmd.Append(wxT(" -n ") + ((pgTable*)object)->GetSchema()->GetQuotedIdentifier()); + } } cmd.Append(wxT(" ") + commandLineCleanOption(object->GetDatabase()->GetQuotedIdentifier())); @@ -343,6 +350,8 @@ if (obj->GetConnection() && obj->GetConnection()->EdbMinimumVersion(8, 0)) return obj->CanBackup() && !edbBackupExecutable.IsEmpty(); + else if (obj->GetConnection() && obj->GetConnection()->GetIsGreenplum()) + return obj->CanBackup() && !gpBackupExecutable.IsEmpty(); else return obj->CanBackup() && !pgBackupExecutable.IsEmpty(); Index: pgadmin/frm/frmQuery.cpp =================================================================== --- pgadmin/frm/frmQuery.cpp (revision 7597) +++ pgadmin/frm/frmQuery.cpp (working copy) @@ -43,6 +43,7 @@ #include "schema/pgDatabase.h" #include "schema/pgTable.h" #include "schema/pgView.h" +#include "schema/pgExtTable.h" #include "schema/pgServer.h" #include "utils/favourites.h" #include "utils/sysLogger.h" @@ -795,6 +796,7 @@ { wxT("TYPE"), 0, 11}, { wxT("USER"), 0, 12}, { wxT("VIEW"), 0, 11}, + { wxT("EXTTABLE"), 0, 12}, { 0, 0 } }; @@ -932,6 +934,8 @@ if (conn->GetIsEdb()) DisplayHelp(page, HELP_ENTERPRISEDB); + else if (conn->GetIsGreenplum()) + DisplayHelp(page, HELP_GREENPLUM); else DisplayHelp(page, HELP_POSTGRESQL); } @@ -958,17 +962,17 @@ { if (event.GetSelection() == 0) - { - manager.GetPane(wxT("outputPane")).Show(true); - manager.GetPane(wxT("scratchPad")).Show(true); - manager.Update(); + { + manager.GetPane(wxT("outputPane")).Show(true); + manager.GetPane(wxT("scratchPad")).Show(true); + manager.Update(); updateFromGqb(false); - } + } else { - manager.GetPane(wxT("outputPane")).Show(false); - manager.GetPane(wxT("scratchPad")).Show(false); - manager.Update(); + manager.GetPane(wxT("outputPane")).Show(false); + manager.GetPane(wxT("scratchPad")).Show(false); + manager.Update(); if(firstTime) //Things that should be done on first click on GQB { // Size, and pause to allow the window to draw @@ -1350,10 +1354,10 @@ return; } - // Rearrangement of a Gqb pane. - manager.GetPane(wxT("outputPane")).Show(true); - manager.GetPane(wxT("scratchPad")).Show(true); - manager.Update(); + // Rearrangement of a Gqb pane. + manager.GetPane(wxT("outputPane")).Show(true); + manager.GetPane(wxT("scratchPad")).Show(true); + manager.Update(); Hide(); @@ -1752,10 +1756,10 @@ { canGenerate=true; } - else - { - gqbUpdateRunning = false; - } + else + { + gqbUpdateRunning = false; + } } else { @@ -2415,6 +2419,11 @@ pgView *view = (pgView*)obj; return StartDialogSql(form, obj, view->GetSelectSql(form->GetBrowser())); } + else if (obj->IsCreatedBy(extTableFactory)) + { + pgExtTable *exttable = (pgExtTable*)obj; + return StartDialogSql(form, obj, exttable->GetSelectSql(form->GetBrowser())); + } return 0; } @@ -2464,6 +2473,11 @@ pgView *view = (pgView*)obj; return StartDialogSql(form, obj, view->GetUpdateSql(form->GetBrowser())); } + /* else if (obj->IsCreatedBy(extTableFactory)) + { + pgExtTable *exttable = (pgExtTable*)obj; + return StartDialogSql(form, obj, exttable->GetUpdateSql(form->GetBrowser())); + }*/ return 0; } Index: pgadmin/frm/frmBackupGlobals.cpp =================================================================== --- pgadmin/frm/frmBackupGlobals.cpp (revision 7597) +++ pgadmin/frm/frmBackupGlobals.cpp (working copy) @@ -150,6 +150,8 @@ wxString cmd; if (server->GetConnection()->EdbMinimumVersion(8,0)) cmd=edbBackupAllExecutable; + else if (server->GetConnection()->GetIsGreenplum()) + cmd=gpBackupAllExecutable; else cmd=pgBackupAllExecutable; @@ -227,6 +229,8 @@ if (obj->GetConnection() && obj->GetConnection()->EdbMinimumVersion(8, 0)) return obj->CanBackupGlobals() && !edbBackupExecutable.IsEmpty() && pgAppMinimumVersion(edbBackupExecutable, 8, 3); + else if (obj->GetConnection() && obj->GetConnection()->GetIsGreenplum()) + return obj->CanBackupGlobals() && !gpBackupExecutable.IsEmpty() && pgAppMinimumVersion(gpBackupExecutable, 8, 3); else return obj->CanBackupGlobals() && !pgBackupExecutable.IsEmpty() && pgAppMinimumVersion(pgBackupExecutable, 8, 3); } Index: pgadmin/frm/frmMainConfig.cpp =================================================================== --- pgadmin/frm/frmMainConfig.cpp (revision 7597) +++ pgadmin/frm/frmMainConfig.cpp (working copy) @@ -125,8 +125,8 @@ } while (item); - editMenu->Enable(MNU_DELETE, false); - toolBar->EnableTool(MNU_DELETE,false); + editMenu->Enable(MNU_DELETE, false); + toolBar->EnableTool(MNU_DELETE,false); } @@ -228,7 +228,7 @@ { wxString page; if (page.IsEmpty()) - page=wxT("runtime-config"); + page=wxT("runtime-config"); return page; } @@ -481,7 +481,8 @@ FillList(wxT("explain_pretty_print")); // Client Connection Defaults / Other Defaults FillList(wxT("enable_hashjoin")); // Query Tuning / Planner Method Configuration FillList(wxT("cpu_operator_cost")); // Query Tuning / Planner Cost Constants - FillList(wxT("geqo")); // Query Tuning / Genetic Query Optimizer + if (!conn || !conn->GetIsGreenplum()) // Greenplum doesn't have the Genetic Query Optimizer + FillList(wxT("geqo")); // Query Tuning / Genetic Query Optimizer FillList(wxT("default_statistics_target")); // Query Tuning / Other Planner Options FillList(wxT("deadlock_timeout")); // Lock Management FillList(wxT("shared_buffers")); // Resource Usage / Memory @@ -497,7 +498,8 @@ FillList(wxT("checkpoint_segments")); // Write-Ahead Log / Checkpoints FillList(wxT("add_missing_from")); // Version and Platform Compatibility / Previous PostgreSQL Version FillList(wxT("transform_null_equals")); // Version and Platform Compatibility / Other Platforms and Clients - FillList(wxT("trace_notify")); // Developer Options + if (!conn || !conn->GetIsGreenplum()) // Greenplum doesn't have trace_notify visible + FillList(wxT("trace_notify")); // Developer Options FillList(wxT("hba_file")); // Ungrouped @@ -694,8 +696,14 @@ wxWindow *mainConfigFileFactory::StartDialog(frmMain *form, pgObject *obj) { - frmConfig *dlg = new frmMainConfig(form); + pgServer *server=0; + if (CheckEnable(obj)) + server=obj->GetServer(); + if (server == 0 || !server->GetConnection()->GetIsGreenplum()) + server = 0; // make this work like it always did if not Greenplum. But wouldn't it be better to work for all DBs this way? + frmConfig *dlg = new frmMainConfig(form,server); dlg->Go(); - dlg->DoOpen(); + if (server==0 || !CheckEnable(obj)) + dlg->DoOpen(); return dlg; } Index: pgadmin/frm/frmHbaConfig.cpp =================================================================== --- pgadmin/frm/frmHbaConfig.cpp (revision 7597) +++ pgadmin/frm/frmHbaConfig.cpp (working copy) @@ -36,7 +36,7 @@ BEGIN_EVENT_TABLE(frmHbaConfig, frmConfig) EVT_MENU(MNU_UNDO, frmHbaConfig::OnUndo) - EVT_MENU(MNU_DELETE, frmHbaConfig::OnDelete) + EVT_MENU(MNU_DELETE, frmHbaConfig::OnDelete) EVT_MENU(MNU_CONTENTS, frmHbaConfig::OnContents) EVT_LIST_ITEM_ACTIVATED(CTL_CFGVIEW, frmHbaConfig::OnEditSetting) EVT_LIST_ITEM_SELECTED(CTL_CFGVIEW, frmHbaConfig::OnSelectSetting) @@ -108,11 +108,11 @@ listEdit->AddColumn(_("Method"), 40); listEdit->AddColumn(_("Option"), 100); - helpMenu->Enable(MNU_HINT, false); - toolBar->EnableTool(MNU_HINT, false); + helpMenu->Enable(MNU_HINT, false); + toolBar->EnableTool(MNU_HINT, false); - editMenu->Enable(MNU_DELETE, false); - toolBar->EnableTool(MNU_DELETE, false); + editMenu->Enable(MNU_DELETE, false); + toolBar->EnableTool(MNU_DELETE, false); } @@ -208,7 +208,7 @@ toolBar->EnableTool(MNU_SAVE, false); toolBar->EnableTool(MNU_UNDO, false); - // make intermediate change current + // make intermediate change current for (i=0 ; i < lines.GetCount() ; i++) lines.Item(i).Init(lines.Item(i).GetText()); } @@ -257,38 +257,38 @@ void frmHbaConfig::OnDelete(wxCommandEvent &event) { - bool found = false; - int pos = listEdit->GetSelection(); - if (pos >= 0) - { - listEdit->DeleteCurrentItem(); - size_t i; - for (i=0; i < lines.GetCount(); i++) - { - if (lines.Item(i).item == pos) - { - lines.RemoveAt(i); - changed = true; + bool found = false; + int pos = listEdit->GetSelection(); + if (pos >= 0) + { + listEdit->DeleteCurrentItem(); + size_t i; + for (i=0; i < lines.GetCount(); i++) + { + if (lines.Item(i).item == pos) + { + lines.RemoveAt(i); + changed = true; fileMenu->Enable(MNU_SAVE, true); editMenu->Enable(MNU_UNDO, false); editMenu->Enable(MNU_DELETE, false); toolBar->EnableTool(MNU_SAVE, true); toolBar->EnableTool(MNU_UNDO, false); - toolBar->EnableTool(MNU_DELETE, false); - found = true; - break; - } - } - if (found) - { - /* Renumber all positions */ - for (i=0; i < lines.GetCount(); i++) - { - if (lines.Item(i).item > pos) - lines.Item(i).item--; - } - } - } + toolBar->EnableTool(MNU_DELETE, false); + found = true; + break; + } + } + if (found) + { + /* Renumber all positions */ + for (i=0; i < lines.GetCount(); i++) + { + if (lines.Item(i).item > pos) + lines.Item(i).item--; + } + } + } } @@ -386,8 +386,14 @@ wxWindow *hbaConfigFileFactory::StartDialog(frmMain *form, pgObject *obj) { - frmConfig *dlg = new frmHbaConfig(form); + pgServer *server=0; + if (CheckEnable(obj)) + server=obj->GetServer(); + if (server ==0 ||!server->GetConnection()->GetIsGreenplum()) + server = 0; // make this work like it always did if not Greenplum. But wouldn't it be better to work for all DBs this way? + frmConfig *dlg = new frmHbaConfig(form,server); dlg->Go(); - dlg->DoOpen(); + if (server==0 || !CheckEnable(obj)) + dlg->DoOpen(); return dlg; } Index: pgadmin/frm/frmRestore.cpp =================================================================== --- pgadmin/frm/frmRestore.cpp (revision 7597) +++ pgadmin/frm/frmRestore.cpp (working copy) @@ -283,6 +283,8 @@ if (object->GetConnection()->EdbMinimumVersion(8,0)) cmd=edbRestoreExecutable; + else if (object->GetConnection()->GetIsGreenplum()) + cmd=gpRestoreExecutable; else cmd=pgRestoreExecutable; @@ -503,6 +505,8 @@ if (obj->GetConnection() && obj->GetConnection()->EdbMinimumVersion(8, 0)) return obj->CanCreate() && obj->CanRestore() && !edbRestoreExecutable.IsEmpty(); + else if (obj->GetConnection() && obj->GetConnection()->GetIsGreenplum()) + return obj->CanCreate() && obj->CanRestore() && !gpRestoreExecutable.IsEmpty(); else return obj->CanCreate() && obj->CanRestore() && !pgRestoreExecutable.IsEmpty(); } Index: pgadmin/frm/frmMain.cpp =================================================================== --- pgadmin/frm/frmMain.cpp (revision 7597) +++ pgadmin/frm/frmMain.cpp (working copy) @@ -425,6 +425,7 @@ new pgsqlHelpFactory(menuFactories, helpMenu, toolBar, true); new edbHelpFactory(menuFactories, helpMenu, toolBar, true); + new greenplumHelpFactory(menuFactories, helpMenu, toolBar, true); new slonyHelpFactory(menuFactories, helpMenu, toolBar, true); // Don't include this seperator on Mac, because the only option @@ -519,12 +520,12 @@ { wxLogInfo(wxT("Replacing with new node %s %s for refresh"), newData->GetTypeName().c_str(), newData->GetQuotedFullIdentifier().c_str()); - newData->SetId(currentItem); // not done automatically + newData->SetId(currentItem); // not done automatically browser->SetItemData(currentItem, newData); - // Update the node text if this is an object, as it may have been renamed - if (!newData->IsCollection()) - browser->SetItemText(currentItem, newData->GetDisplayName()); + // Update the node text if this is an object, as it may have been renamed + if (!newData->IsCollection()) + browser->SetItemText(currentItem, newData->GetDisplayName()); delete data; } @@ -1032,7 +1033,7 @@ settings->Write(key + wxT("Server"), server->GetName()); settings->Write(key + wxT("Description"), server->GetDescription()); settings->Write(key + wxT("ServiceID"), server->GetServiceID()); - settings->Write(key + wxT("DiscoveryID"), server->GetDiscoveryID()); + settings->Write(key + wxT("DiscoveryID"), server->GetDiscoveryID()); settings->Write(key + wxT("Port"), server->GetPort()); settings->Write(key + wxT("StorePwd"), server->GetStorePwd()); settings->Write(key + wxT("Restore"), server->GetRestore()); @@ -1041,7 +1042,7 @@ settings->Write(key + wxT("LastDatabase"), server->GetLastDatabase()); settings->Write(key + wxT("LastSchema"), server->GetLastSchema()); settings->Write(key + wxT("DbRestriction"), server->GetDbRestriction()); - settings->Write(key + wxT("Colour"), server->GetColour().GetAsString(wxC2S_HTML_SYNTAX)); + settings->Write(key + wxT("Colour"), server->GetColour().GetAsString(wxC2S_HTML_SYNTAX)); settings->Write(key + wxT("SSL"), server->GetSSL()); pgCollection *coll=browser->FindCollection(databaseFactory, server->GetId()); @@ -1068,7 +1069,7 @@ wxLogInfo(wxT("Reloading servers...")); serverFactory.CreateObjects(serversObj, browser); - + // Reset the Servers node text wxString label; label.Printf(_("Servers (%d)"), browser->GetChildrenCount(serversObj->GetId(), false)); @@ -1200,6 +1201,19 @@ return 0; } +greenplumHelpFactory::greenplumHelpFactory(menuFactoryList *list, wxMenu *mnu, ctlMenuToolbar *toolbar, bool bigIcon) : actionFactory(list) +{ + mnu->Append(id, _("&Greenplum Database Help"), _("Display help on the Greenplum Database system.")); +} + + +wxWindow *greenplumHelpFactory::StartDialog(frmMain *form, pgObject *obj) +{ + DisplayHelp(wxT("index"), HELP_GREENPLUM); + return 0; +} + + slonyHelpFactory::slonyHelpFactory(menuFactoryList *list, wxMenu *mnu, ctlMenuToolbar *toolbar, bool bigIcon) : actionFactory(list) { mnu->Append(id, _("&Slony Help"), _("Display help on the Slony replication system.")); Index: pgadmin/debugger/dbgPgConn.cpp =================================================================== --- pgadmin/debugger/dbgPgConn.cpp (revision 7597) +++ pgadmin/debugger/dbgPgConn.cpp (working copy) @@ -63,9 +63,9 @@ m_isEdb = false; if( startThread ) - m_workerThread = new dbgPgThread( *this ); + m_workerThread = new dbgPgThread( *this ); else - m_workerThread = NULL; + m_workerThread = NULL; wxString msg; wxString delimiter; @@ -79,8 +79,8 @@ if( m_workerThread ) { - m_workerThread->Create(); - m_workerThread->Run(); + m_workerThread->Create(); + m_workerThread->Run(); } // Figure out the hostname/IP address @@ -108,13 +108,13 @@ return; } - memcpy(&(ipaddr),host->h_addr,host->h_length); - hostip = wxString::FromAscii(inet_ntoa(*((struct in_addr*) host->h_addr_list[0]))); + memcpy(&(ipaddr),host->h_addr,host->h_length); + hostip = wxString::FromAscii(inet_ntoa(*((struct in_addr*) host->h_addr_list[0]))); hostname = server; } - else + else { - hostip = server; + hostip = server; hostname = server; } #ifndef __WXMSW__ @@ -128,10 +128,10 @@ if(hostname.Length()) { - connectParams.Append(wxT( "host=")); - connectParams.Append(hostname); + connectParams.Append(wxT( "host=")); + connectParams.Append(hostname); - msg += delimiter + server; delimiter = _(":"); + msg += delimiter + server; delimiter = _(":"); } if (hostip.Length()) @@ -142,33 +142,33 @@ if( port.Length()) { - connectParams += wxT(" port="); - connectParams += port; + connectParams += wxT(" port="); + connectParams += port; - msg += delimiter + port; delimiter = _(":"); + msg += delimiter + port; delimiter = _(":"); } if( database.Length()) { - connectParams.Append(wxT(" dbname=")); - connectParams.Append(qtConnString(database)); + connectParams.Append(wxT(" dbname=")); + connectParams.Append(qtConnString(database)); - msg += delimiter + database; delimiter = _(":"); + msg += delimiter + database; delimiter = _(":"); } if(username.Length()) { - connectParams.Append(wxT(" user=")); - connectParams.Append(username ); + connectParams.Append(wxT(" user=")); + connectParams.Append(username ); - msg += delimiter + username; delimiter = _(":"); + msg += delimiter + username; delimiter = _(":"); } if(password.Length()) { - connectParams.Append(wxT(" password=")); - connectParams.Append(password); + connectParams.Append(wxT(" password=")); + connectParams.Append(password); } switch (sslmode) @@ -201,13 +201,13 @@ if( PQstatus( m_pgConn ) == CONNECTION_OK ) { - m_frame->getStatusBar()->SetStatusText( wxString::Format(_( "Connected to %s" ), msg.c_str()), 1 ); + m_frame->getStatusBar()->SetStatusText( wxString::Format(_( "Connected to %s" ), msg.c_str()), 1 ); - PQsetClientEncoding( m_pgConn, "UNICODE" ); + PQsetClientEncoding( m_pgConn, "UNICODE" ); } else { - throw( std::runtime_error( PQerrorMessage( m_pgConn ))); + throw( std::runtime_error( PQerrorMessage( m_pgConn ))); } } @@ -225,9 +225,9 @@ bool dbgPgConn::isConnected( void ) const { if( m_pgConn && PQstatus( m_pgConn ) == CONNECTION_OK ) - return( true ); + return( true ); else - return( false ); + return( false ); } //////////////////////////////////////////////////////////////////////////////// @@ -326,7 +326,7 @@ if (m_workerThread) { - m_workerThread->Die(); + m_workerThread->Die(); m_workerThread->Wait(); delete m_workerThread; @@ -334,7 +334,7 @@ } if (m_pgConn) - PQfinish(m_pgConn); + PQfinish(m_pgConn); m_pgConn = NULL; } @@ -381,6 +381,8 @@ } if (result == wxT("0")) m_minorVersion = 2; + + m_isGreenplum = version.Upper().Matches(wxT("*GREENPLUM DATABASE*")); } } @@ -467,5 +469,12 @@ return m_isEdb; } +bool dbgPgConn::GetIsGreenplum() +{ + // to retrieve edb flag + BackendMinimumVersion(0,0); + return m_isGreenplum; +} + Index: pgadmin/db/pgConn.cpp =================================================================== --- pgadmin/db/pgConn.cpp (revision 7597) +++ pgadmin/db/pgConn.cpp (working copy) @@ -52,13 +52,13 @@ { wxString msg, hostip, hostname; - save_server = server; - save_database = database; - save_username = username; - save_password = password; - save_port = port; - save_sslmode = sslmode; - save_oid = oid; + save_server = server; + save_database = database; + save_username = username; + save_password = password; + save_port = port; + save_sslmode = sslmode; + save_oid = oid; memset(features, 0, sizeof(features)); majorVersion=0; @@ -96,13 +96,13 @@ return; } - memcpy(&(ipaddr),host->h_addr,host->h_length); - hostip = wxString::FromAscii(inet_ntoa(*((struct in_addr*) host->h_addr_list[0]))); + memcpy(&(ipaddr),host->h_addr,host->h_length); + hostip = wxString::FromAscii(inet_ntoa(*((struct in_addr*) host->h_addr_list[0]))); hostname = server; } - else + else { - hostip = server; + hostip = server; hostname = server; } #ifndef __WXMSW__ @@ -198,14 +198,14 @@ if (oid) sql += wxT("oid = ") + NumToStr(oid); else - { - // Note, can't use qtDbString here as we don't know the server version yet. - wxString db = database; - db.Replace(wxT("\\"), wxT("\\\\")); - db.Replace(wxT("'"), wxT("''")); + { + // Note, can't use qtDbString here as we don't know the server version yet. + wxString db = database; + db.Replace(wxT("\\"), wxT("\\\\")); + db.Replace(wxT("'"), wxT("''")); sql += wxT("datname=") + qtString(database); - } - + } + pgSet *set = ExecuteSet(sql); @@ -229,7 +229,7 @@ wxLogInfo(wxT("Setting client_encoding to '%s'"), encoding.c_str()); if (PQsetClientEncoding(conn, encoding.ToAscii())) - wxLogError(wxT("%s"), GetLastError().c_str()); + wxLogError(wxT("%s"), GetLastError().c_str()); delete set; } @@ -252,7 +252,7 @@ pgConn *pgConn::Duplicate() { - return new pgConn(wxString(save_server), wxString(save_database), wxString(save_username), wxString(save_password), save_port, save_sslmode, save_oid); + return new pgConn(wxString(save_server), wxString(save_database), wxString(save_username), wxString(save_password), save_port, save_sslmode, save_oid); } // Return the SSL mode name @@ -261,20 +261,20 @@ switch (save_sslmode) { case 1: - return wxT("require"); - break; + return wxT("require"); + break; case 2: - return wxT("prefer"); - break; + return wxT("prefer"); + break; case 3: - return wxT("allow"); - break; + return wxT("allow"); + break; case 4: - return wxT("disable"); - break; + return wxT("disable"); + break; default: - return wxT("prefer"); - break; + return wxT("prefer"); + break; } } @@ -285,6 +285,12 @@ return isEdb; } +bool pgConn::GetIsGreenplum() +{ + // to retrieve Greenplum flag + BackendMinimumVersion(0,0); + return isGreenplum; +} wxString pgConn::SystemNamespaceRestriction(const wxString &nsp) { @@ -310,9 +316,9 @@ } } - if (BackendMinimumVersion(8, 1)) + if (BackendMinimumVersion(8, 1)) return wxT("(") + nsp + wxT(" NOT LIKE E'pg\\_%' AND ") + nsp + wxT(" NOT in (") + reservedNamespaces + wxT("))"); - else + else return wxT("(") + nsp + wxT(" NOT LIKE 'pg\\_%' AND ") + nsp + wxT(" NOT in (") + reservedNamespaces + wxT("))"); } @@ -334,7 +340,7 @@ if (!majorVersion) { wxString version=GetVersionString(); - sscanf(version.ToAscii(), "%*s %d.%d", &majorVersion, &minorVersion); + sscanf(version.ToAscii(), "%*s %d.%d.%d", &majorVersion, &minorVersion, &patchVersion); isEdb = version.Upper().Matches(wxT("ENTERPRISEDB*")); // EnterpriseDB 8.3 beta 1 & 2 and possibly later actually have PostgreSQL 8.2 style @@ -346,12 +352,25 @@ if (ExecuteScalar(wxT("SELECT count(*) FROM pg_attribute WHERE attname = 'proconfig' AND attrelid = 'pg_proc'::regclass")) == wxT("0")) minorVersion = 2; } + + isGreenplum = version.Upper().Matches(wxT("*GREENPLUM DATABASE*")); } - return majorVersion > major || (majorVersion == major && minorVersion >= minor); + return majorVersion > major || (majorVersion == major && minorVersion >= minor); } +// Greenplum sometimes adds features in patch releases, because Greenplum +// releases are not coordinated with PostgreSQL minor releases. +bool pgConn::BackendMinimumVersion(int major, int minor, int patch) +{ + if (!majorVersion) + BackendMinimumVersion(0,0); + + return majorVersion > major || (majorVersion == major && minorVersion > minor) || (majorVersion == major && minorVersion == minor && patchVersion >= patch); +} + + bool pgConn::EdbMinimumVersion(int major, int minor) { return BackendMinimumVersion(major, minor) && GetIsEdb(); @@ -437,15 +456,15 @@ result.Replace(wxT("'"), wxT("''")); result.Append(wxT("'")); - if (BackendMinimumVersion(8, 1)) - { - if (result.Contains(wxT("\\"))) - result.Prepend(wxT("E'")); - else - result.Prepend(wxT("'")); - } - else - result.Prepend(wxT("'")); + if (BackendMinimumVersion(8, 1)) + { + if (result.Contains(wxT("\\"))) + result.Prepend(wxT("E'")); + else + result.Prepend(wxT("'")); + } + else + result.Prepend(wxT("'")); return result; } @@ -596,15 +615,15 @@ return wxEmptyString; } - // Check for a returned row + // Check for a returned row if (PQntuples(qryRes) < 1) { - wxLogInfo(wxT("Query returned no tuples")); + wxLogInfo(wxT("Query returned no tuples")); PQclear(qryRes); return wxEmptyString; - } - - // Retrieve the query result and return it. + } + + // Retrieve the query result and return it. result=wxString(PQgetvalue(qryRes, 0, 0), *conv); wxLogSql(wxT("Query result: %s"), result.c_str()); @@ -636,7 +655,7 @@ wxLogError(__("Couldn't create a pgSet object!")); PQclear(qryRes); } - return set; + return set; } else { @@ -654,7 +673,7 @@ wxString pgConn::GetLastError() const { wxString errmsg; - char *pqErr; + char *pqErr; if (conn && (pqErr = PQerrorMessage(conn)) != 0) { errmsg=wxString(pqErr, wxConvUTF8); @@ -740,7 +759,7 @@ wxString pgConn::GetVersionString() { - return ExecuteScalar(wxT("SELECT version();")); + return ExecuteScalar(wxT("SELECT version();")); } void pgConn::SetLastResultError(PGresult *res) @@ -816,7 +835,7 @@ result.Replace(wxT("'"), wxT("\\'")); result.Append(wxT("'")); result.Prepend(wxT("'")); - + return result; } Index: pgadmin/db/keywords.c =================================================================== --- pgadmin/db/keywords.c (revision 7597) +++ pgadmin/db/keywords.c (working copy) @@ -118,49 +118,50 @@ {"cross", CROSS, TYPE_FUNC_NAME_KEYWORD}, {"csv", CSV, UNRESERVED_KEYWORD}, {"ctype", CTYPE, RESERVED_KEYWORD}, - {"current", CURRENT_P, UNRESERVED_KEYWORD}, - {"current_date", CURRENT_DATE, RESERVED_KEYWORD}, - {"current_role", CURRENT_ROLE, RESERVED_KEYWORD}, - {"current_time", CURRENT_TIME, RESERVED_KEYWORD}, - {"current_timestamp", CURRENT_TIMESTAMP, RESERVED_KEYWORD}, - {"current_user", CURRENT_USER, RESERVED_KEYWORD}, - {"cursor", CURSOR, UNRESERVED_KEYWORD}, - {"cycle", CYCLE, UNRESERVED_KEYWORD}, - {"database", DATABASE, UNRESERVED_KEYWORD}, - {"day", DAY_P, UNRESERVED_KEYWORD}, - {"deallocate", DEALLOCATE, UNRESERVED_KEYWORD}, - {"dec", DEC, COL_NAME_KEYWORD}, - {"decimal", DECIMAL_P, COL_NAME_KEYWORD}, - {"declare", DECLARE, UNRESERVED_KEYWORD}, - {"default", DEFAULT, RESERVED_KEYWORD}, - {"defaults", DEFAULTS, UNRESERVED_KEYWORD}, - {"deferrable", DEFERRABLE, RESERVED_KEYWORD}, - {"deferred", DEFERRED, UNRESERVED_KEYWORD}, - {"definer", DEFINER, UNRESERVED_KEYWORD}, - {"delete", DELETE_P, UNRESERVED_KEYWORD}, - {"delimiter", DELIMITER, UNRESERVED_KEYWORD}, - {"delimiters", DELIMITERS, UNRESERVED_KEYWORD}, - {"desc", DESC, RESERVED_KEYWORD}, - {"dictionary", DICTIONARY, UNRESERVED_KEYWORD}, - {"disable", DISABLE_P, UNRESERVED_KEYWORD}, - {"discard", DISCARD, UNRESERVED_KEYWORD}, - {"distinct", DISTINCT, RESERVED_KEYWORD}, - {"do", DO, RESERVED_KEYWORD}, - {"document", DOCUMENT_P, UNRESERVED_KEYWORD}, - {"domain", DOMAIN_P, UNRESERVED_KEYWORD}, - {"double", DOUBLE_P, UNRESERVED_KEYWORD}, - {"drop", DROP, UNRESERVED_KEYWORD}, - {"each", EACH, UNRESERVED_KEYWORD}, - {"else", ELSE, RESERVED_KEYWORD}, - {"enable", ENABLE_P, UNRESERVED_KEYWORD}, - {"encoding", ENCODING, UNRESERVED_KEYWORD}, - {"encrypted", ENCRYPTED, UNRESERVED_KEYWORD}, - {"end", END_P, RESERVED_KEYWORD}, - {"enum", ENUM_P, UNRESERVED_KEYWORD}, - {"escape", ESCAPE, UNRESERVED_KEYWORD}, - {"except", EXCEPT, RESERVED_KEYWORD}, - {"excluding", EXCLUDING, UNRESERVED_KEYWORD}, - {"exclusive", EXCLUSIVE, UNRESERVED_KEYWORD}, + {"current", CURRENT_P, UNRESERVED_KEYWORD}, + {"current_date", CURRENT_DATE, RESERVED_KEYWORD}, + {"current_role", CURRENT_ROLE, RESERVED_KEYWORD}, + {"current_time", CURRENT_TIME, RESERVED_KEYWORD}, + {"current_timestamp", CURRENT_TIMESTAMP, RESERVED_KEYWORD}, + {"current_user", CURRENT_USER, RESERVED_KEYWORD}, + {"cursor", CURSOR, UNRESERVED_KEYWORD}, + {"cycle", CYCLE, UNRESERVED_KEYWORD}, + {"database", DATABASE, UNRESERVED_KEYWORD}, + {"day", DAY_P, UNRESERVED_KEYWORD}, + {"deallocate", DEALLOCATE, UNRESERVED_KEYWORD}, + {"dec", DEC, COL_NAME_KEYWORD}, + {"decimal", DECIMAL_P, COL_NAME_KEYWORD}, + {"declare", DECLARE, UNRESERVED_KEYWORD}, + {"default", DEFAULT, RESERVED_KEYWORD}, + {"defaults", DEFAULTS, UNRESERVED_KEYWORD}, + {"deferrable", DEFERRABLE, RESERVED_KEYWORD}, + {"deferred", DEFERRED, UNRESERVED_KEYWORD}, + {"definer", DEFINER, UNRESERVED_KEYWORD}, + {"delete", DELETE_P, UNRESERVED_KEYWORD}, + {"delimiter", DELIMITER, UNRESERVED_KEYWORD}, + {"delimiters", DELIMITERS, UNRESERVED_KEYWORD}, + {"desc", DESC, RESERVED_KEYWORD}, + {"dictionary", DICTIONARY, UNRESERVED_KEYWORD}, + {"disable", DISABLE_P, UNRESERVED_KEYWORD}, + {"discard", DISCARD, UNRESERVED_KEYWORD}, + {"distinct", DISTINCT, RESERVED_KEYWORD}, + {"distributed", DISTRIBUTED_GP, UNRESERVED_KEYWORD}, /* Greenplum Keyword */ + {"do", DO, RESERVED_KEYWORD}, + {"document", DOCUMENT_P, UNRESERVED_KEYWORD}, + {"domain", DOMAIN_P, UNRESERVED_KEYWORD}, + {"double", DOUBLE_P, UNRESERVED_KEYWORD}, + {"drop", DROP, UNRESERVED_KEYWORD}, + {"each", EACH, UNRESERVED_KEYWORD}, + {"else", ELSE, RESERVED_KEYWORD}, + {"enable", ENABLE_P, UNRESERVED_KEYWORD}, + {"encoding", ENCODING, UNRESERVED_KEYWORD}, + {"encrypted", ENCRYPTED, UNRESERVED_KEYWORD}, + {"end", END_P, RESERVED_KEYWORD}, + {"enum", ENUM_P, UNRESERVED_KEYWORD}, + {"escape", ESCAPE, UNRESERVED_KEYWORD}, + {"except", EXCEPT, RESERVED_KEYWORD}, + {"excluding", EXCLUDING, UNRESERVED_KEYWORD}, + {"exclusive", EXCLUSIVE, UNRESERVED_KEYWORD}, {"exec", EXEC_EDB, RESERVED_KEYWORD}, /* EnterpriseDB Keyword */ {"execute", EXECUTE, UNRESERVED_KEYWORD}, {"exists", EXISTS, COL_NAME_KEYWORD}, @@ -238,216 +239,217 @@ {"localtimestamp", LOCALTIMESTAMP, RESERVED_KEYWORD}, {"location", LOCATION, UNRESERVED_KEYWORD}, {"lock", LOCK_P, UNRESERVED_KEYWORD}, + {"log", LOG_P_GP, RESERVED_KEYWORD}, /* Greenplum Keyword */ {"login", LOGIN_P, UNRESERVED_KEYWORD}, {"long", LONG_EDB, RESERVED_KEYWORD}, /* EnterpriseDB Keyword */ - {"mapping", MAPPING, UNRESERVED_KEYWORD}, - {"match", MATCH, UNRESERVED_KEYWORD}, - {"maxvalue", MAXVALUE, UNRESERVED_KEYWORD}, - {"minus", MINUS_EDB, RESERVED_KEYWORD}, /* EnterpriseDB Keyword */ - {"minute", MINUTE_P, UNRESERVED_KEYWORD}, - {"minvalue", MINVALUE, UNRESERVED_KEYWORD}, - {"mode", MODE, UNRESERVED_KEYWORD}, - {"month", MONTH_P, UNRESERVED_KEYWORD}, - {"move", MOVE, UNRESERVED_KEYWORD}, - {"name", NAME_P, UNRESERVED_KEYWORD}, - {"names", NAMES, UNRESERVED_KEYWORD}, - {"national", NATIONAL, COL_NAME_KEYWORD}, - {"natural", NATURAL, TYPE_FUNC_NAME_KEYWORD}, - {"nchar", NCHAR, COL_NAME_KEYWORD}, - {"new", NEW, RESERVED_KEYWORD}, - {"next", NEXT, UNRESERVED_KEYWORD}, - {"no", NO, UNRESERVED_KEYWORD}, + {"mapping", MAPPING, UNRESERVED_KEYWORD}, + {"match", MATCH, UNRESERVED_KEYWORD}, + {"maxvalue", MAXVALUE, UNRESERVED_KEYWORD}, + {"minus", MINUS_EDB, RESERVED_KEYWORD}, /* EnterpriseDB Keyword */ + {"minute", MINUTE_P, UNRESERVED_KEYWORD}, + {"minvalue", MINVALUE, UNRESERVED_KEYWORD}, + {"mode", MODE, UNRESERVED_KEYWORD}, + {"month", MONTH_P, UNRESERVED_KEYWORD}, + {"move", MOVE, UNRESERVED_KEYWORD}, + {"name", NAME_P, UNRESERVED_KEYWORD}, + {"names", NAMES, UNRESERVED_KEYWORD}, + {"national", NATIONAL, COL_NAME_KEYWORD}, + {"natural", NATURAL, TYPE_FUNC_NAME_KEYWORD}, + {"nchar", NCHAR, COL_NAME_KEYWORD}, + {"new", NEW, RESERVED_KEYWORD}, + {"next", NEXT, UNRESERVED_KEYWORD}, + {"no", NO, UNRESERVED_KEYWORD}, {"nocache", NOCACHE_EDB, RESERVED_KEYWORD}, /* EnterpriseDB Keyword */ - {"nocreatedb", NOCREATEDB, UNRESERVED_KEYWORD}, - {"nocreaterole", NOCREATEROLE, UNRESERVED_KEYWORD}, - {"nocreateuser", NOCREATEUSER, UNRESERVED_KEYWORD}, - {"noinherit", NOINHERIT, UNRESERVED_KEYWORD}, - {"nologin", NOLOGIN_P, UNRESERVED_KEYWORD}, - {"none", NONE, COL_NAME_KEYWORD}, - {"nosuperuser", NOSUPERUSER, UNRESERVED_KEYWORD}, - {"not", NOT, RESERVED_KEYWORD}, - {"nothing", NOTHING, UNRESERVED_KEYWORD}, - {"notify", NOTIFY, UNRESERVED_KEYWORD}, - {"notnull", NOTNULL, TYPE_FUNC_NAME_KEYWORD}, - {"nowait", NOWAIT, UNRESERVED_KEYWORD}, - {"null", NULL_P, RESERVED_KEYWORD}, - {"nullif", NULLIF, COL_NAME_KEYWORD}, - {"nulls", NULLS_P, UNRESERVED_KEYWORD}, + {"nocreatedb", NOCREATEDB, UNRESERVED_KEYWORD}, + {"nocreaterole", NOCREATEROLE, UNRESERVED_KEYWORD}, + {"nocreateuser", NOCREATEUSER, UNRESERVED_KEYWORD}, + {"noinherit", NOINHERIT, UNRESERVED_KEYWORD}, + {"nologin", NOLOGIN_P, UNRESERVED_KEYWORD}, + {"none", NONE, COL_NAME_KEYWORD}, + {"nosuperuser", NOSUPERUSER, UNRESERVED_KEYWORD}, + {"not", NOT, RESERVED_KEYWORD}, + {"nothing", NOTHING, UNRESERVED_KEYWORD}, + {"notify", NOTIFY, UNRESERVED_KEYWORD}, + {"notnull", NOTNULL, TYPE_FUNC_NAME_KEYWORD}, + {"nowait", NOWAIT, UNRESERVED_KEYWORD}, + {"null", NULL_P, RESERVED_KEYWORD}, + {"nullif", NULLIF, COL_NAME_KEYWORD}, + {"nulls", NULLS_P, UNRESERVED_KEYWORD}, {"number", NUMBER_EDB, RESERVED_KEYWORD}, /* EnterpriseDB Keyword */ - {"numeric", NUMERIC, COL_NAME_KEYWORD}, - {"object", OBJECT_P, UNRESERVED_KEYWORD}, - {"of", OF, UNRESERVED_KEYWORD}, - {"off", OFF, RESERVED_KEYWORD}, - {"offset", OFFSET, RESERVED_KEYWORD}, - {"oids", OIDS, UNRESERVED_KEYWORD}, - {"old", OLD, RESERVED_KEYWORD}, - {"on", ON, RESERVED_KEYWORD}, - {"only", ONLY, RESERVED_KEYWORD}, - {"operator", OPERATOR, UNRESERVED_KEYWORD}, - {"option", OPTION, UNRESERVED_KEYWORD}, - {"or", OR, RESERVED_KEYWORD}, - {"order", ORDER, RESERVED_KEYWORD}, - {"out", OUT_P, COL_NAME_KEYWORD}, - {"outer", OUTER_P, TYPE_FUNC_NAME_KEYWORD}, - {"overlaps", OVERLAPS, TYPE_FUNC_NAME_KEYWORD}, - {"overlay", OVERLAY, COL_NAME_KEYWORD}, - {"owned", OWNED, UNRESERVED_KEYWORD}, - {"owner", OWNER, UNRESERVED_KEYWORD}, + {"numeric", NUMERIC, COL_NAME_KEYWORD}, + {"object", OBJECT_P, UNRESERVED_KEYWORD}, + {"of", OF, UNRESERVED_KEYWORD}, + {"off", OFF, RESERVED_KEYWORD}, + {"offset", OFFSET, RESERVED_KEYWORD}, + {"oids", OIDS, UNRESERVED_KEYWORD}, + {"old", OLD, RESERVED_KEYWORD}, + {"on", ON, RESERVED_KEYWORD}, + {"only", ONLY, RESERVED_KEYWORD}, + {"operator", OPERATOR, UNRESERVED_KEYWORD}, + {"option", OPTION, UNRESERVED_KEYWORD}, + {"or", OR, RESERVED_KEYWORD}, + {"order", ORDER, RESERVED_KEYWORD}, + {"out", OUT_P, COL_NAME_KEYWORD}, + {"outer", OUTER_P, TYPE_FUNC_NAME_KEYWORD}, + {"overlaps", OVERLAPS, TYPE_FUNC_NAME_KEYWORD}, + {"overlay", OVERLAY, COL_NAME_KEYWORD}, + {"owned", OWNED, UNRESERVED_KEYWORD}, + {"owner", OWNER, UNRESERVED_KEYWORD}, {"package", PACKAGE_EDB, RESERVED_KEYWORD}, /* EnterpriseDB Keyword */ - {"parser", PARSER, UNRESERVED_KEYWORD}, - {"partial", PARTIAL, UNRESERVED_KEYWORD}, - {"password", PASSWORD, UNRESERVED_KEYWORD}, - {"placing", PLACING, RESERVED_KEYWORD}, - {"plans", PLANS, UNRESERVED_KEYWORD}, + {"parser", PARSER, UNRESERVED_KEYWORD}, + {"partial", PARTIAL, UNRESERVED_KEYWORD}, + {"password", PASSWORD, UNRESERVED_KEYWORD}, + {"placing", PLACING, RESERVED_KEYWORD}, + {"plans", PLANS, UNRESERVED_KEYWORD}, {"pls_integer", PLS_INTEGER_EDB, RESERVED_KEYWORD}, /* EnterpriseDB Keyword */ - {"position", POSITION, COL_NAME_KEYWORD}, - {"precision", PRECISION, COL_NAME_KEYWORD}, - {"prepare", PREPARE, UNRESERVED_KEYWORD}, - {"prepared", PREPARED, UNRESERVED_KEYWORD}, - {"preserve", PRESERVE, UNRESERVED_KEYWORD}, - {"primary", PRIMARY, RESERVED_KEYWORD}, - {"prior", PRIOR, UNRESERVED_KEYWORD}, - {"privileges", PRIVILEGES, UNRESERVED_KEYWORD}, - {"procedural", PROCEDURAL, UNRESERVED_KEYWORD}, - {"procedure", PROCEDURE, UNRESERVED_KEYWORD}, - {"quote", QUOTE, UNRESERVED_KEYWORD}, + {"position", POSITION, COL_NAME_KEYWORD}, + {"precision", PRECISION, COL_NAME_KEYWORD}, + {"prepare", PREPARE, UNRESERVED_KEYWORD}, + {"prepared", PREPARED, UNRESERVED_KEYWORD}, + {"preserve", PRESERVE, UNRESERVED_KEYWORD}, + {"primary", PRIMARY, RESERVED_KEYWORD}, + {"prior", PRIOR, UNRESERVED_KEYWORD}, + {"privileges", PRIVILEGES, UNRESERVED_KEYWORD}, + {"procedural", PROCEDURAL, UNRESERVED_KEYWORD}, + {"procedure", PROCEDURE, UNRESERVED_KEYWORD}, + {"quote", QUOTE, UNRESERVED_KEYWORD}, {"raw", RAW_EDB, RESERVED_KEYWORD}, /* EnterpriseDB Keyword */ - {"read", READ, UNRESERVED_KEYWORD}, - {"real", REAL, COL_NAME_KEYWORD}, - {"reassign", REASSIGN, UNRESERVED_KEYWORD}, - {"recheck", RECHECK, UNRESERVED_KEYWORD}, - {"references", REFERENCES, RESERVED_KEYWORD}, - {"reindex", REINDEX, UNRESERVED_KEYWORD}, - {"relative", RELATIVE_P, UNRESERVED_KEYWORD}, - {"release", RELEASE, UNRESERVED_KEYWORD}, - {"rename", RENAME, UNRESERVED_KEYWORD}, - {"repeatable", REPEATABLE, UNRESERVED_KEYWORD}, - {"replace", REPLACE, UNRESERVED_KEYWORD}, - {"replica", REPLICA, UNRESERVED_KEYWORD}, - {"reset", RESET, UNRESERVED_KEYWORD}, - {"restart", RESTART, UNRESERVED_KEYWORD}, - {"restrict", RESTRICT, UNRESERVED_KEYWORD}, + {"read", READ, UNRESERVED_KEYWORD}, + {"real", REAL, COL_NAME_KEYWORD}, + {"reassign", REASSIGN, UNRESERVED_KEYWORD}, + {"recheck", RECHECK, UNRESERVED_KEYWORD}, + {"references", REFERENCES, RESERVED_KEYWORD}, + {"reindex", REINDEX, UNRESERVED_KEYWORD}, + {"relative", RELATIVE_P, UNRESERVED_KEYWORD}, + {"release", RELEASE, UNRESERVED_KEYWORD}, + {"rename", RENAME, UNRESERVED_KEYWORD}, + {"repeatable", REPEATABLE, UNRESERVED_KEYWORD}, + {"replace", REPLACE, UNRESERVED_KEYWORD}, + {"replica", REPLICA, UNRESERVED_KEYWORD}, + {"reset", RESET, UNRESERVED_KEYWORD}, + {"restart", RESTART, UNRESERVED_KEYWORD}, + {"restrict", RESTRICT, UNRESERVED_KEYWORD}, {"return", RETURN_EDB, RESERVED_KEYWORD}, /* EnterpriseDB Keyword */ - {"returning", RETURNING, RESERVED_KEYWORD}, - {"returns", RETURNS, UNRESERVED_KEYWORD}, - {"revoke", REVOKE, UNRESERVED_KEYWORD}, - {"right", RIGHT, TYPE_FUNC_NAME_KEYWORD}, - {"role", ROLE, UNRESERVED_KEYWORD}, - {"rollback", ROLLBACK, UNRESERVED_KEYWORD}, - {"row", ROW, COL_NAME_KEYWORD}, - {"rows", ROWS, UNRESERVED_KEYWORD}, - {"rule", RULE, UNRESERVED_KEYWORD}, - {"savepoint", SAVEPOINT, UNRESERVED_KEYWORD}, - {"schema", SCHEMA, UNRESERVED_KEYWORD}, - {"scroll", SCROLL, UNRESERVED_KEYWORD}, - {"search", SEARCH, UNRESERVED_KEYWORD}, - {"second", SECOND_P, UNRESERVED_KEYWORD}, - {"security", SECURITY, UNRESERVED_KEYWORD}, - {"select", SELECT, RESERVED_KEYWORD}, - {"sequence", SEQUENCE, UNRESERVED_KEYWORD}, - {"serializable", SERIALIZABLE, UNRESERVED_KEYWORD}, - {"session", SESSION, UNRESERVED_KEYWORD}, - {"session_user", SESSION_USER, RESERVED_KEYWORD}, - {"set", SET, UNRESERVED_KEYWORD}, - {"setof", SETOF, COL_NAME_KEYWORD}, - {"share", SHARE, UNRESERVED_KEYWORD}, - {"show", SHOW, UNRESERVED_KEYWORD}, - {"similar", SIMILAR, TYPE_FUNC_NAME_KEYWORD}, - {"simple", SIMPLE, UNRESERVED_KEYWORD}, + {"returning", RETURNING, RESERVED_KEYWORD}, + {"returns", RETURNS, UNRESERVED_KEYWORD}, + {"revoke", REVOKE, UNRESERVED_KEYWORD}, + {"right", RIGHT, TYPE_FUNC_NAME_KEYWORD}, + {"role", ROLE, UNRESERVED_KEYWORD}, + {"rollback", ROLLBACK, UNRESERVED_KEYWORD}, + {"row", ROW, COL_NAME_KEYWORD}, + {"rows", ROWS, UNRESERVED_KEYWORD}, + {"rule", RULE, UNRESERVED_KEYWORD}, + {"savepoint", SAVEPOINT, UNRESERVED_KEYWORD}, + {"schema", SCHEMA, UNRESERVED_KEYWORD}, + {"scroll", SCROLL, UNRESERVED_KEYWORD}, + {"search", SEARCH, UNRESERVED_KEYWORD}, + {"second", SECOND_P, UNRESERVED_KEYWORD}, + {"security", SECURITY, UNRESERVED_KEYWORD}, + {"select", SELECT, RESERVED_KEYWORD}, + {"sequence", SEQUENCE, UNRESERVED_KEYWORD}, + {"serializable", SERIALIZABLE, UNRESERVED_KEYWORD}, + {"session", SESSION, UNRESERVED_KEYWORD}, + {"session_user", SESSION_USER, RESERVED_KEYWORD}, + {"set", SET, UNRESERVED_KEYWORD}, + {"setof", SETOF, COL_NAME_KEYWORD}, + {"share", SHARE, UNRESERVED_KEYWORD}, + {"show", SHOW, UNRESERVED_KEYWORD}, + {"similar", SIMILAR, TYPE_FUNC_NAME_KEYWORD}, + {"simple", SIMPLE, UNRESERVED_KEYWORD}, {"smalldatetime", SMALLDATETIME_EDB, RESERVED_KEYWORD}, /* EnterpriseDB Keyword */ - {"smallfloat", SMALLFLOAT_EDB, RESERVED_KEYWORD}, /* EnterpriseDB Keyword */ - {"smallint", SMALLINT, COL_NAME_KEYWORD}, - {"smallmoney", SMALLMONEY_EDB, RESERVED_KEYWORD}, /* EnterpriseDB Keyword */ - {"some", SOME, RESERVED_KEYWORD}, - {"stable", STABLE, UNRESERVED_KEYWORD}, - {"standalone", STANDALONE_P, UNRESERVED_KEYWORD}, - {"start", START, UNRESERVED_KEYWORD}, - {"statement", STATEMENT, UNRESERVED_KEYWORD}, - {"statistics", STATISTICS, UNRESERVED_KEYWORD}, - {"stdin", STDIN, UNRESERVED_KEYWORD}, - {"stdout", STDOUT, UNRESERVED_KEYWORD}, - {"storage", STORAGE, UNRESERVED_KEYWORD}, - {"strict", STRICT_P, UNRESERVED_KEYWORD}, - {"strip", STRIP_P, UNRESERVED_KEYWORD}, - {"substring", SUBSTRING, COL_NAME_KEYWORD}, - {"superuser", SUPERUSER_P, UNRESERVED_KEYWORD}, - {"symmetric", SYMMETRIC, RESERVED_KEYWORD}, + {"smallfloat", SMALLFLOAT_EDB, RESERVED_KEYWORD}, /* EnterpriseDB Keyword */ + {"smallint", SMALLINT, COL_NAME_KEYWORD}, + {"smallmoney", SMALLMONEY_EDB, RESERVED_KEYWORD}, /* EnterpriseDB Keyword */ + {"some", SOME, RESERVED_KEYWORD}, + {"stable", STABLE, UNRESERVED_KEYWORD}, + {"standalone", STANDALONE_P, UNRESERVED_KEYWORD}, + {"start", START, UNRESERVED_KEYWORD}, + {"statement", STATEMENT, UNRESERVED_KEYWORD}, + {"statistics", STATISTICS, UNRESERVED_KEYWORD}, + {"stdin", STDIN, UNRESERVED_KEYWORD}, + {"stdout", STDOUT, UNRESERVED_KEYWORD}, + {"storage", STORAGE, UNRESERVED_KEYWORD}, + {"strict", STRICT_P, UNRESERVED_KEYWORD}, + {"strip", STRIP_P, UNRESERVED_KEYWORD}, + {"substring", SUBSTRING, COL_NAME_KEYWORD}, + {"superuser", SUPERUSER_P, UNRESERVED_KEYWORD}, + {"symmetric", SYMMETRIC, RESERVED_KEYWORD}, {"sysdate", SYSDATE_EDB, RESERVED_KEYWORD}, /* EnterpriseDB Keyword */ - {"sysid", SYSID, UNRESERVED_KEYWORD}, - {"system", SYSTEM_P, UNRESERVED_KEYWORD}, + {"sysid", SYSID, UNRESERVED_KEYWORD}, + {"system", SYSTEM_P, UNRESERVED_KEYWORD}, {"systimestamp", SYSTIMESTAMP_EDB, RESERVED_KEYWORD}, /* EnterpriseDB Keyword */ - {"table", TABLE, RESERVED_KEYWORD}, - {"tablespace", TABLESPACE, UNRESERVED_KEYWORD}, - {"temp", TEMP, UNRESERVED_KEYWORD}, - {"template", TEMPLATE, UNRESERVED_KEYWORD}, - {"temporary", TEMPORARY, UNRESERVED_KEYWORD}, - {"text", TEXT_P, UNRESERVED_KEYWORD}, - {"then", THEN, RESERVED_KEYWORD}, - {"time", TIME, COL_NAME_KEYWORD}, - {"timestamp", TIMESTAMP, COL_NAME_KEYWORD}, - {"tinyint", TINYINT_EDB, RESERVED_KEYWORD}, /* EnterpriseDB Keyword */ - {"tinytext", TINYTEXT_EDB, RESERVED_KEYWORD}, /* EnterpriseDB Keyword */ - {"to", TO, RESERVED_KEYWORD}, - {"trailing", TRAILING, RESERVED_KEYWORD}, - {"transaction", TRANSACTION, UNRESERVED_KEYWORD}, - {"treat", TREAT, COL_NAME_KEYWORD}, - {"trigger", TRIGGER, UNRESERVED_KEYWORD}, - {"trim", TRIM, COL_NAME_KEYWORD}, - {"true", TRUE_P, RESERVED_KEYWORD}, - {"truncate", TRUNCATE, UNRESERVED_KEYWORD}, - {"trusted", TRUSTED, UNRESERVED_KEYWORD}, - {"type", TYPE_P, UNRESERVED_KEYWORD}, - {"uncommitted", UNCOMMITTED, UNRESERVED_KEYWORD}, - {"unencrypted", UNENCRYPTED, UNRESERVED_KEYWORD}, - {"union", UNION, RESERVED_KEYWORD}, - {"unique", UNIQUE, RESERVED_KEYWORD}, - {"unknown", UNKNOWN, UNRESERVED_KEYWORD}, - {"unlisten", UNLISTEN, UNRESERVED_KEYWORD}, - {"until", UNTIL, UNRESERVED_KEYWORD}, - {"update", UPDATE, UNRESERVED_KEYWORD}, - {"user", USER, RESERVED_KEYWORD}, - {"using", USING, RESERVED_KEYWORD}, - {"vacuum", VACUUM, UNRESERVED_KEYWORD}, - {"valid", VALID, UNRESERVED_KEYWORD}, - {"validator", VALIDATOR, UNRESERVED_KEYWORD}, - {"value", VALUE_P, UNRESERVED_KEYWORD}, - {"values", VALUES, COL_NAME_KEYWORD}, - {"varchar", VARCHAR, COL_NAME_KEYWORD}, + {"table", TABLE, RESERVED_KEYWORD}, + {"tablespace", TABLESPACE, UNRESERVED_KEYWORD}, + {"temp", TEMP, UNRESERVED_KEYWORD}, + {"template", TEMPLATE, UNRESERVED_KEYWORD}, + {"temporary", TEMPORARY, UNRESERVED_KEYWORD}, + {"text", TEXT_P, UNRESERVED_KEYWORD}, + {"then", THEN, RESERVED_KEYWORD}, + {"time", TIME, COL_NAME_KEYWORD}, + {"timestamp", TIMESTAMP, COL_NAME_KEYWORD}, + {"tinyint", TINYINT_EDB, RESERVED_KEYWORD}, /* EnterpriseDB Keyword */ + {"tinytext", TINYTEXT_EDB, RESERVED_KEYWORD}, /* EnterpriseDB Keyword */ + {"to", TO, RESERVED_KEYWORD}, + {"trailing", TRAILING, RESERVED_KEYWORD}, + {"transaction", TRANSACTION, UNRESERVED_KEYWORD}, + {"treat", TREAT, COL_NAME_KEYWORD}, + {"trigger", TRIGGER, UNRESERVED_KEYWORD}, + {"trim", TRIM, COL_NAME_KEYWORD}, + {"true", TRUE_P, RESERVED_KEYWORD}, + {"truncate", TRUNCATE, UNRESERVED_KEYWORD}, + {"trusted", TRUSTED, UNRESERVED_KEYWORD}, + {"type", TYPE_P, UNRESERVED_KEYWORD}, + {"uncommitted", UNCOMMITTED, UNRESERVED_KEYWORD}, + {"unencrypted", UNENCRYPTED, UNRESERVED_KEYWORD}, + {"union", UNION, RESERVED_KEYWORD}, + {"unique", UNIQUE, RESERVED_KEYWORD}, + {"unknown", UNKNOWN, UNRESERVED_KEYWORD}, + {"unlisten", UNLISTEN, UNRESERVED_KEYWORD}, + {"until", UNTIL, UNRESERVED_KEYWORD}, + {"update", UPDATE, UNRESERVED_KEYWORD}, + {"user", USER, RESERVED_KEYWORD}, + {"using", USING, RESERVED_KEYWORD}, + {"vacuum", VACUUM, UNRESERVED_KEYWORD}, + {"valid", VALID, UNRESERVED_KEYWORD}, + {"validator", VALIDATOR, UNRESERVED_KEYWORD}, + {"value", VALUE_P, UNRESERVED_KEYWORD}, + {"values", VALUES, COL_NAME_KEYWORD}, + {"varchar", VARCHAR, COL_NAME_KEYWORD}, {"varchar2", VARCHAR2_EDB, RESERVED_KEYWORD}, /* EnterpriseDB Keyword */ - {"varying", VARYING, UNRESERVED_KEYWORD}, - {"verbose", VERBOSE, TYPE_FUNC_NAME_KEYWORD}, - {"version", VERSION_P, UNRESERVED_KEYWORD}, - {"view", VIEW, UNRESERVED_KEYWORD}, - {"volatile", VOLATILE, UNRESERVED_KEYWORD}, - {"when", WHEN, RESERVED_KEYWORD}, - {"where", WHERE, RESERVED_KEYWORD}, - {"whitespace", WHITESPACE_P, UNRESERVED_KEYWORD}, + {"varying", VARYING, UNRESERVED_KEYWORD}, + {"verbose", VERBOSE, TYPE_FUNC_NAME_KEYWORD}, + {"version", VERSION_P, UNRESERVED_KEYWORD}, + {"view", VIEW, UNRESERVED_KEYWORD}, + {"volatile", VOLATILE, UNRESERVED_KEYWORD}, + {"when", WHEN, RESERVED_KEYWORD}, + {"where", WHERE, RESERVED_KEYWORD}, + {"whitespace", WHITESPACE_P, UNRESERVED_KEYWORD}, - /* - * XXX we mark WITH as reserved to force it to be quoted in dumps, even - * though it is currently unreserved according to gram.y. This is because - * we expect we'll have to make it reserved to implement SQL WITH clauses. - * If that patch manages to do without reserving WITH, adjust this entry - * at that time; in any case this should be back in sync with gram.y after - * WITH clauses are implemented. - */ + /* + * XXX we mark WITH as reserved to force it to be quoted in dumps, even + * though it is currently unreserved according to gram.y. This is because + * we expect we'll have to make it reserved to implement SQL WITH clauses. + * If that patch manages to do without reserving WITH, adjust this entry + * at that time; in any case this should be back in sync with gram.y after + * WITH clauses are implemented. + */ {"window", WINDOW, RESERVED_KEYWORD}, - {"with", WITH, RESERVED_KEYWORD}, - {"without", WITHOUT, UNRESERVED_KEYWORD}, - {"work", WORK, UNRESERVED_KEYWORD}, - {"write", WRITE, UNRESERVED_KEYWORD}, - {"xml", XML_P, UNRESERVED_KEYWORD}, - {"xmlattributes", XMLATTRIBUTES, COL_NAME_KEYWORD}, - {"xmlconcat", XMLCONCAT, COL_NAME_KEYWORD}, - {"xmlelement", XMLELEMENT, COL_NAME_KEYWORD}, - {"xmlforest", XMLFOREST, COL_NAME_KEYWORD}, - {"xmlparse", XMLPARSE, COL_NAME_KEYWORD}, - {"xmlpi", XMLPI, COL_NAME_KEYWORD}, - {"xmlroot", XMLROOT, COL_NAME_KEYWORD}, - {"xmlserialize", XMLSERIALIZE, COL_NAME_KEYWORD}, - {"year", YEAR_P, UNRESERVED_KEYWORD}, - {"yes", YES_P, UNRESERVED_KEYWORD}, - {"zone", ZONE, UNRESERVED_KEYWORD}, + {"with", WITH, RESERVED_KEYWORD}, + {"without", WITHOUT, UNRESERVED_KEYWORD}, + {"work", WORK, UNRESERVED_KEYWORD}, + {"write", WRITE, UNRESERVED_KEYWORD}, + {"xml", XML_P, UNRESERVED_KEYWORD}, + {"xmlattributes", XMLATTRIBUTES, COL_NAME_KEYWORD}, + {"xmlconcat", XMLCONCAT, COL_NAME_KEYWORD}, + {"xmlelement", XMLELEMENT, COL_NAME_KEYWORD}, + {"xmlforest", XMLFOREST, COL_NAME_KEYWORD}, + {"xmlparse", XMLPARSE, COL_NAME_KEYWORD}, + {"xmlpi", XMLPI, COL_NAME_KEYWORD}, + {"xmlroot", XMLROOT, COL_NAME_KEYWORD}, + {"xmlserialize", XMLSERIALIZE, COL_NAME_KEYWORD}, + {"year", YEAR_P, UNRESERVED_KEYWORD}, + {"yes", YES_P, UNRESERVED_KEYWORD}, + {"zone", ZONE, UNRESERVED_KEYWORD}, }; /* @@ -465,50 +467,50 @@ const ScanKeyword * ScanKeywordLookup(const char *text) { - int len, - i; - char word[NAMEDATALEN]; - const ScanKeyword *low; - const ScanKeyword *high; + int len, + i; + char word[NAMEDATALEN]; + const ScanKeyword *low; + const ScanKeyword *high; - len = strlen(text); - /* We assume all keywords are shorter than NAMEDATALEN. */ - if (len >= NAMEDATALEN) - return NULL; + len = strlen(text); + /* We assume all keywords are shorter than NAMEDATALEN. */ + if (len >= NAMEDATALEN) + return NULL; - /* - * Apply an ASCII-only downcasing. We must not use tolower() since it may - * produce the wrong translation in some locales (eg, Turkish). - */ - for (i = 0; i < len; i++) - { - char ch = text[i]; + /* + * Apply an ASCII-only downcasing. We must not use tolower() since it may + * produce the wrong translation in some locales (eg, Turkish). + */ + for (i = 0; i < len; i++) + { + char ch = text[i]; - if (ch >= 'A' && ch <= 'Z') - ch += 'a' - 'A'; - word[i] = ch; - } - word[len] = '\0'; + if (ch >= 'A' && ch <= 'Z') + ch += 'a' - 'A'; + word[i] = ch; + } + word[len] = '\0'; - /* - * Now do a binary search using plain strcmp() comparison. - */ - low = &ScanKeywords[0]; - high = endof(ScanKeywords) - 1; - while (low <= high) - { - const ScanKeyword *middle; - int difference; + /* + * Now do a binary search using plain strcmp() comparison. + */ + low = &ScanKeywords[0]; + high = endof(ScanKeywords) - 1; + while (low <= high) + { + const ScanKeyword *middle; + int difference; - middle = low + (high - low) / 2; - difference = strcmp(middle->name, word); - if (difference == 0) - return middle; - else if (difference < 0) - low = middle + 1; - else - high = middle - 1; - } + middle = low + (high - low) / 2; + difference = strcmp(middle->name, word); + if (difference == 0) + return middle; + else if (difference < 0) + low = middle + 1; + else + high = middle - 1; + } - return NULL; + return NULL; } Index: pgadmin/schema/module.mk =================================================================== --- pgadmin/schema/module.mk (revision 7597) +++ pgadmin/schema/module.mk (working copy) @@ -51,7 +51,10 @@ $(subdir)/pgTrigger.cpp \ $(subdir)/pgType.cpp \ $(subdir)/pgUser.cpp \ - $(subdir)/pgView.cpp + $(subdir)/pgView.cpp \ + $(subdir)/pgExtTable.cpp \ + $(subdir)/pgResQueue.cpp \ + $(subdir)/pgPartition.cpp EXTRA_DIST += \ $(srcdir)/schema/module.mk Index: pgadmin/schema/pgSchema.cpp =================================================================== --- pgadmin/schema/pgSchema.cpp (revision 7597) +++ pgadmin/schema/pgSchema.cpp (working copy) @@ -29,12 +29,14 @@ #include "schema/pgOperatorFamily.h" #include "schema/pgSequence.h" #include "schema/pgTable.h" +#include "schema/pgExtTable.h" #include "schema/pgTextSearchConfiguration.h" #include "schema/pgTextSearchDictionary.h" #include "schema/pgTextSearchParser.h" #include "schema/pgTextSearchTemplate.h" #include "schema/pgType.h" #include "schema/pgView.h" +#include "schema/pgPartition.h" #include "frm/frmReport.h" #include "wx/regex.h" @@ -56,20 +58,20 @@ wxString pgCatalog::GetDisplayName() { - if (GetFullName() == wxT("pg_catalog")) - return wxT("PostgreSQL (pg_catalog)"); - else if (GetFullName() == wxT("pgagent")) - return wxT("pgAgent (pgagent)"); - else if (GetFullName() == wxT("information_schema")) - return wxT("ANSI (information_schema)"); - else if (GetFullName().StartsWith(wxT("_"))) - return wxT("Slony cluster (") + GetFullName().AfterFirst('_') + wxT(")"); - else if (GetFullName() == wxT("dbo")) - return wxT("Redmond (dbo)"); - else if (GetFullName() == wxT("sys")) - return wxT("Redwood (sys)"); - else - return GetFullName(); + if (GetFullName() == wxT("pg_catalog")) + return wxT("PostgreSQL (pg_catalog)"); + else if (GetFullName() == wxT("pgagent")) + return wxT("pgAgent (pgagent)"); + else if (GetFullName() == wxT("information_schema")) + return wxT("ANSI (information_schema)"); + else if (GetFullName().StartsWith(wxT("_"))) + return wxT("Slony cluster (") + GetFullName().AfterFirst('_') + wxT(")"); + else if (GetFullName() == wxT("dbo")) + return wxT("Redmond (dbo)"); + else if (GetFullName() == wxT("sys")) + return wxT("Redwood (sys)"); + else + return GetFullName(); } @@ -103,6 +105,8 @@ sequenceFactory.AppendMenu(menu); if (settings->GetDisplayOption(_("Tables"))) tableFactory.AppendMenu(menu); + if (settings->GetDisplayOption(_("Partitions"))) + partitionFactory.AppendMenu(menu); if (settings->GetDisplayOption(_("FTS Configurations"))) { if (GetConnection()->BackendMinimumVersion(8, 3)) @@ -129,6 +133,11 @@ typeFactory.AppendMenu(menu); if (settings->GetDisplayOption(_("Views"))) viewFactory.AppendMenu(menu); + if (settings->GetDisplayOption(_("External Tables"))) + { + if (GetConnection() != 0 && GetConnection()->GetIsGreenplum()) + extTableFactory.AppendMenu(menu); + } } return menu; } @@ -181,64 +190,67 @@ if (!(GetMetaType() == PGM_CATALOG && (GetFullName() == wxT("dbo") || GetFullName() == wxT("sys") || GetFullName() == wxT("information_schema")))) { if (settings->GetDisplayOption(_("Aggregates"))) - browser->AppendCollection(this, aggregateFactory); - if (settings->GetDisplayOption(_("Conversions"))) - browser->AppendCollection(this, conversionFactory); - if (settings->GetDisplayOption(_("Domains"))) - browser->AppendCollection(this, domainFactory); - if (settings->GetDisplayOption(_("FTS Configurations"))) + browser->AppendCollection(this, aggregateFactory); + if (settings->GetDisplayOption(_("Conversions"))) + browser->AppendCollection(this, conversionFactory); + if (settings->GetDisplayOption(_("Domains"))) + browser->AppendCollection(this, domainFactory); + if (settings->GetDisplayOption(_("FTS Configurations"))) { if (GetConnection()->BackendMinimumVersion(8, 3)) - browser->AppendCollection(this, textSearchConfigurationFactory); + browser->AppendCollection(this, textSearchConfigurationFactory); } - if (settings->GetDisplayOption(_("FTS Dictionaries"))) + if (settings->GetDisplayOption(_("FTS Dictionaries"))) { if (GetConnection()->BackendMinimumVersion(8, 3)) - browser->AppendCollection(this, textSearchDictionaryFactory); + browser->AppendCollection(this, textSearchDictionaryFactory); } - if (settings->GetDisplayOption(_("FTS Parsers"))) + if (settings->GetDisplayOption(_("FTS Parsers"))) { if (GetConnection()->BackendMinimumVersion(8, 3)) - browser->AppendCollection(this, textSearchParserFactory); + browser->AppendCollection(this, textSearchParserFactory); } - if (settings->GetDisplayOption(_("FTS Templates"))) + if (settings->GetDisplayOption(_("FTS Templates"))) { if (GetConnection()->BackendMinimumVersion(8, 3)) - browser->AppendCollection(this, textSearchTemplateFactory); + browser->AppendCollection(this, textSearchTemplateFactory); } - if (settings->GetDisplayOption(_("Functions"))) - browser->AppendCollection(this, functionFactory); + if (settings->GetDisplayOption(_("Functions"))) + browser->AppendCollection(this, functionFactory); - if (settings->GetDisplayOption(_("Operators"))) - browser->AppendCollection(this, operatorFactory); - if (settings->GetDisplayOption(_("Operator classes"))) - browser->AppendCollection(this, operatorClassFactory); + if (settings->GetDisplayOption(_("Operators"))) + browser->AppendCollection(this, operatorFactory); + if (settings->GetDisplayOption(_("Operator classes"))) + browser->AppendCollection(this, operatorClassFactory); - if (settings->GetDisplayOption(_("Operator families"))) - { - if (GetConnection()->BackendMinimumVersion(8, 3)) - browser->AppendCollection(this, operatorFamilyFactory); - } + if (settings->GetDisplayOption(_("Operator families"))) + { + if (GetConnection()->BackendMinimumVersion(8, 3)) + browser->AppendCollection(this, operatorFamilyFactory); + } - if (settings->GetDisplayOption(_("Packages")) && GetConnection()->EdbMinimumVersion(8,1)) - browser->AppendCollection(this, packageFactory); + if (settings->GetDisplayOption(_("Packages")) && GetConnection()->EdbMinimumVersion(8,1)) + browser->AppendCollection(this, packageFactory); - if (settings->GetDisplayOption(_("Procedures"))) - { - if (GetConnection()->EdbMinimumVersion(8, 0)) - browser->AppendCollection(this, procedureFactory); - } + if (settings->GetDisplayOption(_("Procedures"))) + { + if (GetConnection()->EdbMinimumVersion(8, 0)) + browser->AppendCollection(this, procedureFactory); + } - if (settings->GetDisplayOption(_("Sequences"))) - browser->AppendCollection(this, sequenceFactory); - if (settings->GetDisplayOption(_("Tables"))) - browser->AppendCollection(this, tableFactory); - if (settings->GetDisplayOption(_("Trigger functions"))) - browser->AppendCollection(this, triggerFunctionFactory); - if (settings->GetDisplayOption(_("Types"))) - browser->AppendCollection(this, typeFactory); - if (settings->GetDisplayOption(_("Views"))) - browser->AppendCollection(this, viewFactory); + if (settings->GetDisplayOption(_("Sequences"))) + browser->AppendCollection(this, sequenceFactory); + if (settings->GetDisplayOption(_("Tables"))) + browser->AppendCollection(this, tableFactory); + if (settings->GetDisplayOption(_("External Tables"))) + if (GetConnection() != 0 && GetConnection()->GetIsGreenplum()) + browser->AppendCollection(this, extTableFactory); + if (settings->GetDisplayOption(_("Trigger functions"))) + browser->AppendCollection(this, triggerFunctionFactory); + if (settings->GetDisplayOption(_("Types"))) + browser->AppendCollection(this, typeFactory); + if (settings->GetDisplayOption(_("Views"))) + browser->AppendCollection(this, viewFactory); } else browser->AppendCollection(this, catalogObjectFactory); @@ -252,9 +264,9 @@ properties->AppendItem(_("Name"), GetName()); properties->AppendItem(_("OID"), GetOid()); properties->AppendItem(_("Owner"), GetOwner()); - properties->AppendItem(_("ACL"), GetAcl()); - if (GetMetaType() != PGM_CATALOG) - properties->AppendItem(_("System schema?"), GetSystemObject()); + properties->AppendItem(_("ACL"), GetAcl()); + if (GetMetaType() != PGM_CATALOG) + properties->AppendItem(_("System schema?"), GetSystemObject()); properties->AppendItem(_("Comment"), firstLineOnly(GetComment())); } } @@ -291,16 +303,16 @@ restr += wxT(" AND "); if (GetMetaType() != PGM_CATALOG) - { - restr += wxT("NOT "); - } + { + restr += wxT("NOT "); + } - restr += wxT("((nspname = 'pg_catalog' and (SELECT count(*) FROM pg_class WHERE relname = 'pg_class' AND relnamespace = nsp.oid) > 0) OR\n"); - restr += wxT("(nspname = 'pgagent' and (SELECT count(*) FROM pg_class WHERE relname = 'pga_job' AND relnamespace = nsp.oid) > 0) OR\n"); - restr += wxT("(nspname = 'information_schema' and (SELECT count(*) FROM pg_class WHERE relname = 'tables' AND relnamespace = nsp.oid) > 0) OR\n"); - restr += wxT("(nspname LIKE '_%' and (SELECT count(*) FROM pg_proc WHERE proname='slonyversion' AND pronamespace = nsp.oid) > 0) OR\n"); - restr += wxT("(nspname = 'dbo' and (SELECT count(*) FROM pg_class WHERE relname = 'systables' AND relnamespace = nsp.oid) > 0) OR\n"); - restr += wxT("(nspname = 'sys' and (SELECT count(*) FROM pg_class WHERE relname = 'all_tables' AND relnamespace = nsp.oid) > 0))\n"); + restr += wxT("((nspname = 'pg_catalog' and (SELECT count(*) FROM pg_class WHERE relname = 'pg_class' AND relnamespace = nsp.oid) > 0) OR\n"); + restr += wxT("(nspname = 'pgagent' and (SELECT count(*) FROM pg_class WHERE relname = 'pga_job' AND relnamespace = nsp.oid) > 0) OR\n"); + restr += wxT("(nspname = 'information_schema' and (SELECT count(*) FROM pg_class WHERE relname = 'tables' AND relnamespace = nsp.oid) > 0) OR\n"); + restr += wxT("(nspname LIKE '_%' and (SELECT count(*) FROM pg_proc WHERE proname='slonyversion' AND pronamespace = nsp.oid) > 0) OR\n"); + restr += wxT("(nspname = 'dbo' and (SELECT count(*) FROM pg_class WHERE relname = 'systables' AND relnamespace = nsp.oid) > 0) OR\n"); + restr += wxT("(nspname = 'sys' and (SELECT count(*) FROM pg_class WHERE relname = 'all_tables' AND relnamespace = nsp.oid) > 0))\n"); if (collection->GetConnection()->EdbMinimumVersion(8, 2)) restr += wxT(" AND nsp.nspparent = 0\n"); @@ -308,48 +320,48 @@ if (!collection->GetDatabase()->GetSchemaRestriction().IsEmpty()) restr += wxT(" AND nspname IN (") + collection->GetDatabase()->GetSchemaRestriction() + wxT(")"); - // Don't fetch temp schemas if not actually required, as Greenplum seems to - // generate thousands in some circumstances. - if (!settings->GetShowSystemObjects()) - { - if (collection->GetDatabase()->BackendMinimumVersion(8, 1)) - restr += wxT(" AND nspname NOT LIKE E'pg\\\\_temp\\\\_%'AND nspname NOT LIKE E'pg\\\\_toast_temp\\\\_%'"); - else - restr += wxT(" AND nspname NOT LIKE 'pg\\\\_temp\\\\_%'AND nspname NOT LIKE 'pg\\\\_toast_temp\\\\_%'"); - } + // Don't fetch temp schemas if not actually required, as Greenplum seems to + // generate thousands in some circumstances. + if (!settings->GetShowSystemObjects()) + { + if (collection->GetDatabase()->BackendMinimumVersion(8, 1)) + restr += wxT(" AND nspname NOT LIKE E'pg\\\\_temp\\\\_%'AND nspname NOT LIKE E'pg\\\\_toast_temp\\\\_%'"); + else + restr += wxT(" AND nspname NOT LIKE 'pg\\\\_temp\\\\_%'AND nspname NOT LIKE 'pg\\\\_toast_temp\\\\_%'"); + } - wxString sql; + wxString sql; - if (GetMetaType() == PGM_CATALOG) - { - sql = wxT("SELECT 2 AS nsptyp,\n") - wxT(" nsp.nspname, nsp.oid, pg_get_userbyid(nspowner) AS namespaceowner, nspacl, description,") - wxT(" FALSE as cancreate\n") - wxT(" FROM pg_namespace nsp\n") - wxT(" LEFT OUTER JOIN pg_description des ON des.objoid=nsp.oid\n") - + restr + - wxT(" ORDER BY 1, nspname"); - } - else - { - if (collection->GetDatabase()->BackendMinimumVersion(8, 1)) - { - sql = wxT("SELECT CASE WHEN nspname LIKE E'pg\\\\_temp\\\\_%' THEN 1\n") - wxT(" WHEN (nspname LIKE E'pg\\\\_%') THEN 0\n"); - } - else - { - sql = wxT("SELECT CASE WHEN nspname LIKE 'pg\\\\_temp\\\\_%' THEN 1\n") - wxT(" WHEN (nspname LIKE 'pg\\\\_%') THEN 0\n"); - } - sql += wxT(" ELSE 3 END AS nsptyp,\n") - wxT(" nsp.nspname, nsp.oid, pg_get_userbyid(nspowner) AS namespaceowner, nspacl, description,") - wxT(" has_schema_privilege(nsp.oid, 'CREATE') as cancreate\n") - wxT(" FROM pg_namespace nsp\n") - wxT(" LEFT OUTER JOIN pg_description des ON des.objoid=nsp.oid\n") - + restr + - wxT(" ORDER BY 1, nspname"); - } + if (GetMetaType() == PGM_CATALOG) + { + sql = wxT("SELECT 2 AS nsptyp,\n") + wxT(" nsp.nspname, nsp.oid, pg_get_userbyid(nspowner) AS namespaceowner, nspacl, description,") + wxT(" FALSE as cancreate\n") + wxT(" FROM pg_namespace nsp\n") + wxT(" LEFT OUTER JOIN pg_description des ON des.objoid=nsp.oid\n") + + restr + + wxT(" ORDER BY 1, nspname"); + } + else + { + if (collection->GetDatabase()->BackendMinimumVersion(8, 1)) + { + sql = wxT("SELECT CASE WHEN nspname LIKE E'pg\\\\_temp\\\\_%' THEN 1\n") + wxT(" WHEN (nspname LIKE E'pg\\\\_%') THEN 0\n"); + } + else + { + sql = wxT("SELECT CASE WHEN nspname LIKE 'pg\\\\_temp\\\\_%' THEN 1\n") + wxT(" WHEN (nspname LIKE 'pg\\\\_%') THEN 0\n"); + } + sql += wxT(" ELSE 3 END AS nsptyp,\n") + wxT(" nsp.nspname, nsp.oid, pg_get_userbyid(nspowner) AS namespaceowner, nspacl, description,") + wxT(" has_schema_privilege(nsp.oid, 'CREATE') as cancreate\n") + wxT(" FROM pg_namespace nsp\n") + wxT(" LEFT OUTER JOIN pg_description des ON des.objoid=nsp.oid\n") + + restr + + wxT(" ORDER BY 1, nspname"); + } pgSet *schemas = collection->GetDatabase()->ExecuteSet(sql); @@ -377,55 +389,55 @@ continue; } - if (GetMetaType() == PGM_CATALOG) - { - catalog = new pgCatalog(name); + if (GetMetaType() == PGM_CATALOG) + { + catalog = new pgCatalog(name); - catalog->iSetSchemaTyp(nsptyp); - catalog->iSetDatabase(collection->GetDatabase()); - catalog->iSetComment(schemas->GetVal(wxT("description"))); - catalog->iSetOid(schemas->GetOid(wxT("oid"))); - catalog->iSetOwner(schemas->GetVal(wxT("namespaceowner"))); - catalog->iSetAcl(schemas->GetVal(wxT("nspacl"))); - catalog->iSetCreatePrivilege(false); + catalog->iSetSchemaTyp(nsptyp); + catalog->iSetDatabase(collection->GetDatabase()); + catalog->iSetComment(schemas->GetVal(wxT("description"))); + catalog->iSetOid(schemas->GetOid(wxT("oid"))); + catalog->iSetOwner(schemas->GetVal(wxT("namespaceowner"))); + catalog->iSetAcl(schemas->GetVal(wxT("nspacl"))); + catalog->iSetCreatePrivilege(false); - if (browser) - { - browser->AppendObject(collection, catalog); - schemas->MoveNext(); - } - else - break; - } - else - { - schema = new pgSchema(name); + if (browser) + { + browser->AppendObject(collection, catalog); + schemas->MoveNext(); + } + else + break; + } + else + { + schema = new pgSchema(name); - schema->iSetSchemaTyp(nsptyp); - schema->iSetDatabase(collection->GetDatabase()); - schema->iSetComment(schemas->GetVal(wxT("description"))); - schema->iSetOid(schemas->GetOid(wxT("oid"))); - schema->iSetOwner(schemas->GetVal(wxT("namespaceowner"))); - schema->iSetAcl(schemas->GetVal(wxT("nspacl"))); - schema->iSetCreatePrivilege(schemas->GetBool(wxT("cancreate"))); + schema->iSetSchemaTyp(nsptyp); + schema->iSetDatabase(collection->GetDatabase()); + schema->iSetComment(schemas->GetVal(wxT("description"))); + schema->iSetOid(schemas->GetOid(wxT("oid"))); + schema->iSetOwner(schemas->GetVal(wxT("namespaceowner"))); + schema->iSetAcl(schemas->GetVal(wxT("nspacl"))); + schema->iSetCreatePrivilege(schemas->GetBool(wxT("cancreate"))); - if (browser) - { - browser->AppendObject(collection, schema); - schemas->MoveNext(); - } - else - break; - } + if (browser) + { + browser->AppendObject(collection, schema); + schemas->MoveNext(); + } + else + break; + } } - delete schemas; + delete schemas; } - if (GetMetaType() == PGM_CATALOG) - return catalog; - else - return schema; + if (GetMetaType() == PGM_CATALOG) + return catalog; + else + return schema; } @@ -454,8 +466,8 @@ bool pgSchemaObjCollection::CanCreate() { - if(IsCollectionForType(PGM_OPCLASS) || IsCollectionForType(PGM_OPFAMILY)) - return false; + if(IsCollectionForType(PGM_OPCLASS) || IsCollectionForType(PGM_OPFAMILY)) + return false; // TODO // OK, this is a hack. Rules and Views are both derived from pgRuleObject, which @@ -464,7 +476,7 @@ // View (yeah, I know - I didn't write it :-p ). This works fine *except* for // Get CreatePrivilege() which doesn't exist in these classes so must be fixed // up at this level. This needs a major rethink in the longer term - if (GetSchema()->GetMetaType() == PGM_TABLE || GetSchema()->GetMetaType() == PGM_VIEW) + if (GetSchema()->GetMetaType() == PGM_TABLE || GetSchema()->GetMetaType() == PGM_VIEW || GetSchema()->GetMetaType() == PGM_EXTTABLE) return GetSchema()->GetSchema()->GetCreatePrivilege(); else return GetSchema()->GetCreatePrivilege(); @@ -493,7 +505,7 @@ pgCatalogFactory::pgCatalogFactory() : pgSchemaBaseFactory(__("Catalog"), __("New Catalog..."), __("Create a new Catalog."), catalog_xpm, catalog_sm_xpm) { - metaType = PGM_CATALOG; + metaType = PGM_CATALOG; } pgCollection *pgSchemaObjFactory::CreateCollection(pgObject *obj) Index: pgadmin/schema/pgRole.cpp =================================================================== --- pgadmin/schema/pgRole.cpp (revision 7597) +++ pgadmin/schema/pgRole.cpp (working copy) @@ -54,7 +54,7 @@ bool pgRole::DropObject(wxFrame *frame, ctlTree *browser, bool cascaded) { - if (GetUpdateCatalog()) + if (GetUpdateCatalog()) { wxMessageDialog dlg(frame, _("Deleting a superuser might result in unwanted behaviour (e.g. when restoring the database).\nAre you sure?"), @@ -94,6 +94,8 @@ sql += wxT(" CONNECTION LIMIT ") + NumToStr(GetConnectionLimit()); if (GetAccountExpires().IsValid()) AppendIfFilled(sql, wxT(" VALID UNTIL "), qtDbString(DateToAnsiStr(GetAccountExpires()))); + if (GetRolQueueName().Length() > 0) + AppendIfFilled(sql, wxT(" RESOURCE QUEUE "), GetRolQueueName()); sql +=wxT(";\n"); if (this->GetSuperuser() && !GetUpdateCatalog()) @@ -288,42 +290,42 @@ void pgRole::ReassignDropOwnedTo(frmMain *form) { - wxString query; - - dlgReassignDropOwned rdo(form, GetConnection(), this, GetServer()->GetDbRestriction()); - if (rdo.ShowModal() != wxID_CANCEL) - { - pgConn *conn; - conn = new pgConn(GetConnection()->GetHost(), - rdo.GetDatabase(), - GetConnection()->GetUser(), - GetConnection()->GetPassword(), - GetConnection()->GetPort(), - GetConnection()->GetSslMode()); - - if (conn->GetStatus() == PGCONN_OK) - { - if (rdo.IsReassign()) - { - if (wxMessageBox(_("Are you sure you wish to reassign all objects owned by the selected role?"), _("Reassign objects"), wxYES_NO) == wxNO) - return; + wxString query; + + dlgReassignDropOwned rdo(form, GetConnection(), this, GetServer()->GetDbRestriction()); + if (rdo.ShowModal() != wxID_CANCEL) + { + pgConn *conn; + conn = new pgConn(GetConnection()->GetHost(), + rdo.GetDatabase(), + GetConnection()->GetUser(), + GetConnection()->GetPassword(), + GetConnection()->GetPort(), + GetConnection()->GetSslMode()); + + if (conn->GetStatus() == PGCONN_OK) + { + if (rdo.IsReassign()) + { + if (wxMessageBox(_("Are you sure you wish to reassign all objects owned by the selected role?"), _("Reassign objects"), wxYES_NO) == wxNO) + return; - query = wxT("REASSIGN OWNED BY ") + GetQuotedFullIdentifier() + wxT(" TO ") + rdo.GetRole(); + query = wxT("REASSIGN OWNED BY ") + GetQuotedFullIdentifier() + wxT(" TO ") + rdo.GetRole(); } else { - if (wxMessageBox(_("Are you sure you wish to drop all objects owned by the selected role?"), _("Drop objects"), wxYES_NO) == wxNO) - return; + if (wxMessageBox(_("Are you sure you wish to drop all objects owned by the selected role?"), _("Drop objects"), wxYES_NO) == wxNO) + return; - query = wxT("DROP OWNED BY ") + GetQuotedFullIdentifier(); + query = wxT("DROP OWNED BY ") + GetQuotedFullIdentifier(); } conn->ExecuteVoid(query); - } - else - { - wxMessageBox(wxT("Connection failed: ") + conn->GetLastError()); } - } + else + { + wxMessageBox(wxT("Connection failed: ") + conn->GetLastError()); + } + } } @@ -379,6 +381,16 @@ role->iSetComment(roles->GetVal(wxT("description"))); role->iSetConnectionLimit(roles->GetLong(wxT("rolconnlimit"))); + if (collection->GetServer()->GetConnection()->GetIsGreenplum()) + { + Oid rolresqueue = roles->GetOid(wxT("rolresqueue")); + if (rolresqueue != 0) + { + role->iSetRolQueueName(collection->GetServer()->ExecuteScalar(wxT("SELECT rsqname FROM pg_resqueue WHERE pg_resqueue.oid = ") + roles->GetVal(wxT("rolresqueue")))); + } + } + + wxString cfg=roles->GetVal(wxT("rolconfig")); if (!cfg.IsEmpty()) FillArray(role->GetConfigList(), cfg.Mid(1, cfg.Length()-2)); @@ -386,13 +398,13 @@ if (browser) { browser->AppendObject(collection, role); - roles->MoveNext(); + roles->MoveNext(); } else break; } - delete roles; + delete roles; } return role; } @@ -425,7 +437,7 @@ pgRoleBaseFactory::pgRoleBaseFactory(const wxChar *tn, const wxChar *ns, const wxChar *nls, const char **img) : pgServerObjFactory(tn, ns, nls, img) { - metaType = PGM_ROLE; + metaType = PGM_ROLE; } pgLoginRoleFactory::pgLoginRoleFactory() @@ -455,7 +467,7 @@ wxWindow *reassignDropOwnedFactory::StartDialog(frmMain *form, pgObject *obj) { ((pgRole*)obj)->ReassignDropOwnedTo(form); - + return 0; } Index: pgadmin/schema/pgObject.cpp =================================================================== --- pgadmin/schema/pgObject.cpp (revision 7597) +++ pgadmin/schema/pgObject.cpp (working copy) @@ -26,6 +26,7 @@ #include "schema/pgType.h" #include "schema/pgDatabase.h" #include "schema/pgTable.h" +#include "schema/pgExtTable.h" #include "schema/pgColumn.h" #include "schema/pgView.h" #include "schema/pgType.h" @@ -226,16 +227,17 @@ case 't': set->MoveNext(); continue; case 'r': - { - if (StrToLong(typestr.Mid(1)) > 0) - depFactory = &columnFactory; - else - depFactory=&tableFactory; - break; - } + { + if (StrToLong(typestr.Mid(1)) > 0) + depFactory = &columnFactory; + else + depFactory=&tableFactory; + break; + } case 'i': depFactory=&indexFactory; break; case 'S': depFactory=&sequenceFactory; break; case 'v': depFactory=&viewFactory; break; + case 'x': depFactory=&extTableFactory; break; case 'p': depFactory=&functionFactory; break; case 'n': depFactory=&schemaFactory; break; case 'y': depFactory=&typeFactory; break; @@ -350,7 +352,7 @@ wxT(" COALESCE(nsc.nspname, nso.nspname, nsp.nspname, nst.nspname, nsrw.nspname) AS nspname\n") wxT(" FROM pg_depend dep\n") wxT(" LEFT JOIN pg_class cl ON dep.refobjid=cl.oid\n") - wxT(" LEFT JOIN pg_attribute att ON dep.refobjid=att.attrelid AND dep.refobjsubid=att.attnum\n") + wxT(" LEFT JOIN pg_attribute att ON dep.refobjid=att.attrelid AND dep.refobjsubid=att.attnum\n") wxT(" LEFT JOIN pg_namespace nsc ON cl.relnamespace=nsc.oid\n") wxT(" LEFT JOIN pg_proc pr ON dep.refobjid=pr.oid\n") wxT(" LEFT JOIN pg_namespace nsp ON pr.pronamespace=nsp.oid\n") @@ -417,11 +419,11 @@ wxT(" WHEN co.oid IS NOT NULL THEN 'C'::text || contype\n") wxT(" ELSE '' END AS type,\n") wxT(" COALESCE(coc.relname, clrw.relname) AS ownertable,\n") - wxT(" COALESCE(cl.relname || '.' || att.attname, cl.relname, co.conname, pr.proname, tg.tgname, ty.typname, la.lanname, rw.rulename, ns.nspname) AS refname,\n") + wxT(" COALESCE(cl.relname || '.' || att.attname, cl.relname, co.conname, pr.proname, tg.tgname, ty.typname, la.lanname, rw.rulename, ns.nspname) AS refname,\n") wxT(" COALESCE(nsc.nspname, nso.nspname, nsp.nspname, nst.nspname, nsrw.nspname) AS nspname\n") wxT(" FROM pg_depend dep\n") wxT(" LEFT JOIN pg_class cl ON dep.objid=cl.oid\n") - wxT(" LEFT JOIN pg_attribute att ON dep.objid=att.attrelid AND dep.objsubid=att.attnum\n") + wxT(" LEFT JOIN pg_attribute att ON dep.objid=att.attrelid AND dep.objsubid=att.attnum\n") wxT(" LEFT JOIN pg_namespace nsc ON cl.relnamespace=nsc.oid\n") wxT(" LEFT JOIN pg_proc pr ON dep.objid=pr.oid\n") wxT(" LEFT JOIN pg_namespace nsp ON pr.pronamespace=nsp.oid\n") @@ -540,11 +542,11 @@ wxString rights; if (allPattern.Length() > 1 && acl == allPattern) - { + { rights = wxT("ALL"); if (!column.IsEmpty()) rights += wxT("(") + column + wxT(")"); - } + } else { AppendRight(rights, acl, 'r', wxT("SELECT"), column); @@ -638,19 +640,19 @@ else { if (user.Left(6) == wxT("group ")) - { - if (user.Mid(6).StartsWith(wxT("\\\"")) && user.Mid(6).EndsWith(wxT("\\\""))) + { + if (user.Mid(6).StartsWith(wxT("\\\"")) && user.Mid(6).EndsWith(wxT("\\\""))) user = wxT("GROUP ") + qtIdent(user.Mid(8, user.Length() - 10)); - else - user = wxT("GROUP ") + qtIdent(user.Mid(6)); - } + else + user = wxT("GROUP ") + qtIdent(user.Mid(6)); + } else - { - if (user.StartsWith(wxT("\\\"")) && user.EndsWith(wxT("\\\""))) + { + if (user.StartsWith(wxT("\\\"")) && user.EndsWith(wxT("\\\""))) user = qtIdent(user.Mid(2, user.Length() - 4)); - else - user = qtIdent(user); - } + else + user = qtIdent(user); + } } grant += GetPrivileges(allPattern, str, grantFor, user, qtIdent(_column)); @@ -687,12 +689,12 @@ if (GetMetaType() == PGM_DATABASE) return (server->GetCreatePrivilege() || server->GetSuperUser()); else - { - if (server->GetConnection()->BackendMinimumVersion(8, 1) && GetMetaType() == PGM_ROLE) - return (server->GetCreateRole() || server->GetSuperUser()); - else - return server->GetSuperUser(); - } + { + if (server->GetConnection()->BackendMinimumVersion(8, 1) && GetMetaType() == PGM_ROLE) + return (server->GetCreateRole() || server->GetSuperUser()); + else + return server->GetSuperUser(); + } } @@ -701,12 +703,12 @@ if (GetMetaType() == PGM_DATABASE) return (server->GetCreatePrivilege() || server->GetSuperUser()); else - { - if (server->GetConnection()->BackendMinimumVersion(8, 1) && GetMetaType() == PGM_ROLE) - return (server->GetCreateRole() || server->GetSuperUser()); - else - return server->GetSuperUser(); - } + { + if (server->GetConnection()->BackendMinimumVersion(8, 1) && GetMetaType() == PGM_ROLE) + return (server->GetCreateRole() || server->GetSuperUser()); + else + return server->GetSuperUser(); + } } @@ -756,7 +758,7 @@ if (!conn) { - tmpConn = GetServer()->CreateConn(dbname); + tmpConn = GetServer()->CreateConn(dbname); conn=tmpConn; } @@ -782,6 +784,7 @@ break; case 'S': ownerFactory=&sequenceFactory; break; case 'v': ownerFactory=&viewFactory; break; + case 'x': ownerFactory=&extTableFactory; break; case 'c': // composite type handled in PG_TYPE case 's': // special case 't': // toast @@ -1163,16 +1166,16 @@ wxString pgObject::qtDbString(const wxString &str) { - // Use the server aware version if possible - if (GetDatabase() && GetDatabase()->GetConnection()) - return GetDatabase()->GetConnection()->qtDbString(str); - else - { - wxString ret = str; - ret.Replace(wxT("\\"), wxT("\\\\")); + // Use the server aware version if possible + if (GetDatabase() && GetDatabase()->GetConnection()) + return GetDatabase()->GetConnection()->qtDbString(str); + else + { + wxString ret = str; + ret.Replace(wxT("\\"), wxT("\\\\")); ret.Replace(wxT("'"), wxT("''")); ret.Append(wxT("'")); ret.Prepend(wxT("'")); - return ret; - } + return ret; + } } Index: pgadmin/schema/pgTable.cpp =================================================================== --- pgadmin/schema/pgTable.cpp (revision 7597) +++ pgadmin/schema/pgTable.cpp (working copy) @@ -26,6 +26,7 @@ #include "schema/pgRule.h" #include "schema/pgTrigger.h" #include "schema/pgConstraints.h" +#include "schema/pgPartition.h" // App headers @@ -36,6 +37,7 @@ inheritedTableCount=0; rowsCounted = false; showExtendedStatistics = false; + distributionIsRandom = false; } pgTable::~pgTable() @@ -149,7 +151,7 @@ pgCollection *collection=browser->FindCollection(factory, GetId()); if (collection) { - tmp += wxT("\n"); + tmp += wxT("\n"); collection->ShowTreeDetail(browser); treeObjectIterator idxIt(browser, collection); @@ -166,10 +168,27 @@ sql += tmp; } +void pgTable::AppendStuffNoSql(wxString &sql, ctlTree *browser, pgaFactory &factory) +{ + pgCollection *collection=browser->FindCollection(factory, GetId()); + if (collection) + { + collection->ShowTreeDetail(browser); + treeObjectIterator idxIt(browser, collection); + pgObject *obj; + while ((obj = idxIt.GetNextObject()) != 0) + { + obj->ShowTreeDetail(browser); + } + } +} + + + wxString pgTable::GetSql(ctlTree *browser) { - wxString colDetails, conDetails; + wxString colDetails, conDetails; wxString prevComment; wxString columnPrivileges; @@ -229,21 +248,21 @@ } if (column->GetInheritedCount() > 0) - { - if (!column->GetIsLocal()) - sql += wxString::Format(wxT("-- %s "), _("Inherited")) + { + if (!column->GetIsLocal()) + sql += wxString::Format(wxT("-- %s "), _("Inherited")) + wxT("from table ") + column->GetInheritedTableName() + wxT(":"); - } + } sql += wxT(" ") + column->GetQuotedIdentifier() + wxT(" ") + column->GetDefinition(); prevComment = column->GetComment(); - // Whilst we are looping round the columns, grab their comments as well. - // Perhaps we should also get storage types here? - colDetails += column->GetCommentSql(); - if (colDetails.Length() > 0) + // Whilst we are looping round the columns, grab their comments as well. + // Perhaps we should also get storage types here? + colDetails += column->GetCommentSql(); + if (colDetails.Length() > 0) if (colDetails.Last() != '\n') colDetails += wxT("\n"); @@ -268,7 +287,7 @@ sql += wxT(","); if (!prevComment.IsEmpty()) - sql += wxT(" -- ") + firstLineOnly(prevComment); + sql += wxT(" -- ") + firstLineOnly(prevComment); sql += wxT("\n CONSTRAINT ") + data->GetQuotedIdentifier() + wxT(" ") + data->GetTypeName().Upper() @@ -290,13 +309,13 @@ sql += ((pgForeignKey*)data)->GetDefinition(); break; case PGM_CHECK: - sql += wxT("(") + ((pgCheck*)data)->GetDefinition() + wxT(")"); + sql += wxT("(") + ((pgCheck*)data)->GetDefinition() + wxT(")"); break; } } } if (!prevComment.IsEmpty()) - sql += wxT(" -- ") + firstLineOnly(prevComment); + sql += wxT(" -- ") + firstLineOnly(prevComment); sql += wxT("\n)"); if (GetInheritedTableCount()) @@ -309,6 +328,10 @@ sql += wxT("\nWITH ("); if (GetFillFactor().Length() > 0) sql += wxT("\n FILLFACTOR=") + GetFillFactor() + wxT(", "); + if (GetAppendOnly().Length() > 0) + sql += wxT("APPENDONLY=") + GetAppendOnly() + wxT(", "); + if (GetCompressLevel().Length() > 0) + sql += wxT("COMPRESSLEVEL=") + GetCompressLevel() + wxT(", "); if (GetHasOids()) sql += wxT("\n OIDS=TRUE"); else @@ -372,6 +395,67 @@ if (GetConnection()->BackendMinimumVersion(8, 0) && tablespace != GetDatabase()->GetDefaultTablespace()) sql += wxT("\nTABLESPACE ") + qtIdent(tablespace); + if (GetConnection()->GetIsGreenplum()) + { + // Add Greenplum DISTRIBUTED BY + if (distributionIsRandom) + { + sql += wxT("\nDISTRIBUTED RANDOMLY"); + } + else if (GetDistributionColNumbers().Length()==0) + { + // catalog table or other non-distributed table + } + else + { + // convert list of columns numbers to column names + wxStringTokenizer collist(GetDistributionColNumbers(), wxT(",")); + wxString cn; + wxString distributionColumns; + while (collist.HasMoreTokens()) + { + cn=collist.GetNextToken(); + pgSet *set=ExecuteSet( + wxT("SELECT attname\n") + wxT(" FROM pg_attribute\n") + wxT(" WHERE attrelid=") + GetOidStr() + wxT(" AND attnum IN (") + cn + wxT(")")); + if (set) + { + if (!distributionColumns.IsNull()) + { + distributionColumns += wxT(", "); + } + distributionColumns += qtIdent(set->GetVal(0)); + delete set; + } + } + + sql += wxT("\nDISTRIBUTED BY ("); + sql += distributionColumns; + + sql += wxT(")"); + } + + if (GetIsPartitioned()) + if (GetConnection()->BackendMinimumVersion(8,2,9) && GetConnection()->GetIsGreenplum()) + if (GetPartitionDef().Length() == 0) + { + wxString query = wxT("SELECT pg_get_partition_def("); + query += GetOidStr(); + query += wxT(", true) "); + wxString partition_def = GetDatabase()->ExecuteScalar(query); + iSetPartitionDef(partition_def); + // pg_get_partition_def() doesn't work on partitions + if (GetPartitionDef().Length() == 0) + iSetPartitionDef(wxT("-- This partition has subpartitions")); + } + if (partitionDef.Length() > 0) + sql += wxT("\n") + partitionDef + wxT("\n"); + + + } + + sql += wxT(";\n") + GetOwnerSql(7, 3); @@ -384,7 +468,7 @@ // Column/constraint comments if (!colDetails.IsEmpty()) - sql += colDetails + wxT("\n"); + sql += colDetails + wxT("\n"); if (!conDetails.IsEmpty()) sql += conDetails + wxT("\n"); @@ -397,6 +481,10 @@ AppendStuff(sql, browser, indexFactory); AppendStuff(sql, browser, ruleFactory); AppendStuff(sql, browser, triggerFactory); + if (partitionDef.Length() > 0) + { + AppendStuffNoSql(sql, browser, partitionFactory); + } } return sql; } @@ -436,10 +524,10 @@ wxString pgTable::GetCols(ctlTree *browser, size_t indent, wxString &QMs, bool withQM) { - wxString sql; - wxString line; - - int colcount=0; + wxString sql; + wxString line; + + int colcount=0; pgCollection *columns=browser->FindCollection(columnFactory, GetId()); if (columns) { @@ -453,36 +541,36 @@ if (column->GetColNumber() > 0) { if (colcount++) - { - line += wxT(", "); - QMs += wxT(", "); - } - if (line.Length() > 60) - { - if (!sql.IsEmpty()) - { - sql += wxT("\n") + wxString(' ', indent); - } - sql += line; - line = wxEmptyString; - QMs += wxT("\n") + wxString(' ', indent); - } + { + line += wxT(", "); + QMs += wxT(", "); + } + if (line.Length() > 60) + { + if (!sql.IsEmpty()) + { + sql += wxT("\n") + wxString(' ', indent); + } + sql += line; + line = wxEmptyString; + QMs += wxT("\n") + wxString(' ', indent); + } - line += column->GetQuotedIdentifier(); - if (withQM) - line += wxT("=?"); - QMs += wxT("?"); + line += column->GetQuotedIdentifier(); + if (withQM) + line += wxT("=?"); + QMs += wxT("?"); } } } - if (!line.IsEmpty()) - { - if (!sql.IsEmpty()) - sql += wxT("\n") + wxString(' ', indent); - sql += line; - } - return sql; + if (!line.IsEmpty()) + { + if (!sql.IsEmpty()) + sql += wxT("\n") + wxString(' ', indent); + sql += line; + } + return sql; } pgCollection *pgTable::GetColumnCollection(ctlTree *browser) @@ -499,54 +587,54 @@ wxString pgTable::GetSelectSql(ctlTree *browser) { - wxString qms; - wxString sql= - wxT("SELECT ") + GetCols(browser, 7, qms, false) + wxT("\n") - wxT(" FROM ") + GetQuotedFullIdentifier() + wxT(";\n"); - return sql; + wxString qms; + wxString sql= + wxT("SELECT ") + GetCols(browser, 7, qms, false) + wxT("\n") + wxT(" FROM ") + GetQuotedFullIdentifier() + wxT(";\n"); + return sql; } wxString pgTable::GetInsertSql(ctlTree *browser) { - wxString qms; - wxString sql = - wxT("INSERT INTO ") + GetQuotedFullIdentifier() + wxT("(\n") - wxT(" ") + GetCols(browser, 12, qms, false) + wxT(")\n") - wxT(" VALUES (") + qms + wxT(");\n"); - return sql; + wxString qms; + wxString sql = + wxT("INSERT INTO ") + GetQuotedFullIdentifier() + wxT("(\n") + wxT(" ") + GetCols(browser, 12, qms, false) + wxT(")\n") + wxT(" VALUES (") + qms + wxT(");\n"); + return sql; } wxString pgTable::GetUpdateSql(ctlTree *browser) { - wxString qms; - wxString sql = - wxT("UPDATE ") + GetQuotedFullIdentifier() + wxT("\n") - wxT(" SET ") + GetCols(browser, 7, qms, true) + wxT("\n") - wxT(" WHERE ;\n"); - return sql; + wxString qms; + wxString sql = + wxT("UPDATE ") + GetQuotedFullIdentifier() + wxT("\n") + wxT(" SET ") + GetCols(browser, 7, qms, true) + wxT("\n") + wxT(" WHERE ;\n"); + return sql; } wxString pgTable::GetDeleteSql(ctlTree *browser) { - wxString qms; - wxString sql = - wxT("DELETE FROM ") + GetQuotedFullIdentifier() + wxT("\n") - wxT(" WHERE ;\n"); - return sql; + wxString qms; + wxString sql = + wxT("DELETE FROM ") + GetQuotedFullIdentifier() + wxT("\n") + wxT(" WHERE ;\n"); + return sql; } bool pgTable::EnableTriggers(const bool b) { - wxString sql = wxT("ALTER TABLE ") + GetQuotedFullIdentifier() + wxT(" "); + wxString sql = wxT("ALTER TABLE ") + GetQuotedFullIdentifier() + wxT(" "); - if (!b) + if (!b) sql += wxT("DISABLE"); - else + else sql += wxT("ENABLE"); - sql += wxT(" TRIGGER ALL"); + sql += wxT(" TRIGGER ALL"); return GetDatabase()->ExecuteVoid(sql); } @@ -617,7 +705,10 @@ browser->AppendCollection(this, indexFactory); browser->AppendCollection(this, ruleFactory); browser->AppendCollection(this, triggerFactory); + if (GetIsPartitioned()) + browser->AppendCollection(this, partitionFactory); + // convert list of columns numbers to column names wxStringTokenizer collist(GetPrimaryKeyColNumbers(), wxT(",")); wxString cn; @@ -799,9 +890,9 @@ pgTrigger *trigger; while ((trigger = (pgTrigger *)trgIt.GetNextObject()) != 0) { - trigger->iSetEnabled(enable); - } - } + trigger->iSetEnabled(enable); + } + } } /////////////////////////////////////////////////////////// @@ -853,9 +944,9 @@ sql += wxT("\n FROM pg_stat_all_tables st") wxT(" JOIN pg_class cl on cl.oid=st.relid\n") - wxT(" WHERE schemaname = ") + qtDbString(GetSchema()->GetName()) - + wxT("\n ORDER BY relname"); - + wxT(" WHERE schemaname = ") + qtDbString(GetSchema()->GetName()) + + wxT("\n ORDER BY relname"); + pgSet *stats = GetDatabase()->ExecuteSet(sql); if (stats) @@ -888,7 +979,7 @@ pos++; } - delete stats; + delete stats; } } @@ -927,12 +1018,12 @@ if (GetConnection()->BackendMinimumVersion(8, 2)) { - sql += + sql += wxT(", last_vacuum AS ") + qtIdent(_("Last Vacuum")) + wxT(", last_autovacuum AS ") + qtIdent(_("Last Autovacuum")) + - wxT(", last_analyze AS ") + qtIdent(_("Last Analyze")) + - wxT(", last_autoanalyze AS ") + qtIdent(_("Last Autoanalyze")); - } + wxT(", last_analyze AS ") + qtIdent(_("Last Analyze")) + + wxT(", last_autoanalyze AS ") + qtIdent(_("Last Autoanalyze")); + } if (GetConnection()->HasFeature(FEATURE_SIZE)) { @@ -985,8 +1076,16 @@ wxT(" WHERE tgrelid=rel.oid) AS isrepl\n"); if (collection->GetConnection()->BackendMinimumVersion(8, 2)) query += wxT(", substring(array_to_string(reloptions, ',') from 'fillfactor=([0-9]*)') AS fillfactor \n"); - if (collection->GetConnection()->BackendMinimumVersion(8, 4)) + if (collection->GetConnection()->GetIsGreenplum()) { + query += wxT(", gpd.localoid, gpd.attrnums \n"); + query += wxT(", substring(array_to_string(reloptions, ',') from 'appendonly=([a-z]*)') AS appendonly \n"); + query += wxT(", substring(array_to_string(reloptions, ',') from 'compresslevel=([0-9]*)') AS compresslevel \n"); + if (collection->GetConnection()->GetIsGreenplum() && collection->GetConnection()->BackendMinimumVersion(8, 2, 9)) + query += wxT(", rel.oid in (select parrelid from pg_partition) as ispartitioned\n"); + } + else if (collection->GetConnection()->BackendMinimumVersion(8, 4)) + { query += wxT(", substring(array_to_string(reloptions, ',') FROM 'autovacuum_enabled=([a-z|0-9]*)') AS autovacuum_enabled \n") wxT(", substring(array_to_string(reloptions, ',') FROM 'autovacuum_vacuum_threshold=([0-9]*)') AS autovacuum_vacuum_threshold \n") wxT(", substring(array_to_string(reloptions, ',') FROM 'autovacuum_vacuum_scale_factor=([0-9]*[.][0-9]*)') AS autovacuum_vacuum_scale_factor \n") @@ -1002,9 +1101,18 @@ query += wxT(" FROM pg_class rel\n") wxT(" LEFT OUTER JOIN pg_tablespace ta on ta.oid=rel.reltablespace\n") wxT(" LEFT OUTER JOIN pg_description des ON (des.objoid=rel.oid AND des.objsubid=0)\n") - wxT(" LEFT OUTER JOIN pg_constraint c ON c.conrelid=rel.oid AND c.contype='p'\n") - wxT(" WHERE relkind IN ('r','s','t') AND relnamespace = ") + collection->GetSchema()->GetOidStr() + wxT("\n") - + restriction + + wxT(" LEFT OUTER JOIN pg_constraint c ON c.conrelid=rel.oid AND c.contype='p'\n"); + if (collection->GetConnection()->GetIsGreenplum()) + { + query += wxT(" LEFT OUTER JOIN gp_distribution_policy gpd ON gpd.localoid=rel.oid\n"); + //if (collection->GetConnection()->GetIsGreenplum() && collection->GetConnection()->BackendMinimumVersion(8, 2, 9)) + // query += wxT(" LEFT OUTER JOIN pg_partition ON rel.oid = parrelid\n"); + } + query += wxT(" WHERE relkind IN ('r','s','t') AND relnamespace = ") + collection->GetSchema()->GetOidStr() + wxT("\n"); + // Greenplum: Eliminate (sub)partitions from the display, only show the parent partitioned table + if (collection->GetConnection()->GetIsGreenplum() && collection->GetConnection()->BackendMinimumVersion(8, 2, 9)) + query += wxT("AND rel.oid NOT IN (select parchildrelid from pg_partition_rule)"); + query += restriction + wxT(" ORDER BY relname"); } else @@ -1034,10 +1142,10 @@ table->iSetAcl(tables->GetVal(wxT("relacl"))); if (collection->GetConnection()->BackendMinimumVersion(8, 0)) { - if (tables->GetOid(wxT("spcoid")) == 0) - table->iSetTablespaceOid(collection->GetDatabase()->GetTablespaceOid()); - else - table->iSetTablespaceOid(tables->GetOid(wxT("spcoid"))); + if (tables->GetOid(wxT("spcoid")) == 0) + table->iSetTablespaceOid(collection->GetDatabase()->GetTablespaceOid()); + else + table->iSetTablespaceOid(tables->GetOid(wxT("spcoid"))); if (tables->GetVal(wxT("spcname")) == wxEmptyString) table->iSetTablespace(collection->GetDatabase()->GetTablespace()); @@ -1073,6 +1181,27 @@ cn=cn.Mid(1, cn.Length()-2); table->iSetPrimaryKeyColNumbers(cn); + if (collection->GetConnection()->GetIsGreenplum()) + { + Oid lo=tables->GetOid(wxT("localoid")); + wxString db=tables->GetVal(wxT("attrnums")); + db=db.Mid(1, db.Length()-2); + table->iSetDistributionColNumbers(db); + if (lo > 0 && db.Length() == 0) + table->iSetDistributionIsRandom(); + table->iSetAppendOnly(tables->GetVal(wxT("appendonly"))); + table->iSetCompressLevel(tables->GetVal(wxT("compresslevel"))); + + table->iSetPartitionDef(wxT("")); + table->iSetIsPartitioned(false); + + if (collection->GetConnection()->BackendMinimumVersion(8,2,9)) + { + table->iSetIsPartitioned(tables->GetBool(wxT("ispartitioned"))); + } + + } + if (browser) { browser->AppendObject(collection, table); @@ -1082,7 +1211,7 @@ break; } - delete tables; + delete tables; } return table; } @@ -1163,17 +1292,17 @@ wxWindow *executePgstattupleFactory::StartDialog(frmMain *form, pgObject *obj) { - if (!((pgTable*)obj)->GetShowExtendedStatistics()) - { - ((pgTable*)obj)->iSetShowExtendedStatistics(true); - wxTreeItemId item=form->GetBrowser()->GetSelection(); - if (obj == form->GetBrowser()->GetObject(item)) - form->SelectStatisticsTab(); - } - else - ((pgTable*)obj)->iSetShowExtendedStatistics(false); + if (!((pgTable*)obj)->GetShowExtendedStatistics()) + { + ((pgTable*)obj)->iSetShowExtendedStatistics(true); + wxTreeItemId item=form->GetBrowser()->GetSelection(); + if (obj == form->GetBrowser()->GetObject(item)) + form->SelectStatisticsTab(); + } + else + ((pgTable*)obj)->iSetShowExtendedStatistics(false); - form->GetMenuFactories()->CheckMenu(obj, form->GetMenuBar(), (ctlMenuToolbar *)form->GetToolBar()); + form->GetMenuFactories()->CheckMenu(obj, form->GetMenuBar(), (ctlMenuToolbar *)form->GetToolBar()); return 0; } @@ -1197,14 +1326,14 @@ wxWindow *disableAllTriggersFactory::StartDialog(frmMain *form, pgObject *obj) { - if (wxMessageBox(_("Are you sure you wish to disable all triggers on this table?"), _("Disable triggers"), wxYES_NO) == wxNO) - return 0; - - if (!((pgTable*)obj)->EnableTriggers(false)) - return 0; + if (wxMessageBox(_("Are you sure you wish to disable all triggers on this table?"), _("Disable triggers"), wxYES_NO) == wxNO) + return 0; + + if (!((pgTable*)obj)->EnableTriggers(false)) + return 0; - ((pgTable *)obj)->iSetTriggersEnabled(form->GetBrowser(), false); - + ((pgTable *)obj)->iSetTriggersEnabled(form->GetBrowser(), false); + return 0; } @@ -1224,13 +1353,13 @@ wxWindow *enableAllTriggersFactory::StartDialog(frmMain *form, pgObject *obj) { - if (wxMessageBox(_("Are you sure you wish to enable all triggers on this table?"), _("Enable triggers"), wxYES_NO) == wxNO) - return 0; - - if (!((pgTable*)obj)->EnableTriggers(true)) - return 0; + if (wxMessageBox(_("Are you sure you wish to enable all triggers on this table?"), _("Enable triggers"), wxYES_NO) == wxNO) + return 0; + + if (!((pgTable*)obj)->EnableTriggers(true)) + return 0; - ((pgTable *)obj)->iSetTriggersEnabled(form->GetBrowser(), true); + ((pgTable *)obj)->iSetTriggersEnabled(form->GetBrowser(), true); return 0; } Index: pgadmin/schema/pgColumn.cpp =================================================================== --- pgadmin/schema/pgColumn.cpp (revision 7597) +++ pgadmin/schema/pgColumn.cpp (working copy) @@ -134,13 +134,13 @@ wxString pgColumn::GetCommentSql() { - wxString commentSql; + wxString commentSql; - if (!GetComment().IsEmpty()) - commentSql = wxT("COMMENT ON COLUMN ") + GetQuotedFullTable() + wxT(".") + GetQuotedIdentifier() + if (!GetComment().IsEmpty()) + commentSql = wxT("COMMENT ON COLUMN ") + GetQuotedFullTable() + wxT(".") + GetQuotedIdentifier() + wxT(" IS ") + qtDbString(GetComment()) + wxT(";\n"); - - return commentSql; + + return commentSql; } wxString pgColumn::GetPrivileges() @@ -200,9 +200,9 @@ if (GetDatabase()->BackendMinimumVersion(8, 1)) { seqDefault1 = wxT("nextval('") + schema->GetPrefix() + GetTableName() - + wxT("_") + GetName() + wxT("_seq'::regclass)"); + + wxT("_") + GetName() + wxT("_seq'::regclass)"); seqDefault2 = wxT("nextval('\"") + schema->GetPrefix() + GetTableName() - + wxT("_") + GetName() + wxT("_seq\"'::regclass)"); + + wxT("_") + GetName() + wxT("_seq\"'::regclass)"); } else { @@ -296,7 +296,7 @@ if (GetTable()->GetMetaType() != PGM_CATALOGOBJECT) { properties->AppendItem(_("Default"), GetDefault()); - if (GetTable()->GetMetaType() != PGM_VIEW) + if (GetTable()->GetMetaType() != PGM_VIEW && GetTable()->GetMetaType() != PGM_EXTTABLE) { properties->AppendItem(_("Sequence"), database->GetSchemaPrefix(GetSerialSchema()) + GetSerialSequence()); @@ -447,7 +447,7 @@ column->iSetTableName(columns->GetVal(wxT("relname"))); column->iSetInheritedCount(columns->GetLong(wxT("attinhcount"))); column->iSetInheritedTableName(columns->GetVal(wxT("inhrelname"))); - column->iSetIsLocal(columns->GetBool(wxT("attislocal"))); + column->iSetIsLocal(columns->GetBool(wxT("attislocal"))); column->iSetAttstattarget(columns->GetLong(wxT("attstattarget"))); if (database->BackendMinimumVersion(8, 4)) column->iSetAcl(columns->GetVal(wxT("attacl"))); @@ -455,13 +455,13 @@ if (browser) { browser->AppendObject(collection, column); - columns->MoveNext(); + columns->MoveNext(); } else break; } - delete columns; + delete columns; } return column; } Index: pgadmin/schema/pgServer.cpp =================================================================== --- pgadmin/schema/pgServer.cpp (revision 7597) +++ pgadmin/schema/pgServer.cpp (working copy) @@ -30,6 +30,7 @@ #include "schema/pgGroup.h" #include "schema/pgUser.h" #include "schema/pgRole.h" +#include "schema/pgResQueue.h" #include "agent/pgaJob.h" #include "utils/utffile.h" #include "utils/pgfeatures.h" @@ -101,6 +102,9 @@ groupRoleFactory.AppendMenu(menu); if (settings->GetDisplayOption(_("Users/login roles"))) loginRoleFactory.AppendMenu(menu); + if (GetConnection()->GetIsGreenplum()) + if (settings->GetDisplayOption(_("ResQueues/resource queues"))) + resQueueFactory.AppendMenu(menu); } else { @@ -850,7 +854,10 @@ if (settings->GetDisplayOption(_("Groups/group roles"))) browser->AppendCollection(this, groupRoleFactory); if (settings->GetDisplayOption(_("Users/login roles"))) - browser->AppendCollection(this, loginRoleFactory); + browser->AppendCollection(this, loginRoleFactory); + if (GetConnection()->GetIsGreenplum()) + if (settings->GetDisplayOption(_("ResQueues/resource queues"))) + browser->AppendCollection(this, resQueueFactory); } else { Index: pgadmin/utils/sysSettings.cpp =================================================================== --- pgadmin/utils/sysSettings.cpp (revision 7597) +++ pgadmin/utils/sysSettings.cpp (working copy) @@ -31,13 +31,13 @@ sysSettings::sysSettings(const wxString& name) : wxConfig(name) { - // Open the default settings file - defaultSettings = NULL; - if (!settingsIni.IsEmpty()) - { - wxFileStream fst(settingsIni); + // Open the default settings file + defaultSettings = NULL; + if (!settingsIni.IsEmpty()) + { + wxFileStream fst(settingsIni); defaultSettings = new wxFileConfig(fst); - } + } // Convert settings from pre-1.5 long i, serverCount; @@ -74,6 +74,8 @@ engtype = wxT("Groups-login roles"); else if (objtype == _("Users/login roles")) engtype = wxT("Users-login roles"); + else if (objtype == _("ResQueues/resource queues")) + engtype = wxT("ResQueues-resource queues"); else if (objtype == _("Catalogs")) engtype = wxT("Catalogs"); else if (objtype == _("Casts")) @@ -135,6 +137,8 @@ else if (objtype == _("Sequences")) engtype = wxT("Sequences"); else if (objtype == _("Tables")) + engtype = wxT("Partitions"); + else if (objtype == _("Partitions")) engtype = wxT("Tables"); else if (objtype == _("FTS Configurations")) engtype = wxT("FTS Configurations"); @@ -151,6 +155,8 @@ } else if (objtype == _("Views")) engtype = wxT("Views"); + else if (objtype == _("External Tables")) + engtype = wxT("External Tables"); // If we just want the default, return it. if (GetDefault) @@ -170,6 +176,7 @@ else if (objtype == _("pgAgent jobs")) engtype = wxT("pgAgent jobs"); else if (objtype == _("Groups/group roles")) engtype = wxT("Groups-login roles"); else if (objtype == _("Users/login roles")) engtype = wxT("Users-login roles"); + else if (objtype == _("ResQueues/resource queues")) engtype = wxT("ResQueues-resource queues"); else if (objtype == _("Catalogs")) engtype = wxT("Catalogs"); else if (objtype == _("Casts")) engtype = wxT("Casts"); else if (objtype == _("Languages")) engtype = wxT("Languages"); @@ -189,12 +196,14 @@ else if (objtype == _("Rules")) engtype = wxT("Rules"); else if (objtype == _("Sequences")) engtype = wxT("Sequences"); else if (objtype == _("Tables")) engtype = wxT("Tables"); + else if (objtype == _("Partitions")) engtype = wxT("Partitions"); else if (objtype == _("FTS Configurations")) engtype = wxT("FTS Configurations"); else if (objtype == _("FTS Dictionaries")) engtype = wxT("FTS Dictionaries"); else if (objtype == _("FTS Parsers")) engtype = wxT("FTS Parsers"); else if (objtype == _("FTS Templates")) engtype = wxT("FTS Templates"); else if (objtype == _("Types")) engtype = wxT("Types"); else if (objtype == _("Views")) engtype = wxT("Views"); + else if (objtype == _("External Tables")) engtype = wxT("External Tables"); Write(wxT("Display/") + engtype, display); } @@ -256,77 +265,77 @@ // Read a string value bool sysSettings::Read(const wxString& key, wxString* str, const wxString& defaultVal) const { - wxString actualDefault = defaultVal; + wxString actualDefault = defaultVal; - // Get the default from the defaults file, in preference - // to the hardcoded value - if (defaultSettings) + // Get the default from the defaults file, in preference + // to the hardcoded value + if (defaultSettings) defaultSettings->Read(key, &actualDefault, defaultVal); - return wxConfig::Read(key, str, actualDefault); + return wxConfig::Read(key, str, actualDefault); } // Return a string value wxString sysSettings::Read(const wxString& key, const wxString &defaultVal) const { - wxString actualDefault = defaultVal; + wxString actualDefault = defaultVal; - // Get the default from the defaults file, in preference - // to the hardcoded value + // Get the default from the defaults file, in preference + // to the hardcoded value if (defaultSettings) defaultSettings->Read(key, &actualDefault, defaultVal); - return wxConfig::Read(key, actualDefault); + return wxConfig::Read(key, actualDefault); } // Read an int value bool sysSettings::Read(const wxString& key, int* i, int defaultVal) const { - int actualDefault = defaultVal; - - // Get the default from the defaults file, in preference - // to the hardcoded value - if (defaultSettings) + int actualDefault = defaultVal; + + // Get the default from the defaults file, in preference + // to the hardcoded value + if (defaultSettings) defaultSettings->Read(key, &actualDefault, defaultVal); - return wxConfig::Read(key, i, actualDefault); + return wxConfig::Read(key, i, actualDefault); } // Read a long value bool sysSettings::Read(const wxString& key, long* l, long defaultVal) const { - long actualDefault = defaultVal; - - // Get the default from the defaults file, in preference - // to the hardcoded value - if (defaultSettings) + long actualDefault = defaultVal; + + // Get the default from the defaults file, in preference + // to the hardcoded value + if (defaultSettings) defaultSettings->Read(key, &actualDefault, defaultVal); - return wxConfig::Read(key, l, actualDefault); + return wxConfig::Read(key, l, actualDefault); } // Return a long value long sysSettings::Read(const wxString& key, long defaultVal) const { - long actualDefault = defaultVal; - - // Get the default from the defaults file, in preference - // to the hardcoded value - if (defaultSettings) + long actualDefault = defaultVal; + + // Get the default from the defaults file, in preference + // to the hardcoded value + if (defaultSettings) defaultSettings->Read(key, &actualDefault, defaultVal); - return wxConfig::Read(key, actualDefault); + return wxConfig::Read(key, actualDefault); } // Read a boolean value bool sysSettings::Read(const wxString& key, bool *val, bool defaultVal) const { - wxString actualDefault = BoolToStr(defaultVal); + wxString actualDefault = BoolToStr(defaultVal); wxString str; - // Get the default from the defaults file, in preference - // to the hardcoded value + // Get the default from the defaults file, in preference + // to the hardcoded value if (defaultSettings) defaultSettings->Read(key, &actualDefault, BoolToStr(defaultVal)); @@ -338,15 +347,15 @@ // Read a point value wxPoint sysSettings::Read(const wxString& key, const wxPoint &defaultVal) const { - wxPoint actualDefault = defaultVal; + wxPoint actualDefault = defaultVal; - // Get the default from the defaults file, in preference - // to the hardcoded value - if (defaultSettings) - { - actualDefault.x = defaultSettings->Read(key + wxT("/Left"), defaultVal.x); + // Get the default from the defaults file, in preference + // to the hardcoded value + if (defaultSettings) + { + actualDefault.x = defaultSettings->Read(key + wxT("/Left"), defaultVal.x); actualDefault.y = defaultSettings->Read(key + wxT("/Top"), defaultVal.y); - } + } return wxPoint(wxConfig::Read(key + wxT("/Left"), actualDefault.x), wxConfig::Read(key + wxT("/Top"), actualDefault.y)); @@ -355,15 +364,15 @@ // Read a size value wxSize sysSettings::Read(const wxString& key, const wxSize &defaultVal) const { - wxSize actualDefault = defaultVal; + wxSize actualDefault = defaultVal; - // Get the default from the defaults file, in preference - // to the hardcoded value - if (defaultSettings) - { + // Get the default from the defaults file, in preference + // to the hardcoded value + if (defaultSettings) + { actualDefault.x = defaultSettings->Read(key + wxT("/Width"), defaultVal.x); actualDefault.y = defaultSettings->Read(key + wxT("/Height"), defaultVal.y); - } + } return wxSize(wxConfig::Read(key + wxT("/Width"), actualDefault.x), wxConfig::Read(key + wxT("/Height"), actualDefault.y)); @@ -399,9 +408,9 @@ wxString sysSettings::GetLogFile() { - wxString logFile; + wxString logFile; - // Try to get a vaguely usable default path. + // Try to get a vaguely usable default path. char *homedir; #ifdef __WXMSW__ char *homedrive; @@ -433,7 +442,7 @@ Read(wxT("LogFile"), &logFile, deflog); - return logFile; + return logFile; } ////////////////////////////////////////////////////////////////////////// @@ -442,43 +451,55 @@ wxString sysSettings::GetSlonyHelpPath() { - wxString path; + wxString path; Read(wxT("SlonyHelpPath"), &path, wxT("")); - path = CleanHelpPath(path); + path = CleanHelpPath(path); if (!HelpPathValid(path)) path = wxEmptyString; - return path; + return path; } wxString sysSettings::GetPgHelpPath() { - wxString path; + wxString path; Read(wxT("PostgreSQLHelpPath"), &path, wxT("")); - path = CleanHelpPath(path); + path = CleanHelpPath(path); if (!HelpPathValid(path)) path = wxEmptyString; - return path; + return path; } wxString sysSettings::GetEdbHelpPath() { - wxString path; + wxString path; Read(wxT("EnterpriseDBHelpPath"), &path, wxT("")); - path = CleanHelpPath(path); + path = CleanHelpPath(path); if (!HelpPathValid(path)) path = wxEmptyString; - return path; + return path; } +wxString sysSettings::GetGpHelpPath() +{ + wxString path; + + Read(wxT("GreenplumDBHelpPath"), &path, wxT("")); + path = CleanHelpPath(path); + + if (!HelpPathValid(path)) + path = wxEmptyString; + + return path; +} ////////////////////////////////////////////////////////////////////////// // Copy quoting ////////////////////////////////////////////////////////////////////////// @@ -520,7 +541,7 @@ int sysSettings::GetExportQuoting() { - wxString val; + wxString val; Read(wxT("Export/Quote"), &val, wxT("Strings")); if (val == wxT("All")) @@ -640,15 +661,15 @@ langInfo = wxLocale::GetLanguageInfo(Read(wxT("LanguageId"), wxLANGUAGE_UNKNOWN)); - if (langInfo) + if (langInfo) return langInfo->CanonicalName; - return wxEmptyString; + return wxEmptyString; } void sysSettings::SetCanonicalLanguage(const wxLanguage &lang) { - if (wxLocale::GetLanguageName(lang) != GetCanonicalLanguageName()) + if (wxLocale::GetLanguageName(lang) != GetCanonicalLanguageName()) { delete locale; locale = new wxLocale(); Index: pgadmin/utils/tab-complete.inc =================================================================== --- pgadmin/utils/tab-complete.inc (revision 7597) +++ pgadmin/utils/tab-complete.inc (working copy) @@ -357,6 +357,7 @@ {"UNIQUE", NULL, NULL}, /* for CREATE UNIQUE INDEX ... */ {"USER", Query_for_list_of_roles}, {"VIEW", NULL, &Query_for_list_of_views}, + {"EXTTABLE", NULL, &Query_for_list_of_views}, {NULL, NULL, NULL} /* end of list */ }; @@ -783,7 +784,7 @@ static const char *const list_COMMENT[] = {"CAST", "CONVERSION", "DATABASE", "INDEX", "LANGUAGE", "RULE", "SCHEMA", "SEQUENCE", "TABLE", "TYPE", "VIEW", "COLUMN", "AGGREGATE", "FUNCTION", - "OPERATOR", "TRIGGER", "CONSTRAINT", "DOMAIN", "LARGE OBJECT", NULL}; + "OPERATOR", "TRIGGER", "CONSTRAINT", "DOMAIN", "LARGE OBJECT", "EXTTABLE", NULL}; COMPLETE_WITH_LIST(list_COMMENT); } Index: pgadmin/utils/misc.cpp =================================================================== --- pgadmin/utils/misc.cpp (revision 7597) +++ pgadmin/utils/misc.cpp (working copy) @@ -261,7 +261,7 @@ result.Replace(wxT("'"), wxT("\\'")); result.Append(wxT("'")); result.Prepend(wxT("'")); - + return result; } @@ -281,14 +281,14 @@ wxString qt=qtDefault; int counter=1; if (value.Find('\'') < 0 && value.Find('\n') < 0) - { - wxString ret = value; - ret.Replace(wxT("\\"), wxT("\\\\")); + { + wxString ret = value; + ret.Replace(wxT("\\"), wxT("\\\\")); ret.Replace(wxT("'"), wxT("''")); ret.Append(wxT("'")); ret.Prepend(wxT("'")); - return ret; - } + return ret; + } while (value.Find(wxT("$") + qt + wxT("$")) >= 0) qt.Printf(wxT("%s%d"), qtDefault.c_str(), counter++); @@ -323,25 +323,25 @@ return true; else { - // certain types should not be quoted even though it contains a space. Evilness. - wxString valNoArray; - if (forTypes && value.Right(2) == wxT("[]")) - valNoArray = value.Mid(0, value.Len()-2); - else - valNoArray = value; + // certain types should not be quoted even though it contains a space. Evilness. + wxString valNoArray; + if (forTypes && value.Right(2) == wxT("[]")) + valNoArray = value.Mid(0, value.Len()-2); + else + valNoArray = value; - if (forTypes && + if (forTypes && !valNoArray.CmpNoCase(wxT("character varying")) || !valNoArray.CmpNoCase(wxT("\"char\"")) || - !valNoArray.CmpNoCase(wxT("bit varying")) || - !valNoArray.CmpNoCase(wxT("double precision")) || - !valNoArray.CmpNoCase(wxT("timestamp without time zone")) || - !valNoArray.CmpNoCase(wxT("timestamp with time zone")) || - !valNoArray.CmpNoCase(wxT("time without time zone")) || - !valNoArray.CmpNoCase(wxT("time with time zone")) || + !valNoArray.CmpNoCase(wxT("bit varying")) || + !valNoArray.CmpNoCase(wxT("double precision")) || + !valNoArray.CmpNoCase(wxT("timestamp without time zone")) || + !valNoArray.CmpNoCase(wxT("timestamp with time zone")) || + !valNoArray.CmpNoCase(wxT("time without time zone")) || + !valNoArray.CmpNoCase(wxT("time with time zone")) || !valNoArray.CmpNoCase(wxT("\"trigger\"")) || !valNoArray.CmpNoCase(wxT("\"unknown\""))) - return false; + return false; int pos = 0; while (pos < (int)valNoArray.length()) @@ -381,7 +381,7 @@ case REAL: case SET: case SMALLINT: - case TEXT_P: + case TEXT_P: case TIME: case TIMESTAMP: case TRIGGER: @@ -662,9 +662,11 @@ { static wxHelpControllerBase *pgHelpCtl=0; static wxHelpControllerBase *edbHelpCtl=0; + static wxHelpControllerBase *greenplumHelpCtl=0; static wxHelpControllerBase *slonyHelpCtl=0; static wxString pgInitPath = wxEmptyString; static wxString edbInitPath = wxEmptyString; + static wxString gpInitPath = wxEmptyString; static wxString slonyInitPath = wxEmptyString; switch (helpType) @@ -683,6 +685,11 @@ edbInitPath = settings->GetEdbHelpPath(); break; + case HELP_GREENPLUM: + DisplayExternalHelp(helpTopic, settings->GetGpHelpPath(), greenplumHelpCtl, (gpInitPath != settings->GetGpHelpPath() ? true : false)); + gpInitPath = settings->GetGpHelpPath(); + break; + case HELP_SLONY: DisplayExternalHelp(helpTopic, settings->GetSlonyHelpPath(), slonyHelpCtl, (slonyInitPath != settings->GetSlonyHelpPath() ? true : false)); slonyInitPath = settings->GetSlonyHelpPath(); @@ -730,7 +737,7 @@ #endif { helpCtl=new wxHtmlHelpController(); - ((wxHtmlHelpController*)helpCtl)->SetTempDir(helpdir); + ((wxHtmlHelpController*)helpCtl)->SetTempDir(helpdir); helpCtl->Initialize(helpdir + wxT("/pgadmin3")); } } @@ -1006,19 +1013,19 @@ wxString ExecProcess(const wxString &cmd) { wxString res; - FILE *f=popen(cmd.ToAscii(), "r"); + FILE *f=popen(cmd.ToAscii(), "r"); - if (f) - { - char buffer[1024]; - int cnt; - while ((cnt = fread(buffer, 1, 1024, f)) > 0) - { - res += wxString::FromAscii(buffer); - } - pclose(f); - } - return res; + if (f) + { + char buffer[1024]; + int cnt; + while ((cnt = fread(buffer, 1, 1024, f)) > 0) + { + res += wxString::FromAscii(buffer); + } + pclose(f); + } + return res; } int ExecProcess(const wxString &command, wxArrayString &result) @@ -1029,13 +1036,13 @@ fp_command = popen(command.mb_str(wxConvUTF8), "r"); if (!fp_command) - return -1; + return -1; while(!feof(fp_command)) { if (fgets(buf, 4096, fp_command) != NULL) - result.Add(wxString::FromAscii(buf)); - } + result.Add(wxString::FromAscii(buf)); + } return pclose(fp_command); } @@ -1080,13 +1087,13 @@ bool pgAppMinimumVersion(const wxString &cmd, const int majorVer, const int minorVer) { - wxArrayString output; + wxArrayString output; bool isEnterpriseDB = false; #ifdef __WXMSW__ - if (wxExecute(cmd + wxT(" --version"), output, 0) != 0) + if (wxExecute(cmd + wxT(" --version"), output, 0) != 0) #else - if (ExecProcess(cmd + wxT(" --version"), output) != 0) + if (ExecProcess(cmd + wxT(" --version"), output) != 0) #endif { wxLogError(_("Failed to execute: %s --version"), cmd.c_str()); @@ -1097,9 +1104,9 @@ if (output[0].Contains(wxT("EnterpriseDB"))) isEnterpriseDB = true; - wxString version = output[0].AfterLast(' '); - long actualMajor = 0, actualMinor = 0; - + wxString version = output[0].AfterLast(' '); + long actualMajor = 0, actualMinor = 0; + wxString tmp=wxT(""); int x=0; while(version[x] == '0' || version[x] == '1' || version[x] == '2' || version[x] == '3' || version[x] == '4' || @@ -1126,13 +1133,13 @@ if (isEnterpriseDB && actualMajor == 8 && actualMinor == 3) actualMinor = 2; - if (actualMajor > majorVer) - return true; + if (actualMajor > majorVer) + return true; - if (actualMajor == majorVer && actualMinor >= minorVer) - return true; + if (actualMajor == majorVer && actualMinor >= minorVer) + return true; - return false; + return false; } bool isPgApp(const wxString &app) @@ -1140,12 +1147,12 @@ if (!wxFile::Exists(app)) return false; - wxArrayString output; + wxArrayString output; #ifdef __WXMSW__ - if (wxExecute(app + wxT(" --version"), output, 0) != 0) + if (wxExecute(app + wxT(" --version"), output, 0) != 0) #else - if (ExecProcess(app + wxT(" --version"), output) != 0) + if (ExecProcess(app + wxT(" --version"), output) != 0) #endif { wxLogError(_("Failed to execute: %s --version"), app.c_str()); @@ -1155,7 +1162,7 @@ if (output[0].Contains(wxT("PostgreSQL"))) return true; - return false; + return false; } bool isEdbApp(const wxString &app) @@ -1163,12 +1170,12 @@ if (!wxFile::Exists(app)) return false; - wxArrayString output; + wxArrayString output; #ifdef __WXMSW__ - if (wxExecute(app + wxT(" --version"), output, 0) != 0) + if (wxExecute(app + wxT(" --version"), output, 0) != 0) #else - if (ExecProcess(app + wxT(" --version"), output) != 0) + if (ExecProcess(app + wxT(" --version"), output) != 0) #endif { wxLogError(_("Failed to execute: %s --version"), app.c_str()); @@ -1178,9 +1185,32 @@ if (output[0].Contains(wxT("EnterpriseDB"))) return true; - return false; + return false; } +bool isGpApp(const wxString &app) +{ + if (!wxFile::Exists(app)) + return false; + + wxArrayString output; + +#ifdef __WXMSW__ + if (wxExecute(app + wxT(" --version"), output, 0) != 0) +#else + if (ExecProcess(app + wxT(" --version"), output) != 0) +#endif + { + wxLogError(_("Failed to execute: %s --version"), app.c_str()); + return false; + } + + if (output[0].Contains(wxT("8.2"))) // Ugly... No way to tell Greenplum app from PostgreSQL 8.2 app + return true; + + return false; +} + wxString sanitizePath(const wxString &path) { if (path.Length()) @@ -1190,7 +1220,7 @@ return fn.GetLongPath(); } - return wxEmptyString; + return wxEmptyString; } // Fixup a (quoted) string for use on the command line Index: pgadmin/dlg/module.mk =================================================================== --- pgadmin/dlg/module.mk (revision 7597) +++ pgadmin/dlg/module.mk (working copy) @@ -54,6 +54,7 @@ $(srcdir)/dlg/dlgUser.cpp \ $(srcdir)/dlg/dlgView.cpp \ $(srcdir)/dlg/dlgManageMacros.cpp \ + $(srcdir)/dlg/dlgExtTable.cpp \ $(srcdir)/dlg/dlgSelectDatabase.cpp EXTRA_DIST += \ Index: pgadmin/dlg/dlgProperty.cpp =================================================================== --- pgadmin/dlg/dlgProperty.cpp (revision 7597) +++ pgadmin/dlg/dlgProperty.cpp (working copy) @@ -122,11 +122,11 @@ txtComment = CTRL_TEXT("txtComment"); cbOwner = CTRL_COMBOBOX2("cbOwner"); cbClusterSet = CTRL_COMBOBOX2("cbClusterSet"); - - wxString db = wxT("Database"); - wxString ts = wxT("Tablespace"); - enableSQL2 = db.Cmp(factory->GetTypeName()) == 0 - || ts.Cmp(factory->GetTypeName()) == 0; + + wxString db = wxT("Database"); + wxString ts = wxT("Tablespace"); + enableSQL2 = db.Cmp(factory->GetTypeName()) == 0 + || ts.Cmp(factory->GetTypeName()) == 0; wxNotebookPage *page=nbNotebook->GetPage(0); wxASSERT(page != NULL); @@ -142,7 +142,7 @@ dlgProperty::~dlgProperty() { wxString prop=wxT("Properties/") + wxString(factory->GetTypeName()); - settings->Write(prop, GetPosition()); + settings->Write(prop, GetPosition()); if (GetWindowStyle() & wxRESIZE_BORDER) settings->Write(prop, GetSize()); @@ -166,7 +166,7 @@ page += wxString(factory->GetTypeName()).Lower(); } } - + return page; } @@ -210,7 +210,7 @@ void dlgSecurityProperty::SetPrivilegesLayout() { - securityPage->lbPrivileges->GetParent()->Layout(); + securityPage->lbPrivileges->GetParent()->Layout(); } @@ -335,7 +335,7 @@ { if (wxString(factory->GetTypeName()).Cmp(wxT("Server"))) { - // create a panel + // create a panel sqlPane = new wxPanel(nbNotebook); // add panel to the notebook @@ -352,7 +352,7 @@ // text entry box sqlTextField1 = new ctlSQLBox(sqlPane, CTL_PROPSQL, wxDefaultPosition, wxDefaultSize, - wxTE_MULTILINE | wxSUNKEN_BORDER | wxTE_RICH2); + wxTE_MULTILINE | wxSUNKEN_BORDER | wxTE_RICH2); fgsizer->Add(sqlTextField1, 1, wxALL | wxEXPAND, 5); // text entry box @@ -360,7 +360,7 @@ { sqlTextField2 = new ctlSQLBox(sqlPane, CTL_PROPSQL, wxDefaultPosition, wxDefaultSize, - wxTE_MULTILINE | wxSUNKEN_BORDER | wxTE_RICH2); + wxTE_MULTILINE | wxSUNKEN_BORDER | wxTE_RICH2); fgsizer->Add(sqlTextField2, 1, wxALL | wxEXPAND, 5); } @@ -471,7 +471,7 @@ void dlgProperty::AppendQuotedType(wxString &sql, const wxString &name) { - // see AppendQuoted() + // see AppendQuoted() if (name.First('.') >= 0) { sql += qtIdent(name.BeforeFirst('.')) + wxT(".") + qtTypeIdent(name.AfterFirst('.')); @@ -520,11 +520,11 @@ if (connection->BackendMinimumVersion(8, 0)) { - // Populate the combo - cb->FillOidKey(connection, wxT("SELECT oid, spcname FROM pg_tablespace WHERE spcname <> 'pg_global' ORDER BY spcname")); + // Populate the combo + cb->FillOidKey(connection, wxT("SELECT oid, spcname FROM pg_tablespace WHERE spcname <> 'pg_global' ORDER BY spcname")); if (current) - cb->SetKey(current); + cb->SetKey(current); else { if (database) @@ -571,25 +571,25 @@ showmessage = chkReadOnly->GetValue() && ! (!enableSQL2 && GetSql().Length() == 0 && sqlTextField1->GetText().Cmp(_("-- nothing to change")) == 0) - && ! (!enableSQL2 && GetSql().Length() == 0 && sqlTextField1->GetText().Cmp(_("-- definition incomplete")) == 0) + && ! (!enableSQL2 && GetSql().Length() == 0 && sqlTextField1->GetText().Cmp(_("-- definition incomplete")) == 0) && ! (enableSQL2 && GetSql().Length() == 0 && GetSql2().Length() == 0 && sqlTextField1->GetText().Cmp(_("-- nothing to change")) == 0 && sqlTextField2->GetText().Length() == 0) - && ! (enableSQL2 && GetSql().Length() == 0 && GetSql2().Length() == 0 && sqlTextField1->GetText().Cmp(_("-- definition incomplete")) == 0 && sqlTextField2->GetText().Length() == 0) - && (sqlTextField1->GetText().Cmp(GetSql()) != 0 || (enableSQL2 && sqlTextField2->GetText().Cmp(GetSql2()) != 0)); + && ! (enableSQL2 && GetSql().Length() == 0 && GetSql2().Length() == 0 && sqlTextField1->GetText().Cmp(_("-- definition incomplete")) == 0 && sqlTextField2->GetText().Length() == 0) + && (sqlTextField1->GetText().Cmp(GetSql()) != 0 || (enableSQL2 && sqlTextField2->GetText().Cmp(GetSql2()) != 0)); - if (showmessage) - { - if (wxMessageBox(_("Are you sure you wish to cancel your edit?"), _("SQL editor"), wxYES_NO|wxNO_DEFAULT) == wxNO) - { - chkReadOnly->SetValue(false); - return; - } - } + if (showmessage) + { + if (wxMessageBox(_("Are you sure you wish to cancel your edit?"), _("SQL editor"), wxYES_NO|wxNO_DEFAULT) == wxNO) + { + chkReadOnly->SetValue(false); + return; + } + } - sqlTextField1->SetReadOnly(chkReadOnly->GetValue()); - if (enableSQL2) - { - sqlTextField2->SetReadOnly(chkReadOnly->GetValue()); - } + sqlTextField1->SetReadOnly(chkReadOnly->GetValue()); + if (enableSQL2) + { + sqlTextField2->SetReadOnly(chkReadOnly->GetValue()); + } for (pos = 0; pos < nbNotebook->GetPageCount() - 1; pos++) { nbNotebook->GetPage(pos)->Enable(chkReadOnly->GetValue()); @@ -597,7 +597,7 @@ if (chkReadOnly->GetValue()) { - FillSQLTextfield(); + FillSQLTextfield(); } } @@ -606,10 +606,10 @@ { // create a function because this is a duplicated code sqlTextField1->SetReadOnly(false); - if (enableSQL2) - { - sqlTextField2->SetReadOnly(false); - } + if (enableSQL2) + { + sqlTextField2->SetReadOnly(false); + } if (btnOK->IsEnabled()) { wxString tmp; @@ -619,27 +619,27 @@ tmp.Printf(_("-- Execute replicated using cluster \"%s\", set %ld\n"), data->cluster.c_str(), data->setId); } sqlTextField1->SetText(tmp + GetSql()); - if (enableSQL2) - { - sqlTextField2->SetText(GetSql2()); - } + if (enableSQL2) + { + sqlTextField2->SetText(GetSql2()); + } } else { if (GetObject()) sqlTextField1->SetText(_("-- nothing to change")); - else + else sqlTextField1->SetText(_("-- definition incomplete")); - if (enableSQL2) - { - sqlTextField2->SetText(wxT("")); - } - } + if (enableSQL2) + { + sqlTextField2->SetText(wxT("")); + } + } sqlTextField1->SetReadOnly(true); - if (enableSQL2) - { - sqlTextField2->SetReadOnly(true); - } + if (enableSQL2) + { + sqlTextField2->SetReadOnly(true); + } } @@ -705,7 +705,7 @@ pgObject *data=GetObject(); // We might have a parent to refresh. If so, the children will - // inherently get refreshed as well. Yay :-) + // inherently get refreshed as well. Yay :-) if (owneritem) { // Stash the selected items path @@ -717,9 +717,9 @@ mainForm->Refresh(tblobj); // Restore the previous selection... - mainForm->SetCurrentNode(mainForm->GetBrowser()->GetRootItem(), currentPath); + mainForm->SetCurrentNode(mainForm->GetBrowser()->GetRootItem(), currentPath); } - else if (data) + else if (data) { pgObject *newData=data->Refresh(mainForm->GetBrowser(), item); if (newData && newData != data) @@ -769,12 +769,12 @@ bool dlgProperty::apply(const wxString &sql, const wxString &sql2) { - pgConn *myConn = connection; + pgConn *myConn = connection; if (GetDisconnectFirst()) { - myConn = database->GetServer()->GetConnection(); - database->Disconnect(); + myConn = database->GetServer()->GetConnection(); + database->Disconnect(); } if (!sql.IsEmpty()) @@ -863,11 +863,11 @@ void dlgProperty::OnApply(wxCommandEvent &ev) { - if (!IsUpToDate()) - { - if (wxMessageBox(wxT("The object has been changed by another user. Do you wish to continue to to try to update it?"), wxT("Overwrite changes?"), wxYES_NO) == wxNO) - return; - } + if (!IsUpToDate()) + { + if (wxMessageBox(wxT("The object has been changed by another user. Do you wish to continue to to try to update it?"), wxT("Overwrite changes?"), wxYES_NO) == wxNO) + return; + } EnableOK(false); @@ -884,11 +884,11 @@ void dlgProperty::OnOK(wxCommandEvent &ev) { - if (!IsUpToDate()) - { - if (wxMessageBox(wxT("The object has been changed by another user. Do you wish to continue to to try to update it?"), wxT("Overwrite changes?"), wxYES_NO) == wxNO) - return; - } + if (!IsUpToDate()) + { + if (wxMessageBox(wxT("The object has been changed by another user. Do you wish to continue to to try to update it?"), wxT("Overwrite changes?"), wxYES_NO) == wxNO) + return; + } EnableOK(false); @@ -903,19 +903,19 @@ if (chkReadOnly->GetValue()) { sql = GetSql(); - sql2 = GetSql2(); + sql2 = GetSql2(); } else { sql = sqlTextField1->GetText(); - if (enableSQL2) - { - sql2 = sqlTextField2->GetText(); - } - else - { - sql2 = wxT(""); - } + if (enableSQL2) + { + sql2 = sqlTextField2->GetText(); + } + else + { + sql2 = wxT(""); + } } if (!apply(sql, sql2)) @@ -933,7 +933,7 @@ if (sqlTextField1 && chkReadOnly->GetValue() && event.GetSelection() == (int)nbNotebook->GetPageCount()-1) { - FillSQLTextfield(); + FillSQLTextfield(); } } @@ -967,35 +967,35 @@ if (!item && (node->GetMetaType() == PGM_TABLE || node->GetMetaType() == PGM_VIEW)) owneritem=node->GetId(); - int metatype = node->GetMetaType(); + int metatype = node->GetMetaType(); - switch (metatype) - { - case PGM_CHECK: - case PGM_COLUMN: - case PGM_CONSTRAINT: - case PGM_FOREIGNKEY: - case PGM_INDEX: - case PGM_PRIMARYKEY: - case PGM_TRIGGER: - case PGM_UNIQUE: - owneritem=node->GetTable()->GetId(); - break; + switch (metatype) + { + case PGM_CHECK: + case PGM_COLUMN: + case PGM_CONSTRAINT: + case PGM_FOREIGNKEY: + case PGM_INDEX: + case PGM_PRIMARYKEY: + case PGM_TRIGGER: + case PGM_UNIQUE: + owneritem=node->GetTable()->GetId(); + break; - case PGM_RULE: // Rules are technically table objects! Yeuch - case EDB_PACKAGEFUNCTION: - case EDB_PACKAGEVARIABLE: - case PGM_SCHEDULE: - case PGM_STEP: - if (node->IsCollection()) - owneritem = frame->GetBrowser()->GetParentObject(node->GetId())->GetId(); - else - owneritem = frame->GetBrowser()->GetParentObject(frame->GetBrowser()->GetParentObject(node->GetId())->GetId())->GetId(); - break; + case PGM_RULE: // Rules are technically table objects! Yeuch + case EDB_PACKAGEFUNCTION: + case EDB_PACKAGEVARIABLE: + case PGM_SCHEDULE: + case PGM_STEP: + if (node->IsCollection()) + owneritem = frame->GetBrowser()->GetParentObject(node->GetId())->GetId(); + else + owneritem = frame->GetBrowser()->GetParentObject(frame->GetBrowser()->GetParentObject(node->GetId())->GetId())->GetId(); + break; - default: - break; - } + default: + break; + } } @@ -1076,13 +1076,13 @@ return false; } - // If this is a function or view, hint that the user might want to edit the object in - // the query tool. + // If this is a function or view, hint that the user might want to edit the object in + // the query tool. if (node->GetMetaType() == PGM_FUNCTION || node->GetMetaType() == PGM_VIEW) - { - if (frmHint::ShowHint(frame, HINT_OBJECT_EDITING) == wxID_CANCEL) - return false; - } + { + if (frmHint::ShowHint(frame, HINT_OBJECT_EDITING) == wxID_CANCEL) + return false; + } dlgProperty *dlg=CreateDlg(frame, node, false); @@ -1104,20 +1104,20 @@ wxString dlgProperty::qtDbString(const wxString &str) { - // Use the server aware version if possible - if (connection) - return connection->qtDbString(str); - else if (database) - return database->GetConnection()->qtDbString(str); - else - { - wxString ret = str; - ret.Replace(wxT("\\"), wxT("\\\\")); + // Use the server aware version if possible + if (connection) + return connection->qtDbString(str); + else if (database) + return database->GetConnection()->qtDbString(str); + else + { + wxString ret = str; + ret.Replace(wxT("\\"), wxT("\\\\")); ret.Replace(wxT("'"), wxT("''")); ret.Append(wxT("'")); ret.Prepend(wxT("'")); - return ret; - } + return ret; + } } void dlgProperty::OnHelp(wxCommandEvent& ev) @@ -1132,6 +1132,8 @@ { if (connection->GetIsEdb()) DisplayHelp(page.Mid(3), HELP_ENTERPRISEDB); + else if (connection->GetIsGreenplum()) + DisplayHelp(page.Mid(3), HELP_GREENPLUM); else DisplayHelp(page.Mid(3), HELP_POSTGRESQL); } @@ -1312,15 +1314,15 @@ suffix = wxT("without time zone"); } else if (sql.Right(2) == wxT("[]")) - { - sql = sql.SubString(0,sql.Len()-3); - isArray = true; - } - else if (sql.Right(3) == wxT("[]\"")) - { - sql = sql.SubString(1,sql.Len()-4); - isArray = true; - } + { + sql = sql.SubString(0,sql.Len()-3); + isArray = true; + } + else if (sql.Right(3) == wxT("[]\"")) + { + sql = sql.SubString(1,sql.Len()-4); + isArray = true; + } // Stick the length on if (isVarLen && txtLength) @@ -1543,8 +1545,8 @@ #ifdef __WXMAC__ void dlgSecurityProperty::OnChangeSize(wxSizeEvent &ev) { - securityPage->lbPrivileges->SetSize(wxDefaultCoord, wxDefaultCoord, - ev.GetSize().GetWidth(), ev.GetSize().GetHeight() - 550); + securityPage->lbPrivileges->SetSize(wxDefaultCoord, wxDefaultCoord, + ev.GetSize().GetWidth(), ev.GetSize().GetHeight() - 550); if (GetAutoLayout()) { Layout(); @@ -1558,7 +1560,7 @@ if (securityPage) { securityPage->SetConnection(connection); - //securityPage->Layout(); + //securityPage->Layout(); } return dlgProperty::Go(modal); @@ -1624,8 +1626,8 @@ void dlgSecurityProperty::EnableOK(bool enable) { - // Don't enable the OK button if the object isn't yet created, - // leave that to the object dialog. + // Don't enable the OK button if the object isn't yet created, + // leave that to the object dialog. if (securityChanged && GetObject()) { wxString sql=GetSql(); @@ -1783,11 +1785,11 @@ void dlgAgentProperty::OnOK(wxCommandEvent &ev) { - if (!IsUpToDate()) - { - if (wxMessageBox(wxT("The object has been changed by another user. Do you wish to continue to to try to update it?"), wxT("Overwrite changes?"), wxYES_NO) == wxNO) - return; - } + if (!IsUpToDate()) + { + if (wxMessageBox(wxT("The object has been changed by another user. Do you wish to continue to to try to update it?"), wxT("Overwrite changes?"), wxYES_NO) == wxNO) + return; + } if (IsModal()) { Index: pgadmin/dlg/dlgColumn.cpp =================================================================== --- pgadmin/dlg/dlgColumn.cpp (revision 7597) +++ pgadmin/dlg/dlgColumn.cpp (working copy) @@ -59,7 +59,7 @@ { column=node; table=parentNode; - wxASSERT(!table || (table->GetMetaType() == PGM_TABLE || table->GetMetaType() == PGM_VIEW)); + wxASSERT(!table || (table->GetMetaType() == PGM_TABLE || table->GetMetaType() == PGM_VIEW || table->GetMetaType() == PGM_EXTTABLE)); txtAttstattarget->SetValidator(numericValidator); @@ -207,9 +207,9 @@ chkNotNull->SetValue(column->GetNotNull()); txtAttstattarget->SetValue(NumToStr(column->GetAttstattarget())); - wxString fullType = column->GetRawTypename(); - if (column->GetIsArray()) - fullType += wxT("[]"); + wxString fullType = column->GetRawTypename(); + if (column->GetIsArray()) + fullType += wxT("[]"); cbDatatype->Append(fullType); AddType(wxT("?"), column->GetAttTypId(), fullType); @@ -262,6 +262,14 @@ cbDatatype->Disable(); txtAttstattarget->Disable(); } + else if (column->GetTable()->GetMetaType() == PGM_EXTTABLE) // Disable controls not valid for external table columns + { + txtName->Disable(); + chkNotNull->Disable(); + txtLength->Disable(); + cbDatatype->Disable(); + txtAttstattarget->Disable(); + } } else { @@ -273,7 +281,7 @@ AddType(wxT(" "), 0, wxT("bigserial")); if (!table) - { + { cbClusterSet->Disable(); cbClusterSet = 0; } @@ -290,7 +298,7 @@ wxString sql; wxString name=GetName(); - bool isSerial = (cbDatatype->GetValue() == wxT("serial") || cbDatatype->GetValue() == wxT("bigserial")); + bool isSerial = (cbDatatype->GetValue() == wxT("serial") || cbDatatype->GetValue() == wxT("bigserial")); if (table) { Index: pgadmin/gqb/gqbBrowser.cpp =================================================================== --- pgadmin/gqb/gqbBrowser.cpp (revision 7597) +++ pgadmin/gqb/gqbBrowser.cpp (working copy) @@ -32,6 +32,7 @@ #include "images/catalog-sm.xpm" #include "images/catalogs.xpm" #include "images/catalogobject-sm.xpm" +#include "images/exttable-sm.xpm" // Greenplum external tables BEGIN_EVENT_TABLE(gqbBrowser, wxTreeCtrl) EVT_TREE_ITEM_ACTIVATED(GQB_BROWSER, gqbBrowser::OnItemActivated) @@ -44,7 +45,7 @@ controller=_controller; rootNode=NULL; - // Create normal images list of browser + // Create normal images list of browser imageList = new wxImageList(16, 16); imageList->Add(wxIcon(database_sm_xpm)); imageList->Add(wxIcon(namespace_sm_xpm)); @@ -53,7 +54,8 @@ imageList->Add(wxIcon(catalogs_xpm)); imageList->Add(wxIcon(catalog_sm_xpm)); imageList->Add(wxIcon(catalogobject_sm_xpm)); - imageList->Add(wxIcon(view_sm_xpm)); + imageList->Add(wxIcon(view_sm_xpm)); + imageList->Add(wxIcon(exttable_sm_xpm)); this->AssignImageList(imageList); } @@ -104,7 +106,7 @@ { wxTreeItemId itemId = event.GetItem(); - // Simplest solution, simulate DnD but actually don't do it + // Simplest solution, simulate DnD but actually don't do it gqbObject *object = (gqbObject *) GetItemData(itemId); if(object!=NULL && (object->getType() == GQB_TABLE || object->getType() == GQB_VIEW)) { Index: pgadmin/gqb/gqbSchema.cpp =================================================================== --- pgadmin/gqb/gqbSchema.cpp (revision 7597) +++ pgadmin/gqb/gqbSchema.cpp (working copy) @@ -47,11 +47,11 @@ void gqbSchema::createTables(pgConn *conn, gqbBrowser *tablesBrowser, wxTreeItemId parentNode, OID oidVal, int tableImage, int viewImage) { - + wxString query; wxString restriction=wxT(""); - - // First Add Tables; + + // First Add Tables; if (conn->BackendMinimumVersion(8, 0)) { query= wxT("SELECT rel.oid, relname, rel.reltablespace AS spcoid, spcname, pg_get_userbyid(relowner) AS relowner, relacl, relhasoids, ") @@ -97,7 +97,7 @@ gqbTable *table = new gqbTable(this, tmpname, GQB_TABLE); parent=tablesBrowser->AppendItem(parentNode, tables->GetVal(wxT("relname")) , tableImage, tableImage, table); - // Create columns inside this table. + // Create columns inside this table. table->createObjects(tablesBrowser, conn, tables->GetOid(wxT("oid")), parent); tables->MoveNext(); @@ -106,8 +106,8 @@ delete tables; } - // Later Add Views; - query=wxT("SELECT c.oid, c.xmin, c.relname, pg_get_userbyid(c.relowner) AS viewowner, c.relacl, description") + // Later Add Views; + query=wxT("SELECT c.oid, c.xmin, c.relname, pg_get_userbyid(c.relowner) AS viewowner, c.relacl, description") wxT(" FROM pg_class c\n") wxT(" LEFT OUTER JOIN pg_description des ON (des.objoid=c.oid and des.objsubid=0)\n") wxT(" WHERE ((c.relhasrules AND (EXISTS (\n") @@ -119,7 +119,7 @@ + wxT(" ORDER BY relname"); pgSet *views = conn->ExecuteSet(query); - if (views) + if (views) { while (!views->Eof()) { @@ -127,12 +127,41 @@ gqbTable *table = new gqbTable(this, tmpname, GQB_VIEW); parent=tablesBrowser->AppendItem(parentNode, views->GetVal(wxT("relname")) , viewImage, viewImage, table); - // Create columns inside this view. + // Create columns inside this view. table->createObjects(tablesBrowser,conn,views->GetOid(wxT("oid")),parent); views->MoveNext(); - } - } + } + } - tablesBrowser->SortChildren(parentNode); + + // And Greenplum External Tables; + if (conn->GetIsGreenplum()) + { + query=wxT("SELECT c.oid, c.xmin, c.relname, pg_get_userbyid(c.relowner) AS viewowner, c.relacl, description") + wxT(" FROM pg_class c\n") + wxT(" LEFT OUTER JOIN pg_description des ON (des.objoid=c.oid and des.objsubid=0)\n") + wxT(" WHERE (c.relkind = 'x'::char)\n") + wxT(" AND relnamespace = ") + NumToStr(oidVal) + wxT("\n") + + restriction + + wxT(" ORDER BY relname"); + + pgSet *exttables = conn->ExecuteSet(query); + if (exttables) + { + while (!exttables->Eof()) + { + wxString tmpname = wxString(exttables->GetVal(wxT("relname"))); + gqbTable *table = new gqbTable(this, tmpname, GQB_VIEW); + parent=tablesBrowser->AppendItem(parentNode, exttables->GetVal(wxT("relname")) , 8, 8, table); + + // Create columns inside this view. + table->createObjects(tablesBrowser,conn,exttables->GetOid(wxT("oid")),parent); + + exttables->MoveNext(); + } + } + } + + tablesBrowser->SortChildren(parentNode); } Index: pgadmin/ui/module.mk =================================================================== --- pgadmin/ui/module.mk (revision 7597) +++ pgadmin/ui/module.mk (working copy) @@ -24,6 +24,7 @@ $(srcdir)/ui/dlgDirectDbg.xrc \ $(srcdir)/ui/dlgDomain.xrc \ $(srcdir)/ui/dlgEditGridOptions.xrc \ + $(srcdir)/ui/dlgExtTable.xrc \ $(srcdir)/ui/dlgFindReplace.xrc \ $(srcdir)/ui/dlgForeignKey.xrc \ $(srcdir)/ui/dlgFunction.xrc \ Index: pgadmin/ui/embed-xrc.bat =================================================================== --- pgadmin/ui/embed-xrc.bat (revision 7597) +++ pgadmin/ui/embed-xrc.bat (working copy) @@ -9,5 +9,5 @@ REM # REM ####################################################################### -wxrc -c -o xrcDialogs.cpp *.xrc +c:\wxWidgets-2.8.9\utils\wxrc\vc_mswu\wxrc -c -o xrcDialogs.cpp *.xrc Index: pgadmin/ui/frmOptions.xrc =================================================================== --- pgadmin/ui/frmOptions.xrc (revision 7597) +++ pgadmin/ui/frmOptions.xrc (working copy) @@ -37,69 +37,90 @@ 70,35d 160,-1d + + + 5,52d + + + 70,50d + 160,-1d + - 5,52d + 5,67d - 70,50d + 70,65d 160,-1d - 5,67d + 5,82d - 70,65d + 70,80d 160,-1d - 5,82d + 5,97d - 70,80d + 70,95d 140,-1d - 215,80d + 215,95d 15,-1d - 5,97d + 5,112d - 70,95d + 70,110d 140,-1d - 215,95d + 215,110d 15,-1d - 5,112d + 5,127d - 70,110d + 70,125d 140,-1d - 215,110d + 215,125d 15,-1d + + + 5,142d + + + 70,140d + 140,-1d + + + + 215,140d + 15,-1d + - 5,125d + 5,155d 226,12d - 15,140d + 15,170d 220,20d