1
//////////////////////////////////////////////////////////////////////////
3
// pgAdmin III - PostgreSQL Tools
5
// Copyright (C) 2002 - 2009, The pgAdmin Development Team
6
// This software is released under the BSD Licence
8
// gpPartition.cpp - Greenplum Table Partition class
10
//////////////////////////////////////////////////////////////////////////
15
#include "utils/misc.h"
16
#include "frm/frmHint.h"
17
#include "frm/frmMain.h"
18
#include "frm/frmMaintenance.h"
19
#include "schema/pgTable.h"
20
#include "schema/gpPartition.h"
21
#include "schema/pgColumn.h"
22
#include "schema/pgIndexConstraint.h"
23
#include "schema/pgForeignKey.h"
24
#include "schema/pgCheck.h"
25
#include "utils/sysSettings.h"
26
#include "utils/pgfeatures.h"
27
#include "schema/pgRule.h"
28
#include "schema/pgTrigger.h"
29
#include "schema/pgConstraints.h"
34
gpPartition::gpPartition(pgSchema *newSchema, const wxString& newName)
35
: pgTable(newSchema, partitionFactory, newName)
39
gpPartition::~gpPartition()
43
bool gpPartition::CanCreate() { return false; }
45
wxMenu *gpPartition::GetNewMenu()
47
wxMenu *menu=pgObject::GetNewMenu();
48
if (schema->GetCreatePrivilege())
55
wxString gpPartition::GetCreate()
59
// sql = GetQuotedIdentifier() + wxT(" ")
60
// + GetTypeName().Upper() + GetDefinition();
61
sql = wxT("Not implemented yet..sorry");
66
wxString gpPartition::GetSql(ctlTree *browser)
70
sql += _("Note: This DDL is a representation of how the partition might look as a table.");
73
sql += pgTable::GetSql(browser);
77
pgObject *gpPartition::Refresh(ctlTree *browser, const wxTreeItemId item)
79
gpPartition *partition=0;
80
pgCollection *coll=browser->GetParentCollection(item);
82
partition = (gpPartition*)partitionFactory.CreateObjects(coll, 0, wxT("\n AND rel.oid=") + GetOidStr());
87
///////////////////////////////////////////////////////////
89
gpPartitionCollection::gpPartitionCollection(pgaFactory *factory, gpPartition *_table)
90
: pgTableCollection(factory, _table->GetSchema()) { iSetOid(_table->GetOid()); }
93
pgObject *gpPartitionFactory::CreateObjects(pgCollection *coll, ctlTree *browser, const wxString &restriction)
95
gpPartitionCollection *collection=(gpPartitionCollection*)coll;
99
// Greenplum returns reltuples and relpages as tuples per segmentDB and pages per segmentDB,
100
// so we need to multiply them by the number of segmentDBs to get reasonable values.
103
query = wxT("SELECT count(*) AS gp_segments from pg_catalog.gp_configuration where definedprimary = 't' and content >= 0");
104
gp_segments = StrToLong(collection->GetDatabase()->ExecuteScalar(query));
105
if (gp_segments <= 1)
111
query= wxT("SELECT rel.oid, relname, rel.reltablespace AS spcoid, spcname, pg_get_userbyid(relowner) AS relowner, relacl, relhasoids, ")
112
wxT("relhassubclass, reltuples, description, conname, conkey, parname, \n")
113
wxT(" EXISTS(select 1 FROM pg_trigger\n")
114
wxT(" JOIN pg_proc pt ON pt.oid=tgfoid AND pt.proname='logtrigger'\n")
115
wxT(" JOIN pg_proc pc ON pc.pronamespace=pt.pronamespace AND pc.proname='slonyversion'\n")
116
wxT(" WHERE tgrelid=rel.oid) AS isrepl\n");
118
query += wxT(", substring(array_to_string(reloptions, ',') from 'fillfactor=([0-9]*)') AS fillfactor \n");
119
query += wxT(", gpd.localoid, gpd.attrnums \n");
120
query += wxT(", substring(array_to_string(reloptions, ',') from 'appendonly=([a-z]*)') AS appendonly \n");
121
query += wxT(", substring(array_to_string(reloptions, ',') from 'compresslevel=([0-9]*)') AS compresslevel \n");
122
query += wxT(", substring(array_to_string(reloptions, ',') from 'columnstore=([a-z]*)') AS columnstore \n");
123
query += wxT(", substring(array_to_string(reloptions, ',') from 'compresstype=([a-z0-9]*)') AS compresstype \n");
124
query += wxT(", substring(array_to_string(reloptions, ',') from 'blocksize=([0-9]*)') AS blocksize \n");
125
query += wxT(", substring(array_to_string(reloptions, ',') from 'checksum=([a-z]*)') AS checksum \n");
126
//query += wxT(", rel.oid in (select parrelid from pg_partition) as ispartitioned\n"); // This only works for top-level tables, not intermediate ones
127
// This looks for intermediate partitions that have subpartitions
128
query += wxT(", rel.oid in (select pr.parchildrelid from pg_partition_rule pr, pg_partition pp where pr.paroid = pp.oid and pp.parlevel < (select max(parlevel) from pg_partition where parrelid = pp.parrelid)) as ispartitioned \n");
131
query += wxT(" FROM pg_class rel JOIN pg_partition_rule pr ON(rel.oid = pr.parchildrelid) JOIN pg_partition p ON (pr.paroid = p.oid)\n")
132
wxT(" JOIN pg_inherits i ON (rel.oid = i.inhrelid) \n")
133
wxT(" LEFT OUTER JOIN pg_tablespace ta on ta.oid=rel.reltablespace\n")
134
wxT(" LEFT OUTER JOIN pg_description des ON (des.objoid=rel.oid AND des.objsubid=0)\n")
135
wxT(" LEFT OUTER JOIN pg_constraint c ON c.conrelid=rel.oid AND c.contype='p'\n");
136
query += wxT(" LEFT OUTER JOIN gp_distribution_policy gpd ON gpd.localoid=rel.oid\n");
137
query += wxT(" WHERE relkind = 'r' ");
138
query += wxT(" AND i.inhparent = ") + collection->GetOidStr() + wxT("\n");
140
query += restriction +
141
wxT(" ORDER BY relname");
144
tables= collection->GetDatabase()->ExecuteSet(query);
147
while (!tables->Eof())
149
table = new gpPartition(collection->GetSchema(), tables->GetVal(wxT("relname")));
151
table->iSetOid(tables->GetOid(wxT("oid")));
152
table->iSetOwner(tables->GetVal(wxT("relowner")));
153
table->iSetAcl(tables->GetVal(wxT("relacl")));
155
if (tables->GetOid(wxT("spcoid")) == 0)
156
table->iSetTablespaceOid(collection->GetDatabase()->GetTablespaceOid());
158
table->iSetTablespaceOid(tables->GetOid(wxT("spcoid")));
160
if (tables->GetVal(wxT("spcname")) == wxEmptyString)
161
table->iSetTablespace(collection->GetDatabase()->GetTablespace());
163
table->iSetTablespace(tables->GetVal(wxT("spcname")));
165
table->iSetComment(tables->GetVal(wxT("description")));
166
table->iSetHasOids(tables->GetBool(wxT("relhasoids")));
167
table->iSetEstimatedRows(tables->GetDouble(wxT("reltuples")) * gp_segments);
169
table->iSetFillFactor(tables->GetVal(wxT("fillfactor")));
171
table->iSetHasSubclass(tables->GetBool(wxT("relhassubclass")));
172
table->iSetPartitionName(tables->GetVal(wxT("parname")));
173
table->iSetPrimaryKeyName(tables->GetVal(wxT("conname")));
174
table->iSetIsReplicated(tables->GetBool(wxT("isrepl")));
175
wxString cn=tables->GetVal(wxT("conkey"));
176
cn=cn.Mid(1, cn.Length()-2);
177
table->iSetPrimaryKeyColNumbers(cn);
180
Oid lo=tables->GetOid(wxT("localoid"));
181
wxString db=tables->GetVal(wxT("attrnums"));
182
db=db.Mid(1, db.Length()-2);
183
table->iSetDistributionColNumbers(db);
184
if (lo > 0 && db.Length() == 0)
185
table->iSetDistributionIsRandom();
186
table->iSetAppendOnly(tables->GetVal(wxT("appendonly")));
187
table->iSetCompressLevel(tables->GetVal(wxT("compresslevel")));
188
table->iSetIsColumnStore(tables->GetVal(wxT("columnstore")));
189
table->iSetCompressType(tables->GetVal(wxT("compresstype")));
190
table->iSetBlocksize(tables->GetVal(wxT("blocksize")));
191
table->iSetChecksum(tables->GetVal(wxT("checksum")));
193
table->iSetPartitionDef(wxT(""));
194
table->iSetIsPartitioned(tables->GetBool(wxT("ispartitioned")));
198
browser->AppendObject(collection, table);
210
void gpPartitionFactory::AppendMenu(wxMenu *menu)
214
#include "images/table.xpm"
215
#include "images/table-sm.xpm"
216
#include "images/tables.xpm"
218
gpPartitionFactory::gpPartitionFactory()
219
: pgTableObjFactory(__("Partition"), __("New Partition..."), __("Create a new Partition."), table_xpm, table_sm_xpm)
221
metaType = GP_PARTITION;
224
pgCollection *gpPartitionFactory::CreateCollection(pgObject *obj)
226
return new gpPartitionCollection(GetCollectionFactory(), (gpPartition *)obj );
229
gpPartitionFactory partitionFactory;
230
static pgaCollectionFactory cf(&partitionFactory, __("Partitions"), tables_xpm);