Пример #1
0
pgObject *pgSchemaBase::Refresh(ctlTree *browser, const wxTreeItemId item)
{
	pgObject *schema = 0;
	pgCollection *coll = browser->GetParentCollection(item);
	if (coll)
	{
		if (coll->IsCollectionForType(PGM_CATALOG))
			schema = catalogFactory.CreateObjects(coll, 0, wxT(" WHERE nsp.oid=") + GetOidStr() + wxT("\n"));
		else
			schema = schemaFactory.CreateObjects(coll, 0, wxT(" WHERE nsp.oid=") + GetOidStr() + wxT("\n"));
	}

	return schema;
}
Пример #2
0
pgObject *pgRole::Refresh(ctlTree *browser, const wxTreeItemId item)
{
	pgObject *role = 0;
	pgCollection *coll = browser->GetParentCollection(item);
	if (coll)
	{
		if (coll->GetServer()->GetConnection()->BackendMinimumVersion(8, 5))
			role = loginRoleFactory.CreateObjects(coll, 0, wxT("\n WHERE tab.oid=") + GetOidStr());
		else
			role = loginRoleFactory.CreateObjects(coll, 0, wxT("\n WHERE oid=") + GetOidStr());
	}

	return role;
}
Пример #3
0
void pgTablespace::ShowStatistics(frmMain *form, ctlListView *statistics)
{
	if (statistics)
	{
		if (GetConnection()->HasFeature(FEATURE_SIZE))
		{
			wxLogInfo(wxT("Displaying statistics for %s"), GetTypeName().c_str());

			// Add the statistics view columns
			CreateListColumns(statistics, _("Statistic"), _("Value"));

			pgSet *stats = GetConnection()->ExecuteSet(
			                   wxT("SELECT pg_size_pretty(pg_tablespace_size(") + GetOidStr() + wxT(")) AS ") + qtIdent(_("Tablespace Size")));

			if (stats)
			{
				int col;
				for (col = 0 ; col < stats->NumCols() ; col++)
				{
					if (!stats->ColName(col).IsEmpty())
						statistics->AppendItem(stats->ColName(col), stats->GetVal(col));
				}
				delete stats;
			}
		}
	}
}
Пример #4
0
void pgTablespace::ShowDependents(frmMain *form, ctlListView *referencedBy, const wxString &where)
{
	form->StartMsg(_(" Retrieving tablespace usage"));

	referencedBy->ClearAll();
	referencedBy->AddColumn(_("Type"), 60);
	referencedBy->AddColumn(_("Database"), 80);
	referencedBy->AddColumn(_("Name"), 300);

	wxArrayString dblist;

	pgSet *set = GetConnection()->ExecuteSet(
	                 wxT("SELECT datname, datallowconn, dattablespace\n")
	                 wxT("  FROM pg_database db\n")
	                 wxT(" ORDER BY datname"));

	if (set)
	{
		while (!set->Eof())
		{
			wxString datname = set->GetVal(wxT("datname"));
			if (set->GetBool(wxT("datallowconn")))
				dblist.Add(datname);
			OID oid = set->GetOid(wxT("dattablespace"));
			if (oid == GetOid())
				referencedBy->AppendItem(databaseFactory.GetIconId(), _("Database"), datname);

			set->MoveNext();
		}
		delete set;
	}

	FillOwned(form->GetBrowser(), referencedBy, dblist,
	          wxT("SELECT cl.relkind, COALESCE(cin.nspname, cln.nspname) as nspname, COALESCE(ci.relname, cl.relname) as relname, cl.relname as indname\n")
	          wxT("  FROM pg_class cl\n")
	          wxT("  JOIN pg_namespace cln ON cl.relnamespace=cln.oid\n")
	          wxT("  LEFT OUTER JOIN pg_index ind ON ind.indexrelid=cl.oid\n")
	          wxT("  LEFT OUTER JOIN pg_class ci ON ind.indrelid=ci.oid\n")
	          wxT("  LEFT OUTER JOIN pg_namespace cin ON ci.relnamespace=cin.oid,\n")
	          wxT("       pg_database\n")
	          wxT(" WHERE datname = current_database()\n")
	          wxT("   AND (cl.reltablespace = ") + GetOidStr() + wxT("\n")
	          wxT("        OR (cl.reltablespace=0 AND dattablespace = ") + GetOidStr() + wxT("))\n")
	          wxT(" ORDER BY 1,2,3"));

	form->EndMsg(set != 0);
}
Пример #5
0
pgObject *pgType::Refresh(ctlTree *browser, const wxTreeItemId item)
{
	pgObject *type = 0;
	pgCollection *coll = browser->GetParentCollection(item);
	if (coll)
		type = typeFactory.CreateObjects(coll, 0, wxT("\n   AND t.oid=") + GetOidStr());

	return type;
}
Пример #6
0
pgObject *pgRule::Refresh(ctlTree *browser, const wxTreeItemId item)
{
	pgObject *rule = 0;
	pgCollection *coll = browser->GetParentCollection(item);
	if (coll)
		rule = ruleFactory.CreateObjects(coll, 0, wxT("\n   AND rw.oid=") + GetOidStr());

	return rule;
}
Пример #7
0
pgObject *pgForeignTable::Refresh(ctlTree *browser, const wxTreeItemId item)
{
	pgObject *ft = 0;
	pgCollection *coll = browser->GetParentCollection(item);
	if (coll)
		ft = foreignTableFactory.CreateObjects(coll, 0, wxT("\n   AND c.oid=") + GetOidStr());

	return ft;
}
Пример #8
0
pgObject *pgCatalogObject::Refresh(ctlTree *browser, const wxTreeItemId item)
{
	pgObject *catalog = 0;
	pgCollection *parent = (pgCollection *)browser->GetItemData(browser->GetItemParent(item));
	if (parent)
		catalog = catalogObjectFactory.CreateObjects(parent, 0, wxT("\n AND c.oid=") + GetOidStr());

	return catalog;
}
Пример #9
0
pgObject *pgTextSearchParser::Refresh(ctlTree *browser, const wxTreeItemId item)
{
	pgObject *parser = 0;
	pgCollection *coll = browser->GetParentCollection(item);
	if (coll)
		parser = textSearchParserFactory.CreateObjects(coll, 0, wxT("\n   AND prs.oid=") + GetOidStr());

	return parser;
}
Пример #10
0
pgObject *pgTablespace::Refresh(ctlTree *browser, const wxTreeItemId item)
{
	pgObject *tablespace = 0;
	pgCollection *coll = browser->GetParentCollection(item);
	if (coll)
		tablespace = tablespaceFactory.CreateObjects(coll, 0, wxT("\n WHERE ts.oid=") + GetOidStr());

	return tablespace;
}
Пример #11
0
pgObject *slCluster::Refresh(ctlTree *browser, const wxTreeItemId item)
{
	pgObject *cluster = 0;
	pgCollection *coll = browser->GetParentCollection(item);
	if (coll)
		cluster = slClusterFactory.CreateObjects(coll, 0, wxT(" WHERE nsp.oid=") + GetOidStr() + wxT("\n"));

	return cluster;
}
Пример #12
0
pgObject *edbResourceGroup::Refresh(ctlTree *browser, const wxTreeItemId item)
{
	pgObject *group = 0;
	pgCollection *coll = browser->GetParentCollection(item);
	if (coll)
		group = resourceGroupFactory.CreateObjects(coll, 0, wxT("\n WHERE oid=") + GetOidStr());

	return group;
}
Пример #13
0
pgObject *pgExtension::Refresh(ctlTree *browser, const wxTreeItemId item)
{
	pgObject *language = 0;
	pgCollection *coll = browser->GetParentCollection(item);
	if (coll)
		language = extensionFactory.CreateObjects(coll, 0, wxT("\n   AND x.oid=") + GetOidStr());

	return language;
}
Пример #14
0
pgObject *pgOperator::Refresh(ctlTree *browser, const wxTreeItemId item)
{
	pgObject *oper = 0;
	pgCollection *coll = browser->GetParentCollection(item);
	if (coll)
		oper = operatorFactory.CreateObjects(coll, 0, wxT("\n   AND op.oid=") + GetOidStr());

	return oper;
}
Пример #15
0
pgObject *pgSequence::Refresh(ctlTree *browser, const wxTreeItemId item)
{
	pgObject *sequence = 0;
	pgCollection *coll = browser->GetParentCollection(item);
	if (coll)
		sequence = sequenceFactory.CreateObjects(coll, 0, wxT("\n   AND cl.oid=") + GetOidStr());

	return sequence;
}
Пример #16
0
pgObject *gpResQueue::Refresh(ctlTree *browser, const wxTreeItemId item)
{
	pgObject *queue = 0;
	pgCollection *coll = browser->GetParentCollection(item);
	if (coll)
		queue = resQueueFactory.CreateObjects(coll, 0, wxT("\n WHERE oid=") + GetOidStr());

	return queue;
}
Пример #17
0
pgObject *pgForeignServer::Refresh(ctlTree *browser, const wxTreeItemId item)
{
	pgObject *fs = 0;
	pgCollection *coll = browser->GetParentCollection(item);
	if (coll)
		fs = foreignServerFactory.CreateObjects(coll, 0, wxT(" AND srv.oid=") + GetOidStr());

	return fs;
}
Пример #18
0
pgObject *pgCast::Refresh(ctlTree *browser, const wxTreeItemId item)
{
	pgObject *cast = 0;

	pgCollection *coll = browser->GetParentCollection(item);
	if (coll)
		cast = castFactory.CreateObjects(coll, 0, wxT(" WHERE ca.oid=") + GetOidStr());

	return cast;
}
Пример #19
0
pgObject *pgCheck::Refresh(ctlTree *browser, const wxTreeItemId item)
{
	pgObject *check = 0;

	pgCollection *coll = browser->GetParentCollection(item);
	if (coll)
		check = checkFactory.CreateObjects(coll, 0, wxT("\n   AND c.oid=") + GetOidStr());

	return check;
}
Пример #20
0
pgObject *pgDomain::Refresh(ctlTree *browser, const wxTreeItemId item)
{
    pgObject *domain = 0;

    pgCollection *coll = browser->GetParentCollection(item);
    if (coll)
        domain = domainFactory.CreateObjects(coll, 0, wxT("   AND d.oid=") + GetOidStr() + wxT("\n"));

    return domain;
}
Пример #21
0
pgObject *gpExtTable::Refresh(ctlTree *browser, const wxTreeItemId item)
{
	pgObject *extTable = 0;
	pgCollection *coll = browser->GetParentCollection(item);
	if (coll)
	{
		extTable = extTableFactory.CreateObjects(coll, 0, wxT("\n   AND c.oid=") + GetOidStr());
	}

	return extTable;
}
Пример #22
0
void gpResQueue::ShowTreeDetail(ctlTree *browser, frmMain *form, ctlListView *properties, ctlSQLBox *sqlPane)
{
	if (!expandedKids)
	{
		expandedKids = true;
		wxString queuesquery;

		queuesquery = wxT("SELECT rolname,\n")
		              wxT(" pg_catalog.shobj_description(r.oid, 'pg_authid') AS description\n");

		queuesquery += wxT("  FROM pg_roles r\n")
		               wxT("  JOIN pg_resqueue q ON  rolresqueue=q.oid\n")
		               wxT(" WHERE  rolresqueue=") + GetOidStr() + wxT("\n")
		               wxT(" ORDER BY rolname");

		pgSetIterator queues(GetConnection(), queuesquery);

		while (queues.RowsLeft())
		{
			wxString queue = queues.GetVal(wxT("rolname"));

			queuesIn.Add(queue);
		}
	}
	if (properties)
	{
		CreateListColumns(properties);

		properties->AppendItem(_("Name"), GetName());
		properties->AppendItem(_("OID"), GetOid());
		properties->AppendItem(_("Active threshold"), GetCountLimit());
		properties->AppendItem(_("Cost threshold"), GetCostLimit());
		properties->AppendItem(_("Ignore threshold"), GetIgnoreCostLimit());
		properties->AppendItem(_("Over commit?"), BoolToYesNo(GetOvercommit()));

		wxString roleList;

		size_t index;
		for (index = 0 ; index < queuesIn.GetCount() ; index++)
		{
			if (!roleList.IsEmpty())
				roleList += wxT(", ");
			roleList += queuesIn.Item(index);
		}
		properties->AppendItem(_("Roles using this"), roleList);
		properties->AppendItem(_("Comment"), firstLineOnly(GetComment()));

	}
}
Пример #23
0
pgObject *pgView::Refresh(ctlTree *browser, const wxTreeItemId item)
{
	pgObject *view = 0;
	pgCollection *coll = browser->GetParentCollection(item);
	if (coll)
	{
		// OIDs may change in EDB which allows the returned column set to be changed.
		if (GetConnection()->EdbMinimumVersion(8, 0))
			view = viewFactory.CreateObjects(coll, 0, wxT("\n   AND c.relname=") + GetConnection()->qtDbString(GetName()));
		else
			view = viewFactory.CreateObjects(coll, 0, wxT("\n   AND c.oid=") + GetOidStr());
	}

	return view;
}
Пример #24
0
wxString pgView::GetCols(ctlTree *browser, size_t indent, wxString &QMs, bool withQM)
{
	wxString sql;
	wxString line;

	int colcount = 0;
	pgSetIterator set(GetConnection(),
	                  wxT("SELECT attname\n")
	                  wxT("  FROM pg_attribute\n")
	                  wxT(" WHERE attrelid=") + GetOidStr() + wxT(" AND attnum>0\n")
	                  wxT(" ORDER BY attnum"));


	while (set.RowsLeft())
	{
		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 += qtIdent(set.GetVal(0));
		if (withQM)
			line += wxT("=?");
		QMs += wxT("?");
	}

	if (!line.IsEmpty())
	{
		if (!sql.IsEmpty())
			sql += wxT("\n") + wxString(' ', indent);
		sql += line;
	}
	return sql;
}
Пример #25
0
void pgTrigger::ReadColumnDetails()
{
	if (!expandedKids && GetLanguage() != wxT("edbspl"))
	{
		expandedKids = true;

		if (GetConnection()->BackendMinimumVersion(8, 5))
		{
			pgSet *res = ExecuteSet(
			                 wxT("SELECT attname\n")
			                 wxT("FROM pg_attribute,\n")
			                 wxT("(SELECT tgrelid, unnest(tgattr) FROM pg_trigger\n")
			                 wxT(" WHERE oid=") + GetOidStr() + wxT(") AS columns(tgrelid, colnum)\n")
			                 wxT("WHERE colnum=attnum AND tgrelid=attrelid"));

			// Allocate memory to store column def
			if (res->NumRows() > 0) columnList.Alloc(res->NumRows());

			long i = 1;
			columns = wxT("");
			quotedColumns = wxT("");

			while (!res->Eof())
			{
				if (i > 1)
				{
					columns += wxT(", ");
					quotedColumns += wxT(", ");
				}

				columns += res->GetVal(wxT("attname"));
				quotedColumns += qtIdent(res->GetVal(wxT("attname")));
				columnList.Add(res->GetVal(wxT("attname")));

				i++;
				res->MoveNext();
			}
		}
		else
		{
			columns = wxT("");
			quotedColumns = wxT("");
		}
	}
}
void pgSequence::ShowStatistics(frmMain *form, ctlListView *statistics)
{
    wxLogInfo(wxT("Displaying statistics for sequence on ") +GetSchema()->GetIdentifier());

    // Add the statistics view columns
    CreateListColumns(statistics, _("Statistic"), _("Value"));

    pgSet *stats = GetSchema()->GetDatabase()->ExecuteSet(wxT(
        "SELECT blks_read, blks_hit FROM pg_statio_all_sequences WHERE relid = ") + GetOidStr());

    if (stats)
    {
        statistics->InsertItem(0, _("Blocks Read"), PGICON_STATISTICS);
        statistics->SetItem(0l, 1, stats->GetVal(wxT("blks_read")));
        statistics->InsertItem(1, _("Blocks Hit"), PGICON_STATISTICS);
        statistics->SetItem(1, 1, stats->GetVal(wxT("blks_hit")));

        delete stats;
    }
}
Пример #27
0
pgObject *gpPartition::Refresh(ctlTree *browser, const wxTreeItemId item)
{
	gpPartition *partition = 0;
	pgCollection *coll = browser->GetParentCollection(item);
	if (coll)
		partition = (gpPartition *)partitionFactory.CreateObjects(coll, 0, wxT("\n   AND rel.oid=") + GetOidStr());

	return partition;
}
Пример #28
0
void pgRole::ShowTreeDetail(ctlTree *browser, frmMain *form, ctlListView *properties, ctlSQLBox *sqlPane)
{
    if (!expandedKids)
    {
        expandedKids=true;
        wxString rolesquery;

        if (GetConnection()->BackendMinimumVersion(8, 2))
            rolesquery = wxT("SELECT rolname, admin_option,\n") 
                         wxT(" pg_catalog.shobj_description(r.oid, 'pg_authid') AS description\n");
        else
            rolesquery = wxT("SELECT rolname, admin_option\n"); 

        rolesquery += wxT("  FROM pg_roles r\n") 
                      wxT("  JOIN pg_auth_members ON r.oid=roleid\n") 
                      wxT(" WHERE member=") + GetOidStr() + wxT("\n") 
                      wxT(" ORDER BY rolname");

        pgSetIterator roles(GetConnection(), rolesquery);

        while (roles.RowsLeft())
        {
            wxString role=roles.GetVal(wxT("rolname"));
            if (roles.GetBool(wxT("admin_option")))
                role += PGROLE_ADMINOPTION;

            rolesIn.Add(role);
        }
    }
    if (properties)
    {
        CreateListColumns(properties);

        properties->AppendItem(_("Name"), GetName());
        properties->AppendItem(_("OID"), GetOid());
        properties->AppendItem(_("Account expires"), DateToAnsiStr(GetAccountExpires()));
        properties->AppendItem(_("Can login?"), BoolToYesNo(GetCanLogin()));
        properties->AppendItem(_("Superuser?"), BoolToYesNo(GetSuperuser()));
        properties->AppendItem(_("Create databases?"), BoolToYesNo(GetCreateDatabase()));
        properties->AppendItem(_("Create roles?"), BoolToYesNo(GetCreateRole()));
        properties->AppendItem(_("Update catalogs?"), BoolToYesNo(GetUpdateCatalog()));
        properties->AppendItem(_("Inherits?"), BoolToYesNo(GetInherits()));
        if (server->GetConnection()->BackendMinimumVersion(9, 1))
        {
            properties->AppendItem(_("Replication?"), BoolToYesNo(GetReplication()));
        }

        wxString strConnLimit;
        strConnLimit.Printf(wxT("%ld"), GetConnectionLimit()); 
        properties->AppendItem(_("Connection Limit"), strConnLimit);

        properties->AppendItem(_("Comment"), firstLineOnly(GetComment()));

        wxString roleList;

        size_t index;
        for (index=0 ; index < rolesIn.GetCount() ; index++)
        {
            if (!roleList.IsEmpty())
                roleList += wxT(", ");
            roleList += rolesIn.Item(index);
        }
        properties->AppendItem(_("Member of"), roleList);

        for (index=0; index < configList.GetCount() ; index++)
        {
            wxString item=configList.Item(index);
            properties->AppendItem(item.BeforeFirst('='), item.AfterFirst('='));
        }
    }
}
Пример #29
0
void pgRole::ShowDependents(frmMain *form, ctlListView *referencedBy, const wxString &where)
{
    form->StartMsg(_(" Retrieving Role owned objects"));

    referencedBy->ClearAll();
    referencedBy->AddColumn(_("Type"), 60);
    referencedBy->AddColumn(_("Database"), 80);
    referencedBy->AddColumn(_("Name"), 300);

    wxString sysoid = NumToStr(GetConnection()->GetLastSystemOID());

    wxArrayString dblist;

    pgSet *set;
    set=GetConnection()->ExecuteSet(
    wxT("SELECT 'd' as type, datname, datallowconn, datdba\n")
    wxT("  FROM pg_database db\n")
    wxT("UNION\n")
    wxT("SELECT 'M', spcname, null, null\n")
    wxT("  FROM pg_tablespace where spcowner=") + GetOidStr() + wxT("\n")
    wxT(" ORDER BY 1, 2"));

    if (set)
    {
        while (!set->Eof())
        {
            wxString name=set->GetVal(wxT("datname"));
            if (set->GetVal(wxT("type")) == wxT("d"))
            {
                if (set->GetBool(wxT("datallowconn")))
                    dblist.Add(name);
                if (GetOidStr() == set->GetLong(wxT("datdba")))
                    referencedBy->AppendItem(databaseFactory.GetIconId(), _("Database"), name);
            }
            else
                referencedBy->AppendItem(tablespaceFactory.GetIconId(), _("Tablespace"), wxEmptyString, name);

            set->MoveNext();
        }
        delete set;
    }

    // We ignore classid and refclassid here because we hope that oids are unique
    // across system tables.
    // Strictly speaking, we'd need to join pg_shdepend to each subquery

    wxString depOids=wxT("(SELECT objid FROM pg_shdepend WHERE refobjid=") + GetOidStr() + wxT(")");

    FillOwned(form->GetBrowser(), referencedBy, dblist, 
        wxT("SELECT cl.relkind, COALESCE(cin.nspname, cln.nspname) as nspname, COALESCE(ci.relname, cl.relname) as relname, cl.relname as indname\n")
        wxT("  FROM pg_class cl\n")
        wxT("  JOIN pg_namespace cln ON cl.relnamespace=cln.oid\n")
        wxT("  LEFT OUTER JOIN pg_index ind ON ind.indexrelid=cl.oid\n")
        wxT("  LEFT OUTER JOIN pg_class ci ON ind.indrelid=ci.oid\n")
        wxT("  LEFT OUTER JOIN pg_namespace cin ON ci.relnamespace=cin.oid\n")
        wxT(" WHERE cl.oid IN ") + depOids + wxT(" AND cl.oid > ") + sysoid + wxT("\n")
        wxT("UNION ALL\n")
        wxT("SELECT 'n', null, nspname, null\n")
        wxT("  FROM pg_namespace nsp WHERE nsp.oid IN ") + depOids + wxT(" AND nsp.oid > ") + sysoid + wxT("\n")
        wxT("UNION ALL\n")
        wxT("SELECT CASE WHEN typtype='d' THEN 'd' ELSE 'y' END, null, typname, null\n")
        wxT("  FROM pg_type ty WHERE ty.oid IN ") + depOids + wxT(" AND ty.oid > ") + sysoid + wxT("\n")
        wxT("UNION ALL\n")
        wxT("SELECT 'C', null, conname, null\n")
        wxT("  FROM pg_conversion co WHERE co.oid IN ") + depOids + wxT(" AND co.oid > ") + sysoid + wxT("\n")
        wxT("UNION ALL\n")
        wxT("SELECT CASE WHEN prorettype=") + NumToStr(PGOID_TYPE_TRIGGER) + wxT(" THEN 'T' ELSE 'p' END, null, proname, null\n")
        wxT("  FROM pg_proc pr WHERE pr.oid IN ") + depOids + wxT(" AND pr.oid > ") + sysoid + wxT("\n")
        wxT("UNION ALL\n")
        wxT("SELECT 'o', null, oprname || '('::text || ")
                    wxT("COALESCE(tl.typname, ''::text) || ")
                    wxT("CASE WHEN tl.oid IS NOT NULL AND tr.oid IS NOT NULL THEN ','::text END || ")
                    wxT("COALESCE(tr.typname, ''::text) || ')'::text, null\n")
        wxT("  FROM pg_operator op\n")
        wxT("  LEFT JOIN pg_type tl ON tl.oid=op.oprleft\n")
        wxT("  LEFT JOIN pg_type tr ON tr.oid=op.oprright\n")
        wxT(" WHERE op.oid IN ") + depOids + wxT(" AND op.oid > ") + sysoid + wxT("\n")
        wxT(" ORDER BY 1,2,3"));
            
    form->EndMsg(set != 0);
}
Пример #30
0
void pgType::ShowTreeDetail(ctlTree *browser, frmMain *form, ctlListView *properties, ctlSQLBox *sqlPane)
{
	wxString query;
	wxString collation;

	if (!expandedKids)
	{
		expandedKids = true;
		if (GetTypeClass() == TYPE_COMPOSITE)
		{
			query = wxT("SELECT attname, format_type(t.oid,NULL) AS typname, attndims, atttypmod, nsp.nspname,\n")
			        wxT("       (SELECT COUNT(1) from pg_type t2 WHERE t2.typname=t.typname) > 1 AS isdup");
			if (GetConnection()->BackendMinimumVersion(9, 1))
				query += wxT(",\n       collname, nspc.nspname as collnspname");
			query += wxT("\n  FROM pg_attribute att\n")
			         wxT("  JOIN pg_type t ON t.oid=atttypid\n")
			         wxT("  JOIN pg_namespace nsp ON t.typnamespace=nsp.oid\n")
			         wxT("  LEFT OUTER JOIN pg_type b ON t.typelem=b.oid\n");
			if (GetConnection()->BackendMinimumVersion(9, 1))
				query += wxT("  LEFT OUTER JOIN pg_collation c ON att.attcollation=c.oid\n")
				         wxT("  LEFT OUTER JOIN pg_namespace nspc ON c.collnamespace=nspc.oid\n");
			query += wxT(" WHERE att.attrelid=") + NumToStr(relOid) + wxT("\n")
			         wxT(" ORDER by attnum");
			pgSet *set = ExecuteSet(query);
			if (set)
			{
				int anzvar = 0;
				while (!set->Eof())
				{
					wxString element;
					if (anzvar++)
					{
						typesList += wxT(", ");
						quotedTypesList += wxT(",\n    ");
					}
					typesList += set->GetVal(wxT("attname")) + wxT(" ");
					typesArray.Add(set->GetVal(wxT("attname")));
					quotedTypesList += qtIdent(set->GetVal(wxT("attname"))) + wxT(" ");

					pgDatatype dt(set->GetVal(wxT("nspname")), set->GetVal(wxT("typname")),
					              set->GetBool(wxT("isdup")), set->GetLong(wxT("attndims")) > 0, set->GetLong(wxT("atttypmod")));

					wxString nspname = set->GetVal(wxT("nspname"));

					typesList += dt.GetSchemaPrefix(GetDatabase()) + dt.FullName();
					typesArray.Add(dt.GetSchemaPrefix(GetDatabase()) + dt.FullName());
					quotedTypesList += dt.GetQuotedSchemaPrefix(GetDatabase()) + dt.QuotedFullName();

					if (GetConnection()->BackendMinimumVersion(9, 1))
					{
						if (set->GetVal(wxT("collname")).IsEmpty() || (set->GetVal(wxT("collname")) == wxT("default") && set->GetVal(wxT("collnspname")) == wxT("pg_catalog")))
							collation = wxEmptyString;
						else
						{
							collation = qtIdent(set->GetVal(wxT("collnspname"))) + wxT(".") + qtIdent(set->GetVal(wxT("collname")));
							quotedTypesList += wxT(" COLLATE ") + collation;
						}
						collationsArray.Add(collation);
					}
					typesArray.Add(collation);

					set->MoveNext();
				}
				delete set;
			}
		}
		else if (GetTypeClass() == TYPE_ENUM)
		{
			query = wxT("SELECT enumlabel\n")
			        wxT("  FROM pg_enum\n")
			        wxT(" WHERE enumtypid=") + GetOidStr() + wxT("\n");
			if (GetConnection()->BackendMinimumVersion(9, 1))
				query += wxT(" ORDER by enumsortorder");
			else
				query += wxT(" ORDER by oid");
			pgSet *set = ExecuteSet(query);
			if (set)
			{
				int anzvar = 0;
				while (!set->Eof())
				{
					wxString element;
					if (anzvar++)
					{
						labelList += wxT(", ");
						quotedLabelList += wxT(",\n    ");
					}
					labelList += set->GetVal(wxT("enumlabel"));
					labelArray.Add(set->GetVal(wxT("enumlabel")));
					quotedLabelList += GetDatabase()->connection()->qtDbString(set->GetVal(wxT("enumlabel")));

					set->MoveNext();
				}
				delete set;
			}
		}
	}

	if (properties)
	{
		CreateListColumns(properties);

		properties->AppendItem(_("Name"), GetName());
		properties->AppendItem(_("OID"), GetOid());
		properties->AppendItem(_("Owner"), GetOwner());
		properties->AppendItem(_("Alias"), GetAlias());
		if (GetTypeClass() == TYPE_COMPOSITE)
		{
			properties->AppendItem(_("Members"), GetTypesList());
		}
		if (GetTypeClass() == TYPE_ENUM)
		{
			properties->AppendItem(_("Labels"), GetLabelList());
		}
		else
		{
			properties->AppendItem(_("Alignment"), GetAlignment());
			properties->AppendItem(_("Internal length"), GetInternalLength());
			properties->AppendItem(_("Default"), GetDefault());
			properties->AppendItem(_("Passed by Value?"), BoolToYesNo(GetPassedByValue()));
			if (!GetElement().IsEmpty())
			{
				properties->AppendItem(_("Element"), GetElement());
				properties->AppendItem(_("Delimiter"), GetDelimiter());
			}
			properties->AppendItem(_("Input function"), GetInputFunction());
			properties->AppendItem(_("Output function"), GetOutputFunction());
			if (GetConnection()->BackendMinimumVersion(7, 4))
			{
				properties->AppendItem(_("Receive function"), GetReceiveFunction());
				properties->AppendItem(_("Send function"), GetSendFunction());
			}
			if (GetConnection()->BackendMinimumVersion(8, 3))
			{
				if (GetTypmodinFunction().Length() > 0)
					properties->AppendItem(_("Typmod in function"), GetTypmodinFunction());
				if (GetTypmodoutFunction().Length() > 0)
					properties->AppendItem(_("Typmod out function"), GetTypmodoutFunction());
			}
			properties->AppendItem(_("Storage"), GetStorage());
			if (GetConnection()->BackendMinimumVersion(9, 1))
				properties->AppendItem(_("Collatable?"), BoolToYesNo(GetCollatable()));
		}
		properties->AppendYesNoItem(_("System type?"), GetSystemObject());
		properties->AppendItem(_("Comment"), firstLineOnly(GetComment()));

		if (!GetLabels().IsEmpty())
		{
			wxArrayString seclabels = GetProviderLabelArray();
			if (seclabels.GetCount() > 0)
			{
				for (unsigned int index = 0 ; index < seclabels.GetCount() - 1 ; index += 2)
				{
					properties->AppendItem(seclabels.Item(index), seclabels.Item(index + 1));
				}
			}
		}
	}
}