|
|
@ -47,15 +47,15 @@ describeAggregates(const char *name, PsqlSettings *pset, bool verbose, bool desc
|
|
|
|
strcpy(buf,
|
|
|
|
strcpy(buf,
|
|
|
|
"SELECT a.aggname AS \"Name\", t.typname AS \"Type\"");
|
|
|
|
"SELECT a.aggname AS \"Name\", t.typname AS \"Type\"");
|
|
|
|
if (verbose)
|
|
|
|
if (verbose)
|
|
|
|
strcat(buf, " ,u.usename as \"Owner\"");
|
|
|
|
strcat(buf, " ,u.usename as \"Owner\"");
|
|
|
|
if (desc)
|
|
|
|
if (desc)
|
|
|
|
strcat(buf, ",\n obj_description(a.oid) as \"Description\"");
|
|
|
|
strcat(buf, ",\n obj_description(a.oid) as \"Description\"");
|
|
|
|
strcat(buf, !verbose ?
|
|
|
|
strcat(buf, !verbose ?
|
|
|
|
("\nFROM pg_aggregate a, pg_type t\n"
|
|
|
|
("\nFROM pg_aggregate a, pg_type t\n"
|
|
|
|
"WHERE a.aggbasetype = t.oid\n") :
|
|
|
|
"WHERE a.aggbasetype = t.oid\n") :
|
|
|
|
("\nFROM pg_aggregate a, pg_type t, pg_user u\n"
|
|
|
|
("\nFROM pg_aggregate a, pg_type t, pg_user u\n"
|
|
|
|
"WHERE a.aggbasetype = t.oid AND a.aggowner = u.usesysid\n")
|
|
|
|
"WHERE a.aggbasetype = t.oid AND a.aggowner = u.usesysid\n")
|
|
|
|
);
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
|
|
if (name)
|
|
|
|
if (name)
|
|
|
|
{
|
|
|
|
{
|
|
|
@ -68,16 +68,16 @@ describeAggregates(const char *name, PsqlSettings *pset, bool verbose, bool desc
|
|
|
|
"UNION\n"
|
|
|
|
"UNION\n"
|
|
|
|
"SELECT a.aggname AS \"Name\", '(all types)' as \"Type\"");
|
|
|
|
"SELECT a.aggname AS \"Name\", '(all types)' as \"Type\"");
|
|
|
|
if (verbose)
|
|
|
|
if (verbose)
|
|
|
|
strcat(buf, " ,u.usename as \"Owner\"");
|
|
|
|
strcat(buf, " ,u.usename as \"Owner\"");
|
|
|
|
if (desc)
|
|
|
|
if (desc)
|
|
|
|
strcat(buf,
|
|
|
|
strcat(buf,
|
|
|
|
",\n obj_description(a.oid) as \"Description\"");
|
|
|
|
",\n obj_description(a.oid) as \"Description\"");
|
|
|
|
strcat(buf, !verbose ?
|
|
|
|
strcat(buf, !verbose ?
|
|
|
|
("\nFROM pg_aggregate a\n"
|
|
|
|
("\nFROM pg_aggregate a\n"
|
|
|
|
"WHERE a.aggbasetype = 0\n") :
|
|
|
|
"WHERE a.aggbasetype = 0\n") :
|
|
|
|
("\nFROM pg_aggregate a, pg_user u\n"
|
|
|
|
("\nFROM pg_aggregate a, pg_user u\n"
|
|
|
|
"WHERE a.aggbasetype = 0 AND a.aggowner = u.usesysid\n")
|
|
|
|
"WHERE a.aggbasetype = 0 AND a.aggowner = u.usesysid\n")
|
|
|
|
);
|
|
|
|
);
|
|
|
|
if (name)
|
|
|
|
if (name)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
strcat(buf, " AND a.aggname ~* '");
|
|
|
|
strcat(buf, " AND a.aggname ~* '");
|
|
|
@ -117,22 +117,22 @@ describeFunctions(const char *name, PsqlSettings *pset, bool verbose, bool desc)
|
|
|
|
* arguments, but have no types defined for those arguments
|
|
|
|
* arguments, but have no types defined for those arguments
|
|
|
|
*/
|
|
|
|
*/
|
|
|
|
strcpy(buf,
|
|
|
|
strcpy(buf,
|
|
|
|
"SELECT t.typname as \"Result\", p.proname as \"Function\",\n"
|
|
|
|
"SELECT t.typname as \"Result\", p.proname as \"Function\",\n"
|
|
|
|
" oid8types(p.proargtypes) as \"Arguments\"");
|
|
|
|
" oid8types(p.proargtypes) as \"Arguments\"");
|
|
|
|
if (verbose)
|
|
|
|
if (verbose)
|
|
|
|
strcat(buf, ",\n u.usename as \"Owner\", l.lanname as \"Language\", p.prosrc as \"Source\"");
|
|
|
|
strcat(buf, ",\n u.usename as \"Owner\", l.lanname as \"Language\", p.prosrc as \"Source\"");
|
|
|
|
if (desc)
|
|
|
|
if (desc)
|
|
|
|
strcat(buf, ",\n obj_description(p.oid) as \"Description\"");
|
|
|
|
strcat(buf, ",\n obj_description(p.oid) as \"Description\"");
|
|
|
|
|
|
|
|
|
|
|
|
if (!verbose)
|
|
|
|
if (!verbose)
|
|
|
|
strcat(buf,
|
|
|
|
strcat(buf,
|
|
|
|
"\nFROM pg_proc p, pg_type t\n"
|
|
|
|
"\nFROM pg_proc p, pg_type t\n"
|
|
|
|
"WHERE p.prorettype = t.oid and (pronargs = 0 or oid8types(p.proargtypes) != '')\n");
|
|
|
|
"WHERE p.prorettype = t.oid and (pronargs = 0 or oid8types(p.proargtypes) != '')\n");
|
|
|
|
else
|
|
|
|
else
|
|
|
|
strcat(buf,
|
|
|
|
strcat(buf,
|
|
|
|
"\nFROM pg_proc p, pg_type t, pg_language l, pg_user u\n"
|
|
|
|
"\nFROM pg_proc p, pg_type t, pg_language l, pg_user u\n"
|
|
|
|
"WHERE p.prorettype = t.oid AND p.prolang = l.oid AND p.proowner = u.usesysid\n"
|
|
|
|
"WHERE p.prorettype = t.oid AND p.prolang = l.oid AND p.proowner = u.usesysid\n"
|
|
|
|
" AND (pronargs = 0 or oid8types(p.proargtypes) != '')\n");
|
|
|
|
" AND (pronargs = 0 or oid8types(p.proargtypes) != '')\n");
|
|
|
|
|
|
|
|
|
|
|
|
if (name)
|
|
|
|
if (name)
|
|
|
|
{
|
|
|
|
{
|
|
|
@ -171,10 +171,10 @@ describeTypes(const char *name, PsqlSettings *pset, bool verbose, bool desc)
|
|
|
|
|
|
|
|
|
|
|
|
strcpy(buf, "SELECT t.typname AS \"Type\"");
|
|
|
|
strcpy(buf, "SELECT t.typname AS \"Type\"");
|
|
|
|
if (verbose)
|
|
|
|
if (verbose)
|
|
|
|
strcat(buf,
|
|
|
|
strcat(buf,
|
|
|
|
",\n (CASE WHEN t.typlen=-1 THEN 'var'::text ELSE t.typlen::text END) as \"Length\""
|
|
|
|
",\n (CASE WHEN t.typlen=-1 THEN 'var'::text ELSE t.typlen::text END) as \"Length\""
|
|
|
|
",\n u.usename as \"Owner\""
|
|
|
|
",\n u.usename as \"Owner\""
|
|
|
|
);
|
|
|
|
);
|
|
|
|
/*
|
|
|
|
/*
|
|
|
|
* Let's always show descriptions for this. There is room.
|
|
|
|
* Let's always show descriptions for this. There is room.
|
|
|
|
* bjm 1999/12/31
|
|
|
|
* bjm 1999/12/31
|
|
|
@ -185,11 +185,11 @@ describeTypes(const char *name, PsqlSettings *pset, bool verbose, bool desc)
|
|
|
|
* do not include user relations (typrelid!=0)
|
|
|
|
* do not include user relations (typrelid!=0)
|
|
|
|
*/
|
|
|
|
*/
|
|
|
|
strcat(buf, !verbose ?
|
|
|
|
strcat(buf, !verbose ?
|
|
|
|
("\nFROM pg_type t\n"
|
|
|
|
("\nFROM pg_type t\n"
|
|
|
|
"WHERE t.typrelid = 0 AND t.typname !~ '^_.*'\n") :
|
|
|
|
"WHERE t.typrelid = 0 AND t.typname !~ '^_.*'\n") :
|
|
|
|
("\nFROM pg_type t, pg_user u\n"
|
|
|
|
("\nFROM pg_type t, pg_user u\n"
|
|
|
|
"WHERE t.typrelid = 0 AND t.typname !~ '^_.*' AND t.typowner = u.usesysid\n")
|
|
|
|
"WHERE t.typrelid = 0 AND t.typname !~ '^_.*' AND t.typowner = u.usesysid\n")
|
|
|
|
);
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
|
|
if (name)
|
|
|
|
if (name)
|
|
|
|
{
|
|
|
|
{
|
|
|
@ -230,14 +230,14 @@ describeOperators(const char *name, PsqlSettings *pset, bool verbose, bool desc)
|
|
|
|
/* FIXME: Use outer joins here when ready */
|
|
|
|
/* FIXME: Use outer joins here when ready */
|
|
|
|
|
|
|
|
|
|
|
|
strcpy(buf,
|
|
|
|
strcpy(buf,
|
|
|
|
"SELECT o.oprname AS \"Op\",\n"
|
|
|
|
"SELECT o.oprname AS \"Op\",\n"
|
|
|
|
" t1.typname AS \"Left arg\",\n"
|
|
|
|
" t1.typname AS \"Left arg\",\n"
|
|
|
|
" t2.typname AS \"Right arg\",\n"
|
|
|
|
" t2.typname AS \"Right arg\",\n"
|
|
|
|
" t0.typname AS \"Result\"");
|
|
|
|
" t0.typname AS \"Result\"");
|
|
|
|
if (desc)
|
|
|
|
if (desc)
|
|
|
|
strcat(buf, ",\n obj_description(p.oid) as \"Description\"");
|
|
|
|
strcat(buf, ",\n obj_description(p.oid) as \"Description\"");
|
|
|
|
strcat(buf,
|
|
|
|
strcat(buf,
|
|
|
|
"\nFROM pg_proc p, pg_type t0,\n"
|
|
|
|
"\nFROM pg_proc p, pg_type t0,\n"
|
|
|
|
" pg_type t1, pg_type t2,\n"
|
|
|
|
" pg_type t1, pg_type t2,\n"
|
|
|
|
" pg_operator o\n"
|
|
|
|
" pg_operator o\n"
|
|
|
|
"WHERE p.prorettype = t0.oid AND\n"
|
|
|
|
"WHERE p.prorettype = t0.oid AND\n"
|
|
|
@ -319,7 +319,7 @@ listAllDbs(PsqlSettings *pset, bool desc)
|
|
|
|
printQueryOpt myopt = pset->popt;
|
|
|
|
printQueryOpt myopt = pset->popt;
|
|
|
|
|
|
|
|
|
|
|
|
strcpy(buf,
|
|
|
|
strcpy(buf,
|
|
|
|
"SELECT pg_database.datname as \"Database\",\n"
|
|
|
|
"SELECT pg_database.datname as \"Database\",\n"
|
|
|
|
" pg_user.usename as \"Owner\"");
|
|
|
|
" pg_user.usename as \"Owner\"");
|
|
|
|
#ifdef MULTIBYTE
|
|
|
|
#ifdef MULTIBYTE
|
|
|
|
strcat(buf,
|
|
|
|
strcat(buf,
|
|
|
@ -541,7 +541,7 @@ xmalloc(size_t size)
|
|
|
|
bool
|
|
|
|
bool
|
|
|
|
describeTableDetails(const char *name, PsqlSettings *pset, bool desc)
|
|
|
|
describeTableDetails(const char *name, PsqlSettings *pset, bool desc)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
char buf[512 + 8 * NAMEDATALEN];
|
|
|
|
char buf[512 + INDEX_MAX_KEYS * NAMEDATALEN];
|
|
|
|
PGresult *res = NULL;
|
|
|
|
PGresult *res = NULL;
|
|
|
|
printTableOpt myopt = pset->popt.topt;
|
|
|
|
printTableOpt myopt = pset->popt.topt;
|
|
|
|
int i;
|
|
|
|
int i;
|
|
|
@ -557,20 +557,20 @@ describeTableDetails(const char *name, PsqlSettings *pset, bool desc)
|
|
|
|
|
|
|
|
|
|
|
|
/* truncate table name */
|
|
|
|
/* truncate table name */
|
|
|
|
if (strlen(name) > NAMEDATALEN) {
|
|
|
|
if (strlen(name) > NAMEDATALEN) {
|
|
|
|
char *my_name = xmalloc(NAMEDATALEN+1);
|
|
|
|
char *my_name = xmalloc(NAMEDATALEN+1);
|
|
|
|
strncpy(my_name, name, NAMEDATALEN);
|
|
|
|
strncpy(my_name, name, NAMEDATALEN);
|
|
|
|
my_name[NAMEDATALEN] = '\0';
|
|
|
|
my_name[NAMEDATALEN] = '\0';
|
|
|
|
name = my_name;
|
|
|
|
name = my_name;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/* Get general table info */
|
|
|
|
/* Get general table info */
|
|
|
|
sprintf(buf,
|
|
|
|
sprintf(buf,
|
|
|
|
"SELECT relhasindex, relkind, relchecks, reltriggers, relhasrules\n"
|
|
|
|
"SELECT relhasindex, relkind, relchecks, reltriggers, relhasrules\n"
|
|
|
|
"FROM pg_class WHERE relname='%s'",
|
|
|
|
"FROM pg_class WHERE relname='%s'",
|
|
|
|
name);
|
|
|
|
name);
|
|
|
|
res = PSQLexec(pset, buf);
|
|
|
|
res = PSQLexec(pset, buf);
|
|
|
|
if (!res)
|
|
|
|
if (!res)
|
|
|
|
return false;
|
|
|
|
return false;
|
|
|
|
|
|
|
|
|
|
|
|
/* Did we get anything? */
|
|
|
|
/* Did we get anything? */
|
|
|
|
if (PQntuples(res) == 0)
|
|
|
|
if (PQntuples(res) == 0)
|
|
|
@ -596,13 +596,13 @@ describeTableDetails(const char *name, PsqlSettings *pset, bool desc)
|
|
|
|
|
|
|
|
|
|
|
|
if (tableinfo.relkind == 'r' || tableinfo.relkind == 's')
|
|
|
|
if (tableinfo.relkind == 'r' || tableinfo.relkind == 's')
|
|
|
|
{
|
|
|
|
{
|
|
|
|
cols++;
|
|
|
|
cols++;
|
|
|
|
headers[cols-1] = "Extra";
|
|
|
|
headers[cols-1] = "Extra";
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if (desc)
|
|
|
|
if (desc)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
cols++;
|
|
|
|
cols++;
|
|
|
|
headers[cols-1] = "Description";
|
|
|
|
headers[cols-1] = "Description";
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
@ -625,19 +625,19 @@ describeTableDetails(const char *name, PsqlSettings *pset, bool desc)
|
|
|
|
|
|
|
|
|
|
|
|
/* Check if table is a view */
|
|
|
|
/* Check if table is a view */
|
|
|
|
if (tableinfo.hasrules) {
|
|
|
|
if (tableinfo.hasrules) {
|
|
|
|
PGresult *result;
|
|
|
|
PGresult *result;
|
|
|
|
sprintf(buf, "SELECT definition FROM pg_views WHERE viewname = '%s'", name);
|
|
|
|
sprintf(buf, "SELECT definition FROM pg_views WHERE viewname = '%s'", name);
|
|
|
|
result = PSQLexec(pset, buf);
|
|
|
|
result = PSQLexec(pset, buf);
|
|
|
|
if (!result)
|
|
|
|
if (!result)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
PQclear(res);
|
|
|
|
PQclear(res);
|
|
|
|
PQclear(result);
|
|
|
|
PQclear(result);
|
|
|
|
return false;
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if (PQntuples(result) > 0)
|
|
|
|
if (PQntuples(result) > 0)
|
|
|
|
view_def = xstrdup(PQgetvalue(result, 0, 0));
|
|
|
|
view_def = xstrdup(PQgetvalue(result, 0, 0));
|
|
|
|
PQclear(result);
|
|
|
|
PQclear(result);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@ -654,7 +654,7 @@ describeTableDetails(const char *name, PsqlSettings *pset, bool desc)
|
|
|
|
cells[i * cols + 0] = (char *)PQgetvalue(res, i, 0); /* don't free this afterwards */
|
|
|
|
cells[i * cols + 0] = (char *)PQgetvalue(res, i, 0); /* don't free this afterwards */
|
|
|
|
|
|
|
|
|
|
|
|
/* Type */
|
|
|
|
/* Type */
|
|
|
|
/* (convert some internal type names to "readable") */
|
|
|
|
/* (convert some internal type names to "readable") */
|
|
|
|
cells[i * cols + 1] = xmalloc(NAMEDATALEN + 16);
|
|
|
|
cells[i * cols + 1] = xmalloc(NAMEDATALEN + 16);
|
|
|
|
if (strcmp(attype, "bpchar") == 0)
|
|
|
|
if (strcmp(attype, "bpchar") == 0)
|
|
|
|
sprintf(cells[i * cols + 1], "char(%d)", attypmod != -1 ? attypmod - VARHDRSZ : 0);
|
|
|
|
sprintf(cells[i * cols + 1], "char(%d)", attypmod != -1 ? attypmod - VARHDRSZ : 0);
|
|
|
@ -671,38 +671,38 @@ describeTableDetails(const char *name, PsqlSettings *pset, bool desc)
|
|
|
|
|
|
|
|
|
|
|
|
/* Extra: not null and default */
|
|
|
|
/* Extra: not null and default */
|
|
|
|
/* (I'm cutting off the 'default' string at 128) */
|
|
|
|
/* (I'm cutting off the 'default' string at 128) */
|
|
|
|
if (tableinfo.relkind == 'r' || tableinfo.relkind == 's')
|
|
|
|
if (tableinfo.relkind == 'r' || tableinfo.relkind == 's')
|
|
|
|
{
|
|
|
|
{
|
|
|
|
cells[i * cols + 2] = xmalloc(128 + 128);
|
|
|
|
cells[i * cols + 2] = xmalloc(128 + 128);
|
|
|
|
cells[i * cols + 2][0] = '\0';
|
|
|
|
cells[i * cols + 2][0] = '\0';
|
|
|
|
if (strcmp(PQgetvalue(res, i, 4), "t") == 0)
|
|
|
|
if (strcmp(PQgetvalue(res, i, 4), "t") == 0)
|
|
|
|
strcat(cells[i * cols + 2], "not null");
|
|
|
|
strcat(cells[i * cols + 2], "not null");
|
|
|
|
|
|
|
|
|
|
|
|
/* handle "default" here */
|
|
|
|
/* handle "default" here */
|
|
|
|
if (strcmp(PQgetvalue(res, i, 5), "t") == 0)
|
|
|
|
if (strcmp(PQgetvalue(res, i, 5), "t") == 0)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
PGresult *result;
|
|
|
|
PGresult *result;
|
|
|
|
|
|
|
|
|
|
|
|
sprintf(buf, "SELECT substring(d.adsrc for 128) FROM pg_attrdef d, pg_class c\n"
|
|
|
|
sprintf(buf, "SELECT substring(d.adsrc for 128) FROM pg_attrdef d, pg_class c\n"
|
|
|
|
"WHERE c.relname = '%s' AND c.oid = d.adrelid AND d.adnum = %s",
|
|
|
|
"WHERE c.relname = '%s' AND c.oid = d.adrelid AND d.adnum = %s",
|
|
|
|
name, PQgetvalue(res, i, 6));
|
|
|
|
name, PQgetvalue(res, i, 6));
|
|
|
|
|
|
|
|
|
|
|
|
result = PSQLexec(pset, buf);
|
|
|
|
result = PSQLexec(pset, buf);
|
|
|
|
if (!result)
|
|
|
|
if (!result)
|
|
|
|
error = true;
|
|
|
|
error = true;
|
|
|
|
else
|
|
|
|
else
|
|
|
|
{
|
|
|
|
{
|
|
|
|
if (cells[i * cols + 2][0])
|
|
|
|
if (cells[i * cols + 2][0])
|
|
|
|
strcat(cells[i * cols + 2], " ");
|
|
|
|
strcat(cells[i * cols + 2], " ");
|
|
|
|
strcat(cells[i * cols + 2], "default ");
|
|
|
|
strcat(cells[i * cols + 2], "default ");
|
|
|
|
strcat(cells[i * cols + 2], PQgetvalue(result, 0, 0));
|
|
|
|
strcat(cells[i * cols + 2], PQgetvalue(result, 0, 0));
|
|
|
|
PQclear(result);
|
|
|
|
PQclear(result);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if (error)
|
|
|
|
if (error)
|
|
|
|
break;
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
|
|
/* Description */
|
|
|
|
/* Description */
|
|
|
|
if (desc)
|
|
|
|
if (desc)
|
|
|
@ -713,50 +713,50 @@ describeTableDetails(const char *name, PsqlSettings *pset, bool desc)
|
|
|
|
title = xmalloc(20 + strlen(name));
|
|
|
|
title = xmalloc(20 + strlen(name));
|
|
|
|
switch (tableinfo.relkind) {
|
|
|
|
switch (tableinfo.relkind) {
|
|
|
|
case 'r':
|
|
|
|
case 'r':
|
|
|
|
if (view_def)
|
|
|
|
if (view_def)
|
|
|
|
sprintf(title, "View \"%s\"", name);
|
|
|
|
sprintf(title, "View \"%s\"", name);
|
|
|
|
else
|
|
|
|
else
|
|
|
|
sprintf(title, "Table \"%s\"", name);
|
|
|
|
sprintf(title, "Table \"%s\"", name);
|
|
|
|
break;
|
|
|
|
break;
|
|
|
|
case 'S':
|
|
|
|
case 'S':
|
|
|
|
sprintf(title, "Sequence \"%s\"", name);
|
|
|
|
sprintf(title, "Sequence \"%s\"", name);
|
|
|
|
break;
|
|
|
|
break;
|
|
|
|
case 'i':
|
|
|
|
case 'i':
|
|
|
|
sprintf(title, "Index \"%s\"", name);
|
|
|
|
sprintf(title, "Index \"%s\"", name);
|
|
|
|
break;
|
|
|
|
break;
|
|
|
|
case 's':
|
|
|
|
case 's':
|
|
|
|
sprintf(title, "System table \"%s\"", name);
|
|
|
|
sprintf(title, "System table \"%s\"", name);
|
|
|
|
break;
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
default:
|
|
|
|
sprintf(title, "?%c?", tableinfo.relkind);
|
|
|
|
sprintf(title, "?%c?", tableinfo.relkind);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/* Make footers */
|
|
|
|
/* Make footers */
|
|
|
|
/* Information about the index */
|
|
|
|
/* Information about the index */
|
|
|
|
if (tableinfo.relkind == 'i')
|
|
|
|
if (tableinfo.relkind == 'i')
|
|
|
|
{
|
|
|
|
{
|
|
|
|
PGresult * result;
|
|
|
|
PGresult * result;
|
|
|
|
|
|
|
|
|
|
|
|
sprintf(buf, "SELECT i.indisunique, i.indisprimary, a.amname\n"
|
|
|
|
sprintf(buf, "SELECT i.indisunique, i.indisprimary, a.amname\n"
|
|
|
|
"FROM pg_index i, pg_class c, pg_am a\n"
|
|
|
|
"FROM pg_index i, pg_class c, pg_am a\n"
|
|
|
|
"WHERE i.indexrelid = c.oid AND c.relname = '%s' AND c.relam = a.oid",
|
|
|
|
"WHERE i.indexrelid = c.oid AND c.relname = '%s' AND c.relam = a.oid",
|
|
|
|
name);
|
|
|
|
name);
|
|
|
|
|
|
|
|
|
|
|
|
result = PSQLexec(pset, buf);
|
|
|
|
result = PSQLexec(pset, buf);
|
|
|
|
if (!result)
|
|
|
|
if (!result)
|
|
|
|
error = true;
|
|
|
|
error = true;
|
|
|
|
else
|
|
|
|
else
|
|
|
|
{
|
|
|
|
{
|
|
|
|
footers = xmalloc(2 * sizeof(*footers));
|
|
|
|
footers = xmalloc(2 * sizeof(*footers));
|
|
|
|
footers[0] = xmalloc(NAMEDATALEN + 32);
|
|
|
|
footers[0] = xmalloc(NAMEDATALEN + 32);
|
|
|
|
sprintf(footers[0], "%s%s",
|
|
|
|
sprintf(footers[0], "%s%s",
|
|
|
|
strcmp(PQgetvalue(result, 0, 0), "t")==0 ? "unique " : "",
|
|
|
|
strcmp(PQgetvalue(result, 0, 0), "t")==0 ? "unique " : "",
|
|
|
|
PQgetvalue(result, 0, 2)
|
|
|
|
PQgetvalue(result, 0, 2)
|
|
|
|
);
|
|
|
|
);
|
|
|
|
if (strcmp(PQgetvalue(result, 0, 1), "t")==0)
|
|
|
|
if (strcmp(PQgetvalue(result, 0, 1), "t")==0)
|
|
|
|
strcat(footers[0], " (primary key)");
|
|
|
|
strcat(footers[0], " (primary key)");
|
|
|
|
footers[1] = NULL;
|
|
|
|
footers[1] = NULL;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
/* Information about the view */
|
|
|
|
/* Information about the view */
|
|
|
|
else if (tableinfo.relkind == 'r' && view_def)
|
|
|
|
else if (tableinfo.relkind == 'r' && view_def)
|
|
|
@ -770,132 +770,132 @@ describeTableDetails(const char *name, PsqlSettings *pset, bool desc)
|
|
|
|
/* Information about the table */
|
|
|
|
/* Information about the table */
|
|
|
|
else if (tableinfo.relkind == 'r')
|
|
|
|
else if (tableinfo.relkind == 'r')
|
|
|
|
{
|
|
|
|
{
|
|
|
|
PGresult *result1=NULL, *result2=NULL, *result3=NULL, *result4=NULL;
|
|
|
|
PGresult *result1=NULL, *result2=NULL, *result3=NULL, *result4=NULL;
|
|
|
|
int index_count=0, constr_count=0, rule_count=0, trigger_count=0;
|
|
|
|
int index_count=0, constr_count=0, rule_count=0, trigger_count=0;
|
|
|
|
int count_footers=0;
|
|
|
|
int count_footers=0;
|
|
|
|
|
|
|
|
|
|
|
|
/* count indices */
|
|
|
|
/* count indices */
|
|
|
|
if (!error && tableinfo.hasindex)
|
|
|
|
if (!error && tableinfo.hasindex)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
sprintf(buf, "SELECT c2.relname\n"
|
|
|
|
sprintf(buf, "SELECT c2.relname\n"
|
|
|
|
"FROM pg_class c, pg_class c2, pg_index i\n"
|
|
|
|
"FROM pg_class c, pg_class c2, pg_index i\n"
|
|
|
|
"WHERE c.relname = '%s' AND c.oid = i.indrelid AND i.indexrelid = c2.oid\n"
|
|
|
|
"WHERE c.relname = '%s' AND c.oid = i.indrelid AND i.indexrelid = c2.oid\n"
|
|
|
|
"ORDER BY c2.relname",
|
|
|
|
"ORDER BY c2.relname",
|
|
|
|
name);
|
|
|
|
name);
|
|
|
|
result1 = PSQLexec(pset, buf);
|
|
|
|
result1 = PSQLexec(pset, buf);
|
|
|
|
if (!result1)
|
|
|
|
if (!result1)
|
|
|
|
error = true;
|
|
|
|
error = true;
|
|
|
|
else
|
|
|
|
else
|
|
|
|
index_count = PQntuples(result1);
|
|
|
|
index_count = PQntuples(result1);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/* count table (and column) constraints */
|
|
|
|
/* count table (and column) constraints */
|
|
|
|
if (!error && tableinfo.checks)
|
|
|
|
if (!error && tableinfo.checks)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
sprintf(buf, "SELECT rcsrc\n"
|
|
|
|
sprintf(buf, "SELECT rcsrc\n"
|
|
|
|
"FROM pg_relcheck r, pg_class c\n"
|
|
|
|
"FROM pg_relcheck r, pg_class c\n"
|
|
|
|
"WHERE c.relname='%s' AND c.oid = r.rcrelid",
|
|
|
|
"WHERE c.relname='%s' AND c.oid = r.rcrelid",
|
|
|
|
name);
|
|
|
|
name);
|
|
|
|
result2 = PSQLexec(pset, buf);
|
|
|
|
result2 = PSQLexec(pset, buf);
|
|
|
|
if (!result2)
|
|
|
|
if (!result2)
|
|
|
|
error = true;
|
|
|
|
error = true;
|
|
|
|
else
|
|
|
|
else
|
|
|
|
constr_count = PQntuples(result2);
|
|
|
|
constr_count = PQntuples(result2);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/* count rules */
|
|
|
|
/* count rules */
|
|
|
|
if (!error && tableinfo.hasrules)
|
|
|
|
if (!error && tableinfo.hasrules)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
sprintf(buf,
|
|
|
|
sprintf(buf,
|
|
|
|
"SELECT r.rulename\n"
|
|
|
|
"SELECT r.rulename\n"
|
|
|
|
"FROM pg_rewrite r, pg_class c\n"
|
|
|
|
"FROM pg_rewrite r, pg_class c\n"
|
|
|
|
"WHERE c.relname='%s' AND c.oid = r.ev_class",
|
|
|
|
"WHERE c.relname='%s' AND c.oid = r.ev_class",
|
|
|
|
name);
|
|
|
|
name);
|
|
|
|
result3 = PSQLexec(pset, buf);
|
|
|
|
result3 = PSQLexec(pset, buf);
|
|
|
|
if (!result3)
|
|
|
|
if (!result3)
|
|
|
|
error = true;
|
|
|
|
error = true;
|
|
|
|
else
|
|
|
|
else
|
|
|
|
rule_count = PQntuples(result3);
|
|
|
|
rule_count = PQntuples(result3);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/* count triggers */
|
|
|
|
/* count triggers */
|
|
|
|
if (!error && tableinfo.hasrules)
|
|
|
|
if (!error && tableinfo.hasrules)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
sprintf(buf,
|
|
|
|
sprintf(buf,
|
|
|
|
"SELECT t.tgname\n"
|
|
|
|
"SELECT t.tgname\n"
|
|
|
|
"FROM pg_trigger t, pg_class c\n"
|
|
|
|
"FROM pg_trigger t, pg_class c\n"
|
|
|
|
"WHERE c.relname='%s' AND c.oid = t.tgrelid",
|
|
|
|
"WHERE c.relname='%s' AND c.oid = t.tgrelid",
|
|
|
|
name);
|
|
|
|
name);
|
|
|
|
result4 = PSQLexec(pset, buf);
|
|
|
|
result4 = PSQLexec(pset, buf);
|
|
|
|
if (!result4)
|
|
|
|
if (!result4)
|
|
|
|
error = true;
|
|
|
|
error = true;
|
|
|
|
else
|
|
|
|
else
|
|
|
|
trigger_count = PQntuples(result4);
|
|
|
|
trigger_count = PQntuples(result4);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
footers = xmalloc((index_count + constr_count + rule_count + trigger_count + 1) * sizeof(*footers));
|
|
|
|
footers = xmalloc((index_count + constr_count + rule_count + trigger_count + 1) * sizeof(*footers));
|
|
|
|
|
|
|
|
|
|
|
|
/* print indices */
|
|
|
|
/* print indices */
|
|
|
|
for (i = 0; i < index_count; i++)
|
|
|
|
for (i = 0; i < index_count; i++)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
sprintf(buf, "%s %s",
|
|
|
|
sprintf(buf, "%s %s",
|
|
|
|
index_count==1 ? "Index:" : (i==0 ? "Indices:" : " "),
|
|
|
|
index_count==1 ? "Index:" : (i==0 ? "Indices:" : " "),
|
|
|
|
PQgetvalue(result1, i, 0)
|
|
|
|
PQgetvalue(result1, i, 0)
|
|
|
|
);
|
|
|
|
);
|
|
|
|
if (i < index_count-1)
|
|
|
|
if (i < index_count-1)
|
|
|
|
strcat(buf, ",");
|
|
|
|
strcat(buf, ",");
|
|
|
|
|
|
|
|
|
|
|
|
footers[count_footers++] = xstrdup(buf);
|
|
|
|
footers[count_footers++] = xstrdup(buf);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/* print contraints */
|
|
|
|
/* print contraints */
|
|
|
|
for (i = 0; i < constr_count; i++)
|
|
|
|
for (i = 0; i < constr_count; i++)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
sprintf(buf, "%s %s",
|
|
|
|
sprintf(buf, "%s %s",
|
|
|
|
constr_count==1 ? "Constraint:" : (i==0 ? "Constraints:" : " "),
|
|
|
|
constr_count==1 ? "Constraint:" : (i==0 ? "Constraints:" : " "),
|
|
|
|
PQgetvalue(result2, i, 0)
|
|
|
|
PQgetvalue(result2, i, 0)
|
|
|
|
);
|
|
|
|
);
|
|
|
|
footers[count_footers++] = xstrdup(buf);
|
|
|
|
footers[count_footers++] = xstrdup(buf);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/* print rules */
|
|
|
|
/* print rules */
|
|
|
|
for (i = 0; i < rule_count; i++)
|
|
|
|
for (i = 0; i < rule_count; i++)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
sprintf(buf, "%s %s",
|
|
|
|
sprintf(buf, "%s %s",
|
|
|
|
rule_count==1 ? "Rule:" : (i==0 ? "Rules:" : " "),
|
|
|
|
rule_count==1 ? "Rule:" : (i==0 ? "Rules:" : " "),
|
|
|
|
PQgetvalue(result3, i, 0)
|
|
|
|
PQgetvalue(result3, i, 0)
|
|
|
|
);
|
|
|
|
);
|
|
|
|
if (i < rule_count-1)
|
|
|
|
if (i < rule_count-1)
|
|
|
|
strcat(buf, ",");
|
|
|
|
strcat(buf, ",");
|
|
|
|
|
|
|
|
|
|
|
|
footers[count_footers++] = xstrdup(buf);
|
|
|
|
footers[count_footers++] = xstrdup(buf);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/* print triggers */
|
|
|
|
/* print triggers */
|
|
|
|
for (i = 0; i < trigger_count; i++)
|
|
|
|
for (i = 0; i < trigger_count; i++)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
sprintf(buf, "%s %s",
|
|
|
|
sprintf(buf, "%s %s",
|
|
|
|
trigger_count==1 ? "Trigger:" : (i==0 ? "Triggers:" : " "),
|
|
|
|
trigger_count==1 ? "Trigger:" : (i==0 ? "Triggers:" : " "),
|
|
|
|
PQgetvalue(result4, i, 0)
|
|
|
|
PQgetvalue(result4, i, 0)
|
|
|
|
);
|
|
|
|
);
|
|
|
|
if (i < trigger_count-1)
|
|
|
|
if (i < trigger_count-1)
|
|
|
|
strcat(buf, ",");
|
|
|
|
strcat(buf, ",");
|
|
|
|
|
|
|
|
|
|
|
|
footers[count_footers++] = xstrdup(buf);
|
|
|
|
footers[count_footers++] = xstrdup(buf);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/* end of list marker */
|
|
|
|
/* end of list marker */
|
|
|
|
footers[count_footers] = NULL;
|
|
|
|
footers[count_footers] = NULL;
|
|
|
|
|
|
|
|
|
|
|
|
PQclear(result1);
|
|
|
|
PQclear(result1);
|
|
|
|
PQclear(result2);
|
|
|
|
PQclear(result2);
|
|
|
|
PQclear(result3);
|
|
|
|
PQclear(result3);
|
|
|
|
PQclear(result4);
|
|
|
|
PQclear(result4);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if (!error) {
|
|
|
|
if (!error) {
|
|
|
|
myopt.tuples_only = false;
|
|
|
|
myopt.tuples_only = false;
|
|
|
|
printTable(title, headers, (const char**)cells, (const char**)footers, "llll", &myopt, pset->queryFout);
|
|
|
|
printTable(title, headers, (const char**)cells, (const char**)footers, "llll", &myopt, pset->queryFout);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/* clean up */
|
|
|
|
/* clean up */
|
|
|
@ -904,8 +904,8 @@ describeTableDetails(const char *name, PsqlSettings *pset, bool desc)
|
|
|
|
for (i = 0; i < PQntuples(res); i++)
|
|
|
|
for (i = 0; i < PQntuples(res); i++)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
free(cells[i * cols + 1]);
|
|
|
|
free(cells[i * cols + 1]);
|
|
|
|
if (tableinfo.relkind == 'r' || tableinfo.relkind == 's')
|
|
|
|
if (tableinfo.relkind == 'r' || tableinfo.relkind == 's')
|
|
|
|
free(cells[i * cols + 2]);
|
|
|
|
free(cells[i * cols + 2]);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
free(cells);
|
|
|
|
free(cells);
|
|
|
|
|
|
|
|
|
|
|
@ -994,10 +994,10 @@ listTables(const char *infotype, const char *name, PsqlSettings *pset, bool desc
|
|
|
|
strcat(buf, "\nUNION\n\n");
|
|
|
|
strcat(buf, "\nUNION\n\n");
|
|
|
|
|
|
|
|
|
|
|
|
strcat(buf,
|
|
|
|
strcat(buf,
|
|
|
|
"SELECT c.relname as \"Name\",\n"
|
|
|
|
"SELECT c.relname as \"Name\",\n"
|
|
|
|
" (CASE WHEN relkind = 'S' THEN 'sequence'::text ELSE 'index'::text END) as \"Type\",\n"
|
|
|
|
" (CASE WHEN relkind = 'S' THEN 'sequence'::text ELSE 'index'::text END) as \"Type\",\n"
|
|
|
|
" u.usename as \"Owner\""
|
|
|
|
" u.usename as \"Owner\""
|
|
|
|
);
|
|
|
|
);
|
|
|
|
if (desc)
|
|
|
|
if (desc)
|
|
|
|
strcat(buf, ", obj_description(c.oid) as \"Description\"");
|
|
|
|
strcat(buf, ", obj_description(c.oid) as \"Description\"");
|
|
|
|
strcat(buf, "\nFROM pg_class c, pg_user u\n"
|
|
|
|
strcat(buf, "\nFROM pg_class c, pg_user u\n"
|
|
|
|