diff options
Diffstat (limited to 'src/bin')
-rw-r--r-- | src/bin/pg_dump/common.c | 589 | ||||
-rw-r--r-- | src/bin/pg_dump/pg_dump.c | 4050 | ||||
-rw-r--r-- | src/bin/pg_dump/pg_dump.h | 368 | ||||
-rw-r--r-- | src/bin/pg_id/pg_id.c | 62 | ||||
-rw-r--r-- | src/bin/pg_passwd/pg_passwd.c | 553 | ||||
-rw-r--r-- | src/bin/pg_version/pg_version.c | 41 | ||||
-rw-r--r-- | src/bin/pgtclsh/pgtclAppInit.c | 111 | ||||
-rw-r--r-- | src/bin/pgtclsh/pgtkAppInit.c | 117 | ||||
-rw-r--r-- | src/bin/psql/psql.c | 3771 | ||||
-rw-r--r-- | src/bin/psql/psqlHelp.h | 338 | ||||
-rw-r--r-- | src/bin/psql/stringutils.c | 116 | ||||
-rw-r--r-- | src/bin/psql/stringutils.h | 11 |
12 files changed, 5441 insertions, 4686 deletions
diff --git a/src/bin/pg_dump/common.c b/src/bin/pg_dump/common.c index 15729fe7b3a..c8d3c755b6f 100644 --- a/src/bin/pg_dump/common.c +++ b/src/bin/pg_dump/common.c @@ -1,19 +1,19 @@ /*------------------------------------------------------------------------- * * common.c-- - * common routines between pg_dump and pg4_dump + * common routines between pg_dump and pg4_dump * * Copyright (c) 1994, Regents of the University of California * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/bin/pg_dump/common.c,v 1.13 1997/08/19 21:36:25 momjian Exp $ + * $Header: /cvsroot/pgsql/src/bin/pg_dump/common.c,v 1.14 1997/09/07 04:54:28 momjian Exp $ * * Modifications - 6/12/96 - dave@bensoft.com - version 1.13.dhb.2 * - * - Fixed dumpTable output to output lengths for char and varchar types! - * - Added single. quote to twin single quote expansion for 'insert' string - * mode. + * - Fixed dumpTable output to output lengths for char and varchar types! + * - Added single. quote to twin single quote expansion for 'insert' string + * mode. * *------------------------------------------------------------------------- */ @@ -22,9 +22,9 @@ #include <stdlib.h> #include <stdio.h> #include <string.h> -#include <sys/param.h> /* for MAXHOSTNAMELEN on most */ +#include <sys/param.h> /* for MAXHOSTNAMELEN on most */ #ifdef sparc_solaris -#include <netdb.h> /* for MAXHOSTNAMELEN on some */ +#include <netdb.h> /* for MAXHOSTNAMELEN on some */ #endif #include "postgres.h" @@ -35,391 +35,446 @@ #include "pg_dump.h" -static char** findParentsByOid(TableInfo* tbinfo, int numTables, - InhInfo* inhinfo, int numInherits, - const char *oid, - int *numParents); -static int findTableByOid(TableInfo *tbinfo, int numTables, const char *oid); -static void flagInhAttrs(TableInfo* tbinfo, int numTables, - InhInfo* inhinfo, int numInherits); -static int strInArray(const char* pattern, char** arr, int arr_size); +static char ** +findParentsByOid(TableInfo * tbinfo, int numTables, + InhInfo * inhinfo, int numInherits, + const char *oid, + int *numParents); +static int findTableByOid(TableInfo * tbinfo, int numTables, const char *oid); +static void +flagInhAttrs(TableInfo * tbinfo, int numTables, + InhInfo * inhinfo, int numInherits); +static int strInArray(const char *pattern, char **arr, int arr_size); /* - * findTypeByOid - * given an oid of a type, return its typename + * findTypeByOid + * given an oid of a type, return its typename * * if oid is "0", return "opaque" -- this is a special case * * NOTE: should hash this, but just do linear search for now */ -char* -findTypeByOid(TypeInfo* tinfo, int numTypes, const char* oid) +char * +findTypeByOid(TypeInfo * tinfo, int numTypes, const char *oid) { - int i; + int i; - if (strcmp(oid, "0") == 0) return g_opaque_type; + if (strcmp(oid, "0") == 0) + return g_opaque_type; - for (i=0;i<numTypes;i++) { - if (strcmp(tinfo[i].oid, oid) == 0) - return tinfo[i].typname; - } + for (i = 0; i < numTypes; i++) + { + if (strcmp(tinfo[i].oid, oid) == 0) + return tinfo[i].typname; + } - /* should never get here */ - fprintf(stderr,"failed sanity check, type with oid %s was not found\n", - oid); - exit(2); + /* should never get here */ + fprintf(stderr, "failed sanity check, type with oid %s was not found\n", + oid); + exit(2); } /* * findOprByOid - * given the oid of an operator, return the name of the operator + * given the oid of an operator, return the name of the operator * * * NOTE: should hash this, but just do linear search for now - * + * */ -char* -findOprByOid(OprInfo *oprinfo, int numOprs, const char *oid) +char * +findOprByOid(OprInfo * oprinfo, int numOprs, const char *oid) { - int i; - for (i=0;i<numOprs;i++) { - if (strcmp(oprinfo[i].oid, oid) == 0) - return oprinfo[i].oprname; - } - - /* should never get here */ - fprintf(stderr,"failed sanity check, opr with oid %s was not found\n", - oid); - exit(2); + int i; + + for (i = 0; i < numOprs; i++) + { + if (strcmp(oprinfo[i].oid, oid) == 0) + return oprinfo[i].oprname; + } + + /* should never get here */ + fprintf(stderr, "failed sanity check, opr with oid %s was not found\n", + oid); + exit(2); } /* * findParentsByOid -- - * given the oid of a class, return the names of its parent classes + * given the oid of a class, return the names of its parent classes * and assign the number of parents to the last argument. * * * returns NULL if none */ -static char** -findParentsByOid(TableInfo* tblinfo, int numTables, - InhInfo* inhinfo, int numInherits, const char *oid, - int *numParentsPtr) +static char ** +findParentsByOid(TableInfo * tblinfo, int numTables, + InhInfo * inhinfo, int numInherits, const char *oid, + int *numParentsPtr) { - int i,j; - int parentInd; - char** result; - int numParents; - - numParents = 0; - for (i=0;i<numInherits;i++) { - if ( strcmp(inhinfo[i].inhrel, oid) == 0) { - numParents++; + int i, + j; + int parentInd; + char **result; + int numParents; + + numParents = 0; + for (i = 0; i < numInherits; i++) + { + if (strcmp(inhinfo[i].inhrel, oid) == 0) + { + numParents++; + } } - } - - *numParentsPtr = numParents; - if (numParents > 0) { - result = (char**)malloc(sizeof(char*) * numParents); - j = 0; - for (i=0;i<numInherits;i++) { - if ( strcmp(inhinfo[i].inhrel, oid) == 0) { - parentInd = findTableByOid(tblinfo, numTables, - inhinfo[i].inhparent); - result[j++] = tblinfo[parentInd].relname; - } + *numParentsPtr = numParents; + + if (numParents > 0) + { + result = (char **) malloc(sizeof(char *) * numParents); + j = 0; + for (i = 0; i < numInherits; i++) + { + if (strcmp(inhinfo[i].inhrel, oid) == 0) + { + parentInd = findTableByOid(tblinfo, numTables, + inhinfo[i].inhparent); + result[j++] = tblinfo[parentInd].relname; + } + } + return result; } - return result; - } - else - return NULL; + else + return NULL; } /* * parseArgTypes - * parse a string of eight numbers delimited by spaces + * parse a string of eight numbers delimited by spaces * into a character array */ -void -parseArgTypes(char **argtypes, const char* str) +void +parseArgTypes(char **argtypes, const char *str) { - int j, argNum; - char temp[100]; - char s; - - argNum = 0; - j = 0; - while ( (s = *str) != '\0') { - if (s == ' ') { - temp[j] = '\0'; - argtypes[argNum] = strdup(temp); - argNum++; - j = 0; - } else { - temp[j] = s; - j++; + int j, + argNum; + char temp[100]; + char s; + + argNum = 0; + j = 0; + while ((s = *str) != '\0') + { + if (s == ' ') + { + temp[j] = '\0'; + argtypes[argNum] = strdup(temp); + argNum++; + j = 0; + } + else + { + temp[j] = s; + j++; + } + str++; + } + if (j != 0) + { + temp[j] = '\0'; + argtypes[argNum] = strdup(temp); } - str++; - } - if (j != 0) { - temp[j] = '\0'; - argtypes[argNum] = strdup(temp); - } - + } /* * strInArray: - * takes in a string and a string array and the number of elements in the - * string array. - * returns the index if the string is somewhere in the array, -1 otherwise + * takes in a string and a string array and the number of elements in the + * string array. + * returns the index if the string is somewhere in the array, -1 otherwise * */ -static int -strInArray(const char* pattern, char** arr, int arr_size) +static int +strInArray(const char *pattern, char **arr, int arr_size) { - int i; - for (i=0;i<arr_size;i++) { - if (strcmp(pattern, arr[i]) == 0) - return i; - } - return -1; + int i; + + for (i = 0; i < arr_size; i++) + { + if (strcmp(pattern, arr[i]) == 0) + return i; + } + return -1; } /* * dumpSchema: - * we have a valid connection, we are now going to dump the schema + * we have a valid connection, we are now going to dump the schema * into the file * */ -TableInfo * -dumpSchema(FILE *fout, - int *numTablesPtr, - const char *tablename, - const bool acls) +TableInfo * +dumpSchema(FILE * fout, + int *numTablesPtr, + const char *tablename, + const bool acls) { - int numTypes; - int numFuncs; - int numTables; - int numInherits; - int numAggregates; - int numOperators; - TypeInfo *tinfo=NULL; - FuncInfo *finfo=NULL; - AggInfo *agginfo=NULL; - TableInfo *tblinfo=NULL; - InhInfo *inhinfo=NULL; - OprInfo *oprinfo=NULL; - -if (g_verbose) fprintf(stderr,"%s reading user-defined types %s\n", - g_comment_start, g_comment_end); - tinfo = getTypes(&numTypes); - -if (g_verbose) fprintf(stderr,"%s reading user-defined functions %s\n", - g_comment_start, g_comment_end); - finfo = getFuncs(&numFuncs); - -if (g_verbose) fprintf(stderr,"%s reading user-defined aggregates %s\n", - g_comment_start, g_comment_end); - agginfo = getAggregates(&numAggregates); - -if (g_verbose) fprintf(stderr,"%s reading user-defined operators %s\n", - g_comment_start, g_comment_end); - oprinfo = getOperators(&numOperators); - -if (g_verbose) fprintf(stderr,"%s reading user-defined tables %s\n", - g_comment_start, g_comment_end); - tblinfo = getTables(&numTables); - -if (g_verbose) fprintf(stderr,"%s reading table inheritance information %s\n", - g_comment_start, g_comment_end); - inhinfo = getInherits(&numInherits); - -if (g_verbose) fprintf(stderr, "%s finding the attribute names and types for each table %s\n", - g_comment_start, g_comment_end); - getTableAttrs(tblinfo, numTables); - -if (g_verbose) fprintf(stderr, "%s flagging inherited attributes in subtables %s\n", - g_comment_start, g_comment_end); - flagInhAttrs(tblinfo, numTables, inhinfo, numInherits); - -if (!tablename && fout) { - if (g_verbose) fprintf(stderr,"%s dumping out user-defined types %s\n", - g_comment_start, g_comment_end); - dumpTypes(fout, finfo, numFuncs, tinfo, numTypes); -} - -if (fout) { - if (g_verbose) fprintf(stderr,"%s dumping out tables %s\n", - g_comment_start, g_comment_end); - dumpTables(fout, tblinfo, numTables, inhinfo, numInherits, - tinfo, numTypes, tablename, acls); -} - -if (!tablename && fout) { - if (g_verbose) fprintf(stderr,"%s dumping out user-defined functions %s\n", - g_comment_start, g_comment_end); - dumpFuncs(fout, finfo, numFuncs, tinfo, numTypes); -} + int numTypes; + int numFuncs; + int numTables; + int numInherits; + int numAggregates; + int numOperators; + TypeInfo *tinfo = NULL; + FuncInfo *finfo = NULL; + AggInfo *agginfo = NULL; + TableInfo *tblinfo = NULL; + InhInfo *inhinfo = NULL; + OprInfo *oprinfo = NULL; + + if (g_verbose) + fprintf(stderr, "%s reading user-defined types %s\n", + g_comment_start, g_comment_end); + tinfo = getTypes(&numTypes); + + if (g_verbose) + fprintf(stderr, "%s reading user-defined functions %s\n", + g_comment_start, g_comment_end); + finfo = getFuncs(&numFuncs); + + if (g_verbose) + fprintf(stderr, "%s reading user-defined aggregates %s\n", + g_comment_start, g_comment_end); + agginfo = getAggregates(&numAggregates); + + if (g_verbose) + fprintf(stderr, "%s reading user-defined operators %s\n", + g_comment_start, g_comment_end); + oprinfo = getOperators(&numOperators); + + if (g_verbose) + fprintf(stderr, "%s reading user-defined tables %s\n", + g_comment_start, g_comment_end); + tblinfo = getTables(&numTables); + + if (g_verbose) + fprintf(stderr, "%s reading table inheritance information %s\n", + g_comment_start, g_comment_end); + inhinfo = getInherits(&numInherits); + + if (g_verbose) + fprintf(stderr, "%s finding the attribute names and types for each table %s\n", + g_comment_start, g_comment_end); + getTableAttrs(tblinfo, numTables); + + if (g_verbose) + fprintf(stderr, "%s flagging inherited attributes in subtables %s\n", + g_comment_start, g_comment_end); + flagInhAttrs(tblinfo, numTables, inhinfo, numInherits); + + if (!tablename && fout) + { + if (g_verbose) + fprintf(stderr, "%s dumping out user-defined types %s\n", + g_comment_start, g_comment_end); + dumpTypes(fout, finfo, numFuncs, tinfo, numTypes); + } -if (!tablename && fout) { - if (g_verbose) fprintf(stderr,"%s dumping out user-defined functions %s\n", - g_comment_start, g_comment_end); - dumpAggs(fout, agginfo, numAggregates, tinfo, numTypes); -} + if (fout) + { + if (g_verbose) + fprintf(stderr, "%s dumping out tables %s\n", + g_comment_start, g_comment_end); + dumpTables(fout, tblinfo, numTables, inhinfo, numInherits, + tinfo, numTypes, tablename, acls); + } -if (!tablename && fout) { - if (g_verbose) fprintf(stderr,"%s dumping out user-defined operators %s\n", - g_comment_start, g_comment_end); - dumpOprs(fout, oprinfo, numOperators, tinfo, numTypes); -} + if (!tablename && fout) + { + if (g_verbose) + fprintf(stderr, "%s dumping out user-defined functions %s\n", + g_comment_start, g_comment_end); + dumpFuncs(fout, finfo, numFuncs, tinfo, numTypes); + } + + if (!tablename && fout) + { + if (g_verbose) + fprintf(stderr, "%s dumping out user-defined functions %s\n", + g_comment_start, g_comment_end); + dumpAggs(fout, agginfo, numAggregates, tinfo, numTypes); + } + + if (!tablename && fout) + { + if (g_verbose) + fprintf(stderr, "%s dumping out user-defined operators %s\n", + g_comment_start, g_comment_end); + dumpOprs(fout, oprinfo, numOperators, tinfo, numTypes); + } - *numTablesPtr = numTables; - clearAggInfo(agginfo,numAggregates); - clearOprInfo(oprinfo,numOperators); - clearTypeInfo(tinfo, numTypes); - clearFuncInfo(finfo,numFuncs); - clearInhInfo(inhinfo,numInherits); - return tblinfo; + *numTablesPtr = numTables; + clearAggInfo(agginfo, numAggregates); + clearOprInfo(oprinfo, numOperators); + clearTypeInfo(tinfo, numTypes); + clearFuncInfo(finfo, numFuncs); + clearInhInfo(inhinfo, numInherits); + return tblinfo; } /* * dumpSchemaIdx: - * dump indexes at the end for performance + * dump indexes at the end for performance * */ extern void -dumpSchemaIdx(FILE *fout, int *numTablesPtr, const char *tablename, - TableInfo* tblinfo, int numTables) +dumpSchemaIdx(FILE * fout, int *numTablesPtr, const char *tablename, + TableInfo * tblinfo, int numTables) { - int numIndices; - IndInfo *indinfo; - - if (g_verbose) fprintf(stderr,"%s reading indices information %s\n", - g_comment_start, g_comment_end); - indinfo = getIndices(&numIndices); - - if (fout) { - if (g_verbose) fprintf(stderr,"%s dumping out indices %s\n", - g_comment_start, g_comment_end); - dumpIndices(fout, indinfo, numIndices, tblinfo, numTables, tablename); - } - clearIndInfo(indinfo,numIndices); + int numIndices; + IndInfo *indinfo; + + if (g_verbose) + fprintf(stderr, "%s reading indices information %s\n", + g_comment_start, g_comment_end); + indinfo = getIndices(&numIndices); + + if (fout) + { + if (g_verbose) + fprintf(stderr, "%s dumping out indices %s\n", + g_comment_start, g_comment_end); + dumpIndices(fout, indinfo, numIndices, tblinfo, numTables, tablename); + } + clearIndInfo(indinfo, numIndices); } /* flagInhAttrs - - * for each table in tblinfo, flag its inherited attributes + * for each table in tblinfo, flag its inherited attributes * so when we dump the table out, we don't dump out the inherited attributes - * + * * initializes the parentRels field of each table * * modifies tblinfo * */ static void -flagInhAttrs(TableInfo* tblinfo, int numTables, - InhInfo* inhinfo, int numInherits) +flagInhAttrs(TableInfo * tblinfo, int numTables, + InhInfo * inhinfo, int numInherits) { - int i,j,k; - int parentInd; - - /* we go backwards because the tables in tblinfo are in OID - order, meaning the subtables are after the parent tables - we flag inherited attributes from child tables first */ - for (i = numTables-1; i >= 0; i--) { - tblinfo[i].parentRels = findParentsByOid(tblinfo, numTables, - inhinfo, numInherits, - tblinfo[i].oid, - &tblinfo[i].numParents); - for (k=0;k<tblinfo[i].numParents;k++) { - parentInd = findTableByName(tblinfo, numTables, - tblinfo[i].parentRels[k]); - for (j=0;j<tblinfo[i].numatts;j++) { - if (strInArray(tblinfo[i].attnames[j], - tblinfo[parentInd].attnames, - tblinfo[parentInd].numatts) != -1) { - tblinfo[i].inhAttrs[j] = 1; + int i, + j, + k; + int parentInd; + + /* + * we go backwards because the tables in tblinfo are in OID order, + * meaning the subtables are after the parent tables we flag inherited + * attributes from child tables first + */ + for (i = numTables - 1; i >= 0; i--) + { + tblinfo[i].parentRels = findParentsByOid(tblinfo, numTables, + inhinfo, numInherits, + tblinfo[i].oid, + &tblinfo[i].numParents); + for (k = 0; k < tblinfo[i].numParents; k++) + { + parentInd = findTableByName(tblinfo, numTables, + tblinfo[i].parentRels[k]); + for (j = 0; j < tblinfo[i].numatts; j++) + { + if (strInArray(tblinfo[i].attnames[j], + tblinfo[parentInd].attnames, + tblinfo[parentInd].numatts) != -1) + { + tblinfo[i].inhAttrs[j] = 1; + } + } } - } } - } } /* * findTableByName - * finds the index (in tblinfo) of the table with the given relname - * returns -1 if not found + * finds the index (in tblinfo) of the table with the given relname + * returns -1 if not found * * NOTE: should hash this, but just do linear search for now */ int -findTableByName(TableInfo* tblinfo, int numTables, const char* relname) +findTableByName(TableInfo * tblinfo, int numTables, const char *relname) { - int i; - for (i=0;i<numTables;i++) { - if (strcmp(tblinfo[i].relname, relname) == 0) - return i; - } - return -1; + int i; + + for (i = 0; i < numTables; i++) + { + if (strcmp(tblinfo[i].relname, relname) == 0) + return i; + } + return -1; } /* * findTableByOid - * finds the index (in tblinfo) of the table with the given oid - * returns -1 if not found + * finds the index (in tblinfo) of the table with the given oid + * returns -1 if not found * * NOTE: should hash this, but just do linear search for now */ static int -findTableByOid(TableInfo* tblinfo, int numTables, const char* oid) +findTableByOid(TableInfo * tblinfo, int numTables, const char *oid) { - int i; - for (i=0;i<numTables;i++) { - if (strcmp(tblinfo[i].oid, oid) == 0) - return i; - } - return -1; + int i; + + for (i = 0; i < numTables; i++) + { + if (strcmp(tblinfo[i].oid, oid) == 0) + return i; + } + return -1; } /* * findFuncByName - * finds the index (in finfo) of the function with the given name - * returns -1 if not found + * finds the index (in finfo) of the function with the given name + * returns -1 if not found * * NOTE: should hash this, but just do linear search for now */ int -findFuncByName(FuncInfo* finfo, int numFuncs, const char* name) +findFuncByName(FuncInfo * finfo, int numFuncs, const char *name) { - int i; - for (i=0;i<numFuncs;i++) { - if (strcmp(finfo[i].proname, name) == 0) - return i; - } - return -1; + int i; + + for (i = 0; i < numFuncs; i++) + { + if (strcmp(finfo[i].proname, name) == 0) + return i; + } + return -1; } /* * isArchiveName * - * returns true if the relation name is an archive name, false otherwise - */ + * returns true if the relation name is an archive name, false otherwise + */ int -isArchiveName(const char* relname) +isArchiveName(const char *relname) { - return (strlen(relname) > 1 && relname[1] == ','); + return (strlen(relname) > 1 && relname[1] == ','); } diff --git a/src/bin/pg_dump/pg_dump.c b/src/bin/pg_dump/pg_dump.c index c006505a13b..8192d5c30b6 100644 --- a/src/bin/pg_dump/pg_dump.c +++ b/src/bin/pg_dump/pg_dump.c @@ -1,19 +1,19 @@ /*------------------------------------------------------------------------- * * pg_dump.c-- - * pg_dump is an utility for dumping out a postgres database + * pg_dump is an utility for dumping out a postgres database * into a script file. * - * pg_dump will read the system catalogs in a database and - * dump out a script that reproduces - * the schema of the database in terms of - * user-defined types - * user-defined functions - * tables - * indices - * aggregates - * operators - * ACL - grant/revoke + * pg_dump will read the system catalogs in a database and + * dump out a script that reproduces + * the schema of the database in terms of + * user-defined types + * user-defined functions + * tables + * indices + * aggregates + * operators + * ACL - grant/revoke * * the output script is SQL that is understood by PostgreSQL * @@ -21,39 +21,39 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/bin/pg_dump/pg_dump.c,v 1.40 1997/08/22 17:15:41 momjian Exp $ + * $Header: /cvsroot/pgsql/src/bin/pg_dump/pg_dump.c,v 1.41 1997/09/07 04:54:38 momjian Exp $ * * Modifications - 6/10/96 - dave@bensoft.com - version 1.13.dhb * - * Applied 'insert string' patch from "Marc G. Fournier" <scrappy@ki.net> - * Added '-t table' option - * Added '-a' option - * Added '-da' option + * Applied 'insert string' patch from "Marc G. Fournier" <scrappy@ki.net> + * Added '-t table' option + * Added '-a' option + * Added '-da' option * * Modifications - 6/12/96 - dave@bensoft.com - version 1.13.dhb.2 * - * - Fixed dumpTable output to output lengths for char and varchar types! - * - Added single. quote to twin single quote expansion for 'insert' string - * mode. + * - Fixed dumpTable output to output lengths for char and varchar types! + * - Added single. quote to twin single quote expansion for 'insert' string + * mode. * * Modifications - 7/26/96 - asussman@vidya.com * - * - Fixed ouput lengths for char and varchar type where the length is variable (-1) + * - Fixed ouput lengths for char and varchar type where the length is variable (-1) * * Modifications - 6/1/97 - igor@sba.miami.edu * - Added functions to free allocated memory used for retrieving - * indices,tables,inheritance,types,functions and aggregates. - * No more leaks reported by Purify. + * indices,tables,inheritance,types,functions and aggregates. + * No more leaks reported by Purify. *------------------------------------------------------------------------- */ #include <stdlib.h> -#include <unistd.h> /* for getopt() */ +#include <unistd.h> /* for getopt() */ #include <stdio.h> #include <string.h> -#include <sys/param.h> /* for MAXHOSTNAMELEN on most */ +#include <sys/param.h> /* for MAXHOSTNAMELEN on most */ #ifdef sparc_solaris -#include <netdb.h> /* for MAXHOSTNAMELEN on some */ +#include <netdb.h> /* for MAXHOSTNAMELEN on some */ #endif #include "postgres.h" @@ -67,1946 +67,2202 @@ #include "pg_dump.h" -static void dumpSequence (FILE* fout, TableInfo tbinfo); -static char *checkForQuote(const char* s); -static void clearTableInfo(TableInfo*, int); -static void dumpOneFunc(FILE* fout, FuncInfo* finfo, int i, - TypeInfo *tinfo, int numTypes); -static int findLastBuiltinOid(void); -static bool isViewRule(char *relname); -static void setMaxOid(FILE *fout); +static void dumpSequence(FILE * fout, TableInfo tbinfo); +static char *checkForQuote(const char *s); +static void clearTableInfo(TableInfo *, int); +static void +dumpOneFunc(FILE * fout, FuncInfo * finfo, int i, + TypeInfo * tinfo, int numTypes); +static int findLastBuiltinOid(void); +static bool isViewRule(char *relname); +static void setMaxOid(FILE * fout); -extern char *optarg; -extern int optind, opterr; +extern char *optarg; +extern int optind, + opterr; /* global decls */ -bool g_verbose; /* User wants verbose narration of our activities. */ -int g_last_builtin_oid; /* value of the last builtin oid */ -FILE *g_fout; /* the script file */ -PGconn *g_conn; /* the database connection */ -int dumpData; /* dump data using proper insert strings */ -int attrNames; /* put attr names into insert strings */ -int schemaOnly; -int dataOnly; - -char g_opaque_type[10]; /* name for the opaque type */ +bool g_verbose; /* User wants verbose narration of our + * activities. */ +int g_last_builtin_oid; /* value of the last builtin oid */ +FILE *g_fout; /* the script file */ +PGconn *g_conn; /* the database connection */ +int dumpData; /* dump data using proper insert strings */ +int attrNames; /* put attr names into insert strings */ +int schemaOnly; +int dataOnly; + +char g_opaque_type[10]; /* name for the opaque type */ /* placeholders for the delimiters for comments */ -char g_comment_start[10]; -char g_comment_end[10]; +char g_comment_start[10]; +char g_comment_end[10]; static void -usage(const char* progname) +usage(const char *progname) { - fprintf(stderr, - "%s - version 1.13.dhb.2\n\n",progname); - fprintf(stderr, - "usage: %s [options] [dbname]\n",progname); - fprintf(stderr, - "\t -f filename \t\t script output filename\n"); - fprintf(stderr, - "\t -H hostname \t\t server host name\n"); - fprintf(stderr, - "\t -p port \t\t server port number\n"); - fprintf(stderr, - "\t -v \t\t verbose\n"); - fprintf(stderr, - "\t -d \t\t dump data as proper insert strings\n"); - fprintf(stderr, - "\t -D \t\t dump data as inserts with attribute names\n"); - fprintf(stderr, - "\t -S \t\t dump out only the schema, no data\n"); - fprintf(stderr, - "\t -a \t\t dump out only the data, no schema\n"); - fprintf(stderr, - "\t -t table \t\t dump for this table only\n"); - fprintf(stderr, - "\t -o \t\t dump object id's (oids)\n"); - fprintf(stderr, - "\t -z \t\t dump ACLs (grant/revoke)\n"); - fprintf(stderr, - "\nIf dbname is not supplied, then the DATABASE environment " - "variable value is used.\n"); - fprintf(stderr, "\n"); - - exit(1); + fprintf(stderr, + "%s - version 1.13.dhb.2\n\n", progname); + fprintf(stderr, + "usage: %s [options] [dbname]\n", progname); + fprintf(stderr, + "\t -f filename \t\t script output filename\n"); + fprintf(stderr, + "\t -H hostname \t\t server host name\n"); + fprintf(stderr, + "\t -p port \t\t server port number\n"); + fprintf(stderr, + "\t -v \t\t verbose\n"); + fprintf(stderr, + "\t -d \t\t dump data as proper insert strings\n"); + fprintf(stderr, + "\t -D \t\t dump data as inserts with attribute names\n"); + fprintf(stderr, + "\t -S \t\t dump out only the schema, no data\n"); + fprintf(stderr, + "\t -a \t\t dump out only the data, no schema\n"); + fprintf(stderr, + "\t -t table \t\t dump for this table only\n"); + fprintf(stderr, + "\t -o \t\t dump object id's (oids)\n"); + fprintf(stderr, + "\t -z \t\t dump ACLs (grant/revoke)\n"); + fprintf(stderr, + "\nIf dbname is not supplied, then the DATABASE environment " + "variable value is used.\n"); + fprintf(stderr, "\n"); + + exit(1); } -static void -exit_nicely(PGconn* conn) +static void +exit_nicely(PGconn * conn) { - PQfinish(conn); - exit(1); + PQfinish(conn); + exit(1); } /* * isViewRule - * Determine if the relation is a VIEW + * Determine if the relation is a VIEW * */ -static bool +static bool isViewRule(char *relname) { - PGresult *res; - int ntups; - char query[MAXQUERYLEN]; - - res = PQexec(g_conn, "begin"); - if (!res || - PQresultStatus(res) != PGRES_COMMAND_OK) { - fprintf(stderr,"BEGIN command failed\n"); - exit_nicely(g_conn); - } - PQclear(res); - - sprintf(query, "select relname from pg_class, pg_rewrite " - "where pg_class.oid = ev_class " - "and rulename = '_RET%s'", relname); - - res = PQexec(g_conn, query); - if (!res || - PQresultStatus(res) != PGRES_TUPLES_OK) { - fprintf(stderr,"isViewRule(): SELECT failed\n"); - exit_nicely(g_conn); - } - - ntups = PQntuples(res); - - PQclear(res); - res = PQexec(g_conn, "end"); - PQclear(res); - return ntups > 0 ? TRUE : FALSE; + PGresult *res; + int ntups; + char query[MAXQUERYLEN]; + + res = PQexec(g_conn, "begin"); + if (!res || + PQresultStatus(res) != PGRES_COMMAND_OK) + { + fprintf(stderr, "BEGIN command failed\n"); + exit_nicely(g_conn); + } + PQclear(res); + + sprintf(query, "select relname from pg_class, pg_rewrite " + "where pg_class.oid = ev_class " + "and rulename = '_RET%s'", relname); + + res = PQexec(g_conn, query); + if (!res || + PQresultStatus(res) != PGRES_TUPLES_OK) + { + fprintf(stderr, "isViewRule(): SELECT failed\n"); + exit_nicely(g_conn); + } + + ntups = PQntuples(res); + + PQclear(res); + res = PQexec(g_conn, "end"); + PQclear(res); + return ntups > 0 ? TRUE : FALSE; } -#define COPYBUFSIZ 8192 - - -static void -dumpClasses_nodumpData(FILE *fout, const char *classname, const bool oids) { - - PGresult *res; - char query[255]; - int ret; - bool copydone; - char copybuf[COPYBUFSIZ]; - - if (oids) { - fprintf(fout, "COPY %s WITH OIDS FROM stdin;\n", - classname); - sprintf(query, "COPY %s WITH OIDS TO stdout;\n", - classname); - } else { - fprintf(fout, "COPY %s FROM stdin;\n", classname); - sprintf(query, "COPY %s TO stdout;\n", classname); - } - res = PQexec(g_conn, query); - if (!res) { - fprintf(stderr, "SQL query to dump the contents of Table %s " - "did not execute. Explanation from backend: '%s'.\n" - "The query was: '%s'.\n", - classname, PQerrorMessage(g_conn), query); - exit_nicely(g_conn); - } else { - if (PQresultStatus(res) != PGRES_COPY_OUT) { - fprintf(stderr,"SQL query to dump the contents of Table %s " - "executed abnormally.\n" - "PQexec() returned status %d when %d was expected.\n" - "The query was: '%s'.\n", - classname, PQresultStatus(res), PGRES_COPY_OUT, query); - exit_nicely(g_conn); - } else { - copydone = false; - while (!copydone) { - ret = PQgetline(res->conn, copybuf, COPYBUFSIZ); - - if (copybuf[0] == '\\' && - copybuf[1] == '.' && - copybuf[2] == '\0') { - copydone = true; /* don't print this... */ - } else { - fputs(copybuf, fout); - switch (ret) { - case EOF: - copydone = true; - /*FALLTHROUGH*/ - case 0: - fputc('\n', fout); - break; - case 1: - break; - } - } - } - fprintf(fout, "\\.\n"); - } - ret = PQendcopy(res->conn); - if (ret != 0) { - fprintf(stderr, "SQL query to dump the contents of Table %s " - "did not execute correctly. After we read all the " - "table contents from the backend, PQendcopy() failed. " - "Explanation from backend: '%s'.\n" - "The query was: '%s'.\n", - classname, PQerrorMessage(g_conn), query); - if(res) PQclear(res); - exit_nicely(g_conn); - } - if(res) PQclear(res); - } +#define COPYBUFSIZ 8192 + + +static void +dumpClasses_nodumpData(FILE * fout, const char *classname, const bool oids) +{ + + PGresult *res; + char query[255]; + int ret; + bool copydone; + char copybuf[COPYBUFSIZ]; + + if (oids) + { + fprintf(fout, "COPY %s WITH OIDS FROM stdin;\n", + classname); + sprintf(query, "COPY %s WITH OIDS TO stdout;\n", + classname); + } + else + { + fprintf(fout, "COPY %s FROM stdin;\n", classname); + sprintf(query, "COPY %s TO stdout;\n", classname); + } + res = PQexec(g_conn, query); + if (!res) + { + fprintf(stderr, "SQL query to dump the contents of Table %s " + "did not execute. Explanation from backend: '%s'.\n" + "The query was: '%s'.\n", + classname, PQerrorMessage(g_conn), query); + exit_nicely(g_conn); + } + else + { + if (PQresultStatus(res) != PGRES_COPY_OUT) + { + fprintf(stderr, "SQL query to dump the contents of Table %s " + "executed abnormally.\n" + "PQexec() returned status %d when %d was expected.\n" + "The query was: '%s'.\n", + classname, PQresultStatus(res), PGRES_COPY_OUT, query); + exit_nicely(g_conn); + } + else + { + copydone = false; + while (!copydone) + { + ret = PQgetline(res->conn, copybuf, COPYBUFSIZ); + + if (copybuf[0] == '\\' && + copybuf[1] == '.' && + copybuf[2] == '\0') + { + copydone = true; /* don't print this... */ + } + else + { + fputs(copybuf, fout); + switch (ret) + { + case EOF: + copydone = true; + /* FALLTHROUGH */ + case 0: + fputc('\n', fout); + break; + case 1: + break; + } + } + } + fprintf(fout, "\\.\n"); + } + ret = PQendcopy(res->conn); + if (ret != 0) + { + fprintf(stderr, "SQL query to dump the contents of Table %s " + "did not execute correctly. After we read all the " + "table contents from the backend, PQendcopy() failed. " + "Explanation from backend: '%s'.\n" + "The query was: '%s'.\n", + classname, PQerrorMessage(g_conn), query); + if (res) + PQclear(res); + exit_nicely(g_conn); + } + if (res) + PQclear(res); + } } static void -dumpClasses_dumpData(FILE *fout, const char *classname, - const TableInfo tblinfo, bool oids) { - - PGresult *res; - char query[255]; - int actual_atts; /* number of attrs in this a table */ - char expandbuf[COPYBUFSIZ]; - char q[MAXQUERYLEN]; - int tuple; - int field; - - sprintf(query, "select * from %s", classname); - res = PQexec(g_conn, query); - if (!res || - PQresultStatus(res) != PGRES_TUPLES_OK) { - fprintf(stderr,"dumpClasses(): command failed\n"); - exit_nicely(g_conn); - } - tuple=0; - while(tuple < PQntuples(res)) { - fprintf(fout, "insert into %s ", classname); - if (attrNames) { - int j; - actual_atts = 0; - sprintf(q, "("); - for (j=0;j<tblinfo.numatts;j++) { - if (tblinfo.inhAttrs[j] == 0) { - sprintf(q, "%s%s%s", - q, - (actual_atts > 0) ? "," : "", - tblinfo.attnames[j]); - actual_atts++; - } - } - sprintf(q,"%s%s",q, ") "); - fprintf(fout, q); - } - fprintf(fout, "values ("); - field=0; - do { - if (PQgetisnull(res,tuple,field)) { - fprintf(fout,"NULL"); - } else { - switch(PQftype(res,field)) { - case INT2OID: case INT4OID: case OIDOID: /* int types */ - case FLOAT4OID: case FLOAT8OID: /* float types */ - fprintf(fout, "%s", - PQgetvalue(res,tuple,field)); - break; - default: { - char *expsrc,*expdest; - - /* Before outputting string value, expand all - single quotes to twin single quotes - - dhb - 6/11/96 */ - expsrc=PQgetvalue(res,tuple,field); - expdest=expandbuf; - while (*expsrc) { - *expdest++=*expsrc; - if (*expsrc == (char)0x27) /*single quote*/ - *expdest++ = *expsrc; - expsrc++; - } - *expdest=*expsrc; /* null term. */ - - fprintf(fout, "'%s'", expandbuf); - } - break; - } - } - field++; - if(field != PQnfields(res)) - fprintf(fout, ","); - } while(field < PQnfields(res)); - fprintf(fout, ");\n"); - tuple++; - } - PQclear(res); +dumpClasses_dumpData(FILE * fout, const char *classname, + const TableInfo tblinfo, bool oids) +{ + + PGresult *res; + char query[255]; + int actual_atts;/* number of attrs in this a table */ + char expandbuf[COPYBUFSIZ]; + char q[MAXQUERYLEN]; + int tuple; + int field; + + sprintf(query, "select * from %s", classname); + res = PQexec(g_conn, query); + if (!res || + PQresultStatus(res) != PGRES_TUPLES_OK) + { + fprintf(stderr, "dumpClasses(): command failed\n"); + exit_nicely(g_conn); + } + tuple = 0; + while (tuple < PQntuples(res)) + { + fprintf(fout, "insert into %s ", classname); + if (attrNames) + { + int j; + + actual_atts = 0; + sprintf(q, "("); + for (j = 0; j < tblinfo.numatts; j++) + { + if (tblinfo.inhAttrs[j] == 0) + { + sprintf(q, "%s%s%s", + q, + (actual_atts > 0) ? "," : "", + tblinfo.attnames[j]); + actual_atts++; + } + } + sprintf(q, "%s%s", q, ") "); + fprintf(fout, q); + } + fprintf(fout, "values ("); + field = 0; + do + { + if (PQgetisnull(res, tuple, field)) + { + fprintf(fout, "NULL"); + } + else + { + switch (PQftype(res, field)) + { + case INT2OID: + case INT4OID: + case OIDOID: /* int types */ + case FLOAT4OID: + case FLOAT8OID:/* float types */ + fprintf(fout, "%s", + PQgetvalue(res, tuple, field)); + break; + default: + { + char *expsrc, + *expdest; + + /* + * Before outputting string value, expand all + * single quotes to twin single quotes - dhb - + * 6/11/96 + */ + expsrc = PQgetvalue(res, tuple, field); + expdest = expandbuf; + while (*expsrc) + { + *expdest++ = *expsrc; + if (*expsrc == (char) 0x27) /* single quote */ + *expdest++ = *expsrc; + expsrc++; + } + *expdest = *expsrc; /* null term. */ + + fprintf(fout, "'%s'", expandbuf); + } + break; + } + } + field++; + if (field != PQnfields(res)) + fprintf(fout, ","); + } while (field < PQnfields(res)); + fprintf(fout, ");\n"); + tuple++; + } + PQclear(res); } /* * DumpClasses - - * dump the contents of all the classes. + * dump the contents of all the classes. */ static void -dumpClasses(const TableInfo tblinfo[], const int numTables, FILE *fout, - const char *onlytable, const bool oids) { - - int i; - char *all_only; - - if (onlytable == NULL) all_only = "all"; - else all_only = "one"; - - if (g_verbose) - fprintf(stderr, "%s dumping out the contents of %s of %d tables %s\n", - g_comment_start, all_only, numTables, g_comment_end); - - for(i = 0; i < numTables; i++) { - const char *classname = tblinfo[i].relname; - - /* Skip VIEW relations */ - if (isViewRule(tblinfo[i].relname)) - continue; - - if (!onlytable || (!strcmp(classname,onlytable))) - { - if ( tblinfo[i].sequence ) - { - if ( dataOnly ) /* i.e. SCHEMA didn't dumped */ - { - if ( g_verbose ) - fprintf (stderr, "%s dumping out schema of sequence %s %s\n", - g_comment_start, classname, g_comment_end); - dumpSequence (fout, tblinfo[i]); +dumpClasses(const TableInfo tblinfo[], const int numTables, FILE * fout, + const char *onlytable, const bool oids) +{ + + int i; + char *all_only; + + if (onlytable == NULL) + all_only = "all"; + else + all_only = "one"; + + if (g_verbose) + fprintf(stderr, "%s dumping out the contents of %s of %d tables %s\n", + g_comment_start, all_only, numTables, g_comment_end); + + for (i = 0; i < numTables; i++) + { + const char *classname = tblinfo[i].relname; + + /* Skip VIEW relations */ + if (isViewRule(tblinfo[i].relname)) + continue; + + if (!onlytable || (!strcmp(classname, onlytable))) + { + if (tblinfo[i].sequence) + { + if (dataOnly) /* i.e. SCHEMA didn't dumped */ + { + if (g_verbose) + fprintf(stderr, "%s dumping out schema of sequence %s %s\n", + g_comment_start, classname, g_comment_end); + dumpSequence(fout, tblinfo[i]); + } + else if (g_verbose) + fprintf(stderr, "%s contents of sequence '%s' dumped in schema %s\n", + g_comment_start, classname, g_comment_end); + continue; + } + + if (g_verbose) + fprintf(stderr, "%s dumping out the contents of Table %s %s\n", + g_comment_start, classname, g_comment_end); + + /* skip archive names */ + if (isArchiveName(classname)) + continue; + + if (!dumpData) + dumpClasses_nodumpData(fout, classname, oids); + else + dumpClasses_dumpData(fout, classname, tblinfo[i], oids); } - else if ( g_verbose ) - fprintf (stderr, "%s contents of sequence '%s' dumped in schema %s\n", - g_comment_start, classname, g_comment_end); - continue; - } - - if (g_verbose) - fprintf(stderr, "%s dumping out the contents of Table %s %s\n", - g_comment_start, classname, g_comment_end); - - /* skip archive names*/ - if (isArchiveName(classname)) - continue; - - if(!dumpData) - dumpClasses_nodumpData(fout, classname, oids); - else - dumpClasses_dumpData(fout, classname, tblinfo[i], oids); - } - } + } } int -main(int argc, char** argv) +main(int argc, char **argv) { - int c; - const char* progname; - const char* filename = NULL; - const char* dbname = NULL; - const char *pghost = NULL; - const char *pgport = NULL; - const char *tablename = NULL; - int oids = 0, acls = 0; - TableInfo *tblinfo; - int numTables; - - g_verbose = false; - - strcpy(g_comment_start,"-- "); - g_comment_end[0] = '\0'; - strcpy(g_opaque_type, "opaque"); - - dataOnly = schemaOnly = dumpData = attrNames = 0; - - progname = *argv; - - while ((c = getopt(argc, argv,"f:H:p:t:vSDdDaoz")) != EOF) { - switch(c) { - case 'f': /* output file name */ - filename = optarg; - break; - case 'H' : /* server host */ - pghost = optarg; - break; - case 'p' : /* server port */ - pgport = optarg; - break; - case 'v': /* verbose */ - g_verbose = true; - break; - case 'S': /* dump schema only */ - schemaOnly = 1; - break; - case 'd': /* dump data as proper insert strings */ - dumpData = 1; - break; - case 'D': /* dump data as proper insert strings with attr names */ - dumpData = 1; - attrNames = 1; - break; - case 't': /* Dump data for this table only */ - tablename = optarg; - break; - case 'a': /* Dump data only */ - dataOnly = 1; - break; - case 'o': /* Dump oids */ - oids = 1; - break; - case 'z': /* Dump oids */ - acls = 1; - break; - default: - usage(progname); - break; - } - } - - /* open the output file */ - if (filename == NULL) { - g_fout = stdout; - } else { - g_fout = fopen(filename, "w"); - if (g_fout == NULL) { - fprintf(stderr, - "%s: could not open output file named %s for writing\n", - progname, filename); - exit(2); - } - } - - /* find database */ - if (!(dbname = argv[optind]) && - !(dbname = getenv("DATABASE")) ) { - fprintf(stderr, "%s: no database name specified\n",progname); - exit (2); - } - - g_conn = PQsetdb(pghost, pgport, NULL, NULL, dbname); - /* check to see that the backend connection was successfully made */ - if (PQstatus(g_conn) == CONNECTION_BAD) { - fprintf(stderr,"Connection to database '%s' failed.\n", dbname); - fprintf(stderr,"%s\n",PQerrorMessage(g_conn)); - exit_nicely(g_conn); - } - - g_last_builtin_oid = findLastBuiltinOid(); - - if (oids) - setMaxOid(g_fout); - if (!dataOnly) { - if (g_verbose) - fprintf(stderr, "%s last builtin oid is %d %s\n", - g_comment_start, g_last_builtin_oid, g_comment_end); - tblinfo = dumpSchema(g_fout, &numTables, tablename, acls); - } - else - tblinfo = dumpSchema(NULL, &numTables, tablename, acls); - - if (!schemaOnly) { - dumpClasses(tblinfo, numTables, g_fout, tablename, oids); - } - - if (!dataOnly) /* dump indexes at the end for performance */ - dumpSchemaIdx(g_fout, &numTables, tablename, tblinfo, numTables); - - fflush(g_fout); - fclose(g_fout); - clearTableInfo(tblinfo, numTables); - PQfinish(g_conn); - exit(0); + int c; + const char *progname; + const char *filename = NULL; + const char *dbname = NULL; + const char *pghost = NULL; + const char *pgport = NULL; + const char *tablename = NULL; + int oids = 0, + acls = 0; + TableInfo *tblinfo; + int numTables; + + g_verbose = false; + + strcpy(g_comment_start, "-- "); + g_comment_end[0] = '\0'; + strcpy(g_opaque_type, "opaque"); + + dataOnly = schemaOnly = dumpData = attrNames = 0; + + progname = *argv; + + while ((c = getopt(argc, argv, "f:H:p:t:vSDdDaoz")) != EOF) + { + switch (c) + { + case 'f': /* output file name */ + filename = optarg; + break; + case 'H': /* server host */ + pghost = optarg; + break; + case 'p': /* server port */ + pgport = optarg; + break; + case 'v': /* verbose */ + g_verbose = true; + break; + case 'S': /* dump schema only */ + schemaOnly = 1; + break; + case 'd': /* dump data as proper insert strings */ + dumpData = 1; + break; + case 'D': /* dump data as proper insert strings with + * attr names */ + dumpData = 1; + attrNames = 1; + break; + case 't': /* Dump data for this table only */ + tablename = optarg; + break; + case 'a': /* Dump data only */ + dataOnly = 1; + break; + case 'o': /* Dump oids */ + oids = 1; + break; + case 'z': /* Dump oids */ + acls = 1; + break; + default: + usage(progname); + break; + } + } + + /* open the output file */ + if (filename == NULL) + { + g_fout = stdout; + } + else + { + g_fout = fopen(filename, "w"); + if (g_fout == NULL) + { + fprintf(stderr, + "%s: could not open output file named %s for writing\n", + progname, filename); + exit(2); + } + } + + /* find database */ + if (!(dbname = argv[optind]) && + !(dbname = getenv("DATABASE"))) + { + fprintf(stderr, "%s: no database name specified\n", progname); + exit(2); + } + + g_conn = PQsetdb(pghost, pgport, NULL, NULL, dbname); + /* check to see that the backend connection was successfully made */ + if (PQstatus(g_conn) == CONNECTION_BAD) + { + fprintf(stderr, "Connection to database '%s' failed.\n", dbname); + fprintf(stderr, "%s\n", PQerrorMessage(g_conn)); + exit_nicely(g_conn); + } + + g_last_builtin_oid = findLastBuiltinOid(); + + if (oids) + setMaxOid(g_fout); + if (!dataOnly) + { + if (g_verbose) + fprintf(stderr, "%s last builtin oid is %d %s\n", + g_comment_start, g_last_builtin_oid, g_comment_end); + tblinfo = dumpSchema(g_fout, &numTables, tablename, acls); + } + else + tblinfo = dumpSchema(NULL, &numTables, tablename, acls); + + if (!schemaOnly) + { + dumpClasses(tblinfo, numTables, g_fout, tablename, oids); + } + + if (!dataOnly) /* dump indexes at the end for performance */ + dumpSchemaIdx(g_fout, &numTables, tablename, tblinfo, numTables); + + fflush(g_fout); + fclose(g_fout); + clearTableInfo(tblinfo, numTables); + PQfinish(g_conn); + exit(0); } /* - * getTypes: - * read all base types in the system catalogs and return them in the + * getTypes: + * read all base types in the system catalogs and return them in the * TypeInfo* structure * - * numTypes is set to the number of types read in + * numTypes is set to the number of types read in * */ -TypeInfo* +TypeInfo * getTypes(int *numTypes) { - PGresult *res; - int ntups; - int i; - char query[MAXQUERYLEN]; - TypeInfo *tinfo; - - int i_oid; - int i_typowner; - int i_typname; - int i_typlen; - int i_typprtlen; - int i_typinput; - int i_typoutput; - int i_typreceive; - int i_typsend; - int i_typelem; - int i_typdelim; - int i_typdefault; - int i_typrelid; - int i_typbyval; - int i_usename; - - res = PQexec(g_conn, "begin"); - if (!res || - PQresultStatus(res) != PGRES_COMMAND_OK) { - fprintf(stderr,"BEGIN command failed\n"); - exit_nicely(g_conn); - } - PQclear(res); - - /* find all base types */ - /* we include even the built-in types - because those may be used as array elements by user-defined types */ - /* we filter out the built-in types when - we dump out the types */ - - sprintf(query, "SELECT pg_type.oid, typowner,typname, typlen, typprtlen, " - "typinput, typoutput, typreceive, typsend, typelem, typdelim, " - "typdefault, typrelid,typbyval, usename from pg_type, pg_user " - "where typowner = usesysid"); - - res = PQexec(g_conn,query); - if (!res || - PQresultStatus(res) != PGRES_TUPLES_OK) { - fprintf(stderr,"getTypes(): SELECT failed\n"); - exit_nicely(g_conn); - } - - ntups = PQntuples(res); - - tinfo = (TypeInfo*)malloc(ntups * sizeof(TypeInfo)); - - i_oid = PQfnumber(res,"oid"); - i_typowner = PQfnumber(res,"typowner"); - i_typname = PQfnumber(res,"typname"); - i_typlen = PQfnumber(res,"typlen"); - i_typprtlen = PQfnumber(res,"typprtlen"); - i_typinput = PQfnumber(res,"typinput"); - i_typoutput = PQfnumber(res,"typoutput"); - i_typreceive = PQfnumber(res,"typreceive"); - i_typsend = PQfnumber(res,"typsend"); - i_typelem = PQfnumber(res,"typelem"); - i_typdelim = PQfnumber(res,"typdelim"); - i_typdefault = PQfnumber(res,"typdefault"); - i_typrelid = PQfnumber(res,"typrelid"); - i_typbyval = PQfnumber(res,"typbyval"); - i_usename = PQfnumber(res,"usename"); - - for (i=0;i<ntups;i++) { - tinfo[i].oid = strdup(PQgetvalue(res,i,i_oid)); - tinfo[i].typowner = strdup(PQgetvalue(res,i,i_typowner)); - tinfo[i].typname = strdup(PQgetvalue(res,i,i_typname)); - tinfo[i].typlen = strdup(PQgetvalue(res,i,i_typlen)); - tinfo[i].typprtlen = strdup(PQgetvalue(res,i,i_typprtlen)); - tinfo[i].typinput = strdup(PQgetvalue(res,i,i_typinput)); - tinfo[i].typoutput = strdup(PQgetvalue(res,i,i_typoutput)); - tinfo[i].typreceive = strdup(PQgetvalue(res,i,i_typreceive)); - tinfo[i].typsend = strdup(PQgetvalue(res,i,i_typsend)); - tinfo[i].typelem = strdup(PQgetvalue(res,i,i_typelem)); - tinfo[i].typdelim = strdup(PQgetvalue(res,i,i_typdelim)); - tinfo[i].typdefault = strdup(PQgetvalue(res,i,i_typdefault)); - tinfo[i].typrelid = strdup(PQgetvalue(res,i,i_typrelid)); - tinfo[i].usename = strdup(PQgetvalue(res,i,i_usename)); - - if (strcmp(PQgetvalue(res,i,i_typbyval), "f") == 0) - tinfo[i].passedbyvalue = 0; - else - tinfo[i].passedbyvalue = 1; - - /* check for user-defined array types, - omit system generated ones */ - if ( (strcmp(tinfo[i].typelem, "0") != 0) && - tinfo[i].typname[0] != '_') - tinfo[i].isArray = 1; - else - tinfo[i].isArray = 0; - } - - *numTypes = ntups; - - PQclear(res); - - res = PQexec(g_conn,"end"); - PQclear(res); - - return tinfo; + PGresult *res; + int ntups; + int i; + char query[MAXQUERYLEN]; + TypeInfo *tinfo; + + int i_oid; + int i_typowner; + int i_typname; + int i_typlen; + int i_typprtlen; + int i_typinput; + int i_typoutput; + int i_typreceive; + int i_typsend; + int i_typelem; + int i_typdelim; + int i_typdefault; + int i_typrelid; + int i_typbyval; + int i_usename; + + res = PQexec(g_conn, "begin"); + if (!res || + PQresultStatus(res) != PGRES_COMMAND_OK) + { + fprintf(stderr, "BEGIN command failed\n"); + exit_nicely(g_conn); + } + PQclear(res); + + /* find all base types */ + + /* + * we include even the built-in types because those may be used as + * array elements by user-defined types + */ + + /* + * we filter out the built-in types when we dump out the types + */ + + sprintf(query, "SELECT pg_type.oid, typowner,typname, typlen, typprtlen, " + "typinput, typoutput, typreceive, typsend, typelem, typdelim, " + "typdefault, typrelid,typbyval, usename from pg_type, pg_user " + "where typowner = usesysid"); + + res = PQexec(g_conn, query); + if (!res || + PQresultStatus(res) != PGRES_TUPLES_OK) + { + fprintf(stderr, "getTypes(): SELECT failed\n"); + exit_nicely(g_conn); + } + + ntups = PQntuples(res); + + tinfo = (TypeInfo *) malloc(ntups * sizeof(TypeInfo)); + + i_oid = PQfnumber(res, "oid"); + i_typowner = PQfnumber(res, "typowner"); + i_typname = PQfnumber(res, "typname"); + i_typlen = PQfnumber(res, "typlen"); + i_typprtlen = PQfnumber(res, "typprtlen"); + i_typinput = PQfnumber(res, "typinput"); + i_typoutput = PQfnumber(res, "typoutput"); + i_typreceive = PQfnumber(res, "typreceive"); + i_typsend = PQfnumber(res, "typsend"); + i_typelem = PQfnumber(res, "typelem"); + i_typdelim = PQfnumber(res, "typdelim"); + i_typdefault = PQfnumber(res, "typdefault"); + i_typrelid = PQfnumber(res, "typrelid"); + i_typbyval = PQfnumber(res, "typbyval"); + i_usename = PQfnumber(res, "usename"); + + for (i = 0; i < ntups; i++) + { + tinfo[i].oid = strdup(PQgetvalue(res, i, i_oid)); + tinfo[i].typowner = strdup(PQgetvalue(res, i, i_typowner)); + tinfo[i].typname = strdup(PQgetvalue(res, i, i_typname)); + tinfo[i].typlen = strdup(PQgetvalue(res, i, i_typlen)); + tinfo[i].typprtlen = strdup(PQgetvalue(res, i, i_typprtlen)); + tinfo[i].typinput = strdup(PQgetvalue(res, i, i_typinput)); + tinfo[i].typoutput = strdup(PQgetvalue(res, i, i_typoutput)); + tinfo[i].typreceive = strdup(PQgetvalue(res, i, i_typreceive)); + tinfo[i].typsend = strdup(PQgetvalue(res, i, i_typsend)); + tinfo[i].typelem = strdup(PQgetvalue(res, i, i_typelem)); + tinfo[i].typdelim = strdup(PQgetvalue(res, i, i_typdelim)); + tinfo[i].typdefault = strdup(PQgetvalue(res, i, i_typdefault)); + tinfo[i].typrelid = strdup(PQgetvalue(res, i, i_typrelid)); + tinfo[i].usename = strdup(PQgetvalue(res, i, i_usename)); + + if (strcmp(PQgetvalue(res, i, i_typbyval), "f") == 0) + tinfo[i].passedbyvalue = 0; + else + tinfo[i].passedbyvalue = 1; + + /* + * check for user-defined array types, omit system generated ones + */ + if ((strcmp(tinfo[i].typelem, "0") != 0) && + tinfo[i].typname[0] != '_') + tinfo[i].isArray = 1; + else + tinfo[i].isArray = 0; + } + + *numTypes = ntups; + + PQclear(res); + + res = PQexec(g_conn, "end"); + PQclear(res); + + return tinfo; } /* * getOperators: - * read all operators in the system catalogs and return them in the + * read all operators in the system catalogs and return them in the * OprInfo* structure * - * numOprs is set to the number of operators read in - * + * numOprs is set to the number of operators read in + * * */ -OprInfo* +OprInfo * getOperators(int *numOprs) { - PGresult *res; - int ntups; - int i; - char query[MAXQUERYLEN]; - - OprInfo* oprinfo; - - int i_oid; - int i_oprname; - int i_oprkind; - int i_oprcode; - int i_oprleft; - int i_oprright; - int i_oprcom; - int i_oprnegate; - int i_oprrest; - int i_oprjoin; - int i_oprcanhash; - int i_oprlsortop; - int i_oprrsortop; - int i_usename; - - /* find all operators, including builtin operators, - filter out system-defined operators at dump-out time */ - res = PQexec(g_conn, "begin"); - if (!res || - PQresultStatus(res) != PGRES_COMMAND_OK) { - fprintf(stderr,"BEGIN command failed\n"); - exit_nicely(g_conn); - } - PQclear(res); - - sprintf(query, "SELECT pg_operator.oid, oprname, oprkind, oprcode, " - "oprleft, oprright, oprcom, oprnegate, oprrest, oprjoin, " - "oprcanhash, oprlsortop, oprrsortop, usename " - "from pg_operator, pg_user " - "where oprowner = usesysid"); - - res = PQexec(g_conn, query); - if (!res || - PQresultStatus(res) != PGRES_TUPLES_OK) { - fprintf(stderr,"getOperators(): SELECT failed\n"); - exit_nicely(g_conn); - } - - ntups = PQntuples(res); - *numOprs = ntups; - - oprinfo = (OprInfo*)malloc(ntups * sizeof(OprInfo)); - - i_oid = PQfnumber(res,"oid"); - i_oprname = PQfnumber(res,"oprname"); - i_oprkind = PQfnumber(res,"oprkind"); - i_oprcode = PQfnumber(res,"oprcode"); - i_oprleft = PQfnumber(res,"oprleft"); - i_oprright = PQfnumber(res,"oprright"); - i_oprcom = PQfnumber(res,"oprcom"); - i_oprnegate = PQfnumber(res,"oprnegate"); - i_oprrest = PQfnumber(res,"oprrest"); - i_oprjoin = PQfnumber(res,"oprjoin"); - i_oprcanhash = PQfnumber(res,"oprcanhash"); - i_oprlsortop = PQfnumber(res,"oprlsortop"); - i_oprrsortop = PQfnumber(res,"oprrsortop"); - i_usename = PQfnumber(res,"usename"); - - for (i=0;i<ntups;i++) { - oprinfo[i].oid = strdup(PQgetvalue(res,i,i_oid)); - oprinfo[i].oprname = strdup(PQgetvalue(res,i,i_oprname)); - oprinfo[i].oprkind = strdup(PQgetvalue(res,i,i_oprkind)); - oprinfo[i].oprcode = strdup(PQgetvalue(res,i,i_oprcode)); - oprinfo[i].oprleft = strdup(PQgetvalue(res,i,i_oprleft)); - oprinfo[i].oprright = strdup(PQgetvalue(res,i,i_oprright)); - oprinfo[i].oprcom = strdup(PQgetvalue(res,i,i_oprcom)); - oprinfo[i].oprnegate = strdup(PQgetvalue(res,i,i_oprnegate)); - oprinfo[i].oprrest = strdup(PQgetvalue(res,i,i_oprrest)); - oprinfo[i].oprjoin = strdup(PQgetvalue(res,i,i_oprjoin)); - oprinfo[i].oprcanhash = strdup(PQgetvalue(res,i,i_oprcanhash)); - oprinfo[i].oprlsortop = strdup(PQgetvalue(res,i,i_oprlsortop)); - oprinfo[i].oprrsortop = strdup(PQgetvalue(res,i,i_oprrsortop)); - oprinfo[i].usename = strdup(PQgetvalue(res,i,i_usename)); - } - - PQclear(res); - res = PQexec(g_conn, "end"); - PQclear(res); - - return oprinfo; + PGresult *res; + int ntups; + int i; + char query[MAXQUERYLEN]; + + OprInfo *oprinfo; + + int i_oid; + int i_oprname; + int i_oprkind; + int i_oprcode; + int i_oprleft; + int i_oprright; + int i_oprcom; + int i_oprnegate; + int i_oprrest; + int i_oprjoin; + int i_oprcanhash; + int i_oprlsortop; + int i_oprrsortop; + int i_usename; + + /* + * find all operators, including builtin operators, filter out + * system-defined operators at dump-out time + */ + res = PQexec(g_conn, "begin"); + if (!res || + PQresultStatus(res) != PGRES_COMMAND_OK) + { + fprintf(stderr, "BEGIN command failed\n"); + exit_nicely(g_conn); + } + PQclear(res); + + sprintf(query, "SELECT pg_operator.oid, oprname, oprkind, oprcode, " + "oprleft, oprright, oprcom, oprnegate, oprrest, oprjoin, " + "oprcanhash, oprlsortop, oprrsortop, usename " + "from pg_operator, pg_user " + "where oprowner = usesysid"); + + res = PQexec(g_conn, query); + if (!res || + PQresultStatus(res) != PGRES_TUPLES_OK) + { + fprintf(stderr, "getOperators(): SELECT failed\n"); + exit_nicely(g_conn); + } + + ntups = PQntuples(res); + *numOprs = ntups; + + oprinfo = (OprInfo *) malloc(ntups * sizeof(OprInfo)); + + i_oid = PQfnumber(res, "oid"); + i_oprname = PQfnumber(res, "oprname"); + i_oprkind = PQfnumber(res, "oprkind"); + i_oprcode = PQfnumber(res, "oprcode"); + i_oprleft = PQfnumber(res, "oprleft"); + i_oprright = PQfnumber(res, "oprright"); + i_oprcom = PQfnumber(res, "oprcom"); + i_oprnegate = PQfnumber(res, "oprnegate"); + i_oprrest = PQfnumber(res, "oprrest"); + i_oprjoin = PQfnumber(res, "oprjoin"); + i_oprcanhash = PQfnumber(res, "oprcanhash"); + i_oprlsortop = PQfnumber(res, "oprlsortop"); + i_oprrsortop = PQfnumber(res, "oprrsortop"); + i_usename = PQfnumber(res, "usename"); + + for (i = 0; i < ntups; i++) + { + oprinfo[i].oid = strdup(PQgetvalue(res, i, i_oid)); + oprinfo[i].oprname = strdup(PQgetvalue(res, i, i_oprname)); + oprinfo[i].oprkind = strdup(PQgetvalue(res, i, i_oprkind)); + oprinfo[i].oprcode = strdup(PQgetvalue(res, i, i_oprcode)); + oprinfo[i].oprleft = strdup(PQgetvalue(res, i, i_oprleft)); + oprinfo[i].oprright = strdup(PQgetvalue(res, i, i_oprright)); + oprinfo[i].oprcom = strdup(PQgetvalue(res, i, i_oprcom)); + oprinfo[i].oprnegate = strdup(PQgetvalue(res, i, i_oprnegate)); + oprinfo[i].oprrest = strdup(PQgetvalue(res, i, i_oprrest)); + oprinfo[i].oprjoin = strdup(PQgetvalue(res, i, i_oprjoin)); + oprinfo[i].oprcanhash = strdup(PQgetvalue(res, i, i_oprcanhash)); + oprinfo[i].oprlsortop = strdup(PQgetvalue(res, i, i_oprlsortop)); + oprinfo[i].oprrsortop = strdup(PQgetvalue(res, i, i_oprrsortop)); + oprinfo[i].usename = strdup(PQgetvalue(res, i, i_usename)); + } + + PQclear(res); + res = PQexec(g_conn, "end"); + PQclear(res); + + return oprinfo; } void -clearTypeInfo(TypeInfo *tp, int numTypes) +clearTypeInfo(TypeInfo * tp, int numTypes) { - int i; - for(i=0;i<numTypes;++i) { - if(tp[i].oid) free(tp[i].oid); - if(tp[i].typowner) free(tp[i].typowner); - if(tp[i].typname) free(tp[i].typname); - if(tp[i].typlen) free(tp[i].typlen); - if(tp[i].typprtlen) free(tp[i].typprtlen); - if(tp[i].typinput) free(tp[i].typinput); - if(tp[i].typoutput) free(tp[i].typoutput); - if(tp[i].typreceive) free(tp[i].typreceive); - if(tp[i].typsend) free(tp[i].typsend); - if(tp[i].typelem) free(tp[i].typelem); - if(tp[i].typdelim) free(tp[i].typdelim); - if(tp[i].typdefault) free(tp[i].typdefault); - if(tp[i].typrelid) free(tp[i].typrelid); - if(tp[i].usename) free(tp[i].usename); - } - free(tp); + int i; + + for (i = 0; i < numTypes; ++i) + { + if (tp[i].oid) + free(tp[i].oid); + if (tp[i].typowner) + free(tp[i].typowner); + if (tp[i].typname) + free(tp[i].typname); + if (tp[i].typlen) + free(tp[i].typlen); + if (tp[i].typprtlen) + free(tp[i].typprtlen); + if (tp[i].typinput) + free(tp[i].typinput); + if (tp[i].typoutput) + free(tp[i].typoutput); + if (tp[i].typreceive) + free(tp[i].typreceive); + if (tp[i].typsend) + free(tp[i].typsend); + if (tp[i].typelem) + free(tp[i].typelem); + if (tp[i].typdelim) + free(tp[i].typdelim); + if (tp[i].typdefault) + free(tp[i].typdefault); + if (tp[i].typrelid) + free(tp[i].typrelid); + if (tp[i].usename) + free(tp[i].usename); + } + free(tp); } void -clearFuncInfo (FuncInfo *fun, int numFuncs) +clearFuncInfo(FuncInfo * fun, int numFuncs) { - int i,a; - if(!fun) return; - for(i=0;i<numFuncs;++i) { - if(fun[i].oid) free(fun[i].oid); - if(fun[i].proname) free(fun[i].proname); - if(fun[i].usename) free(fun[i].usename); - for(a=0;a<8;++a) - if(fun[i].argtypes[a]) free(fun[i].argtypes[a]); - if(fun[i].prorettype) free(fun[i].prorettype); - if(fun[i].prosrc) free(fun[i].prosrc); - if(fun[i].probin) free(fun[i].probin); - } - free(fun); + int i, + a; + + if (!fun) + return; + for (i = 0; i < numFuncs; ++i) + { + if (fun[i].oid) + free(fun[i].oid); + if (fun[i].proname) + free(fun[i].proname); + if (fun[i].usename) + free(fun[i].usename); + for (a = 0; a < 8; ++a) + if (fun[i].argtypes[a]) + free(fun[i].argtypes[a]); + if (fun[i].prorettype) + free(fun[i].prorettype); + if (fun[i].prosrc) + free(fun[i].prosrc); + if (fun[i].probin) + free(fun[i].probin); + } + free(fun); } static void -clearTableInfo(TableInfo *tblinfo, int numTables) +clearTableInfo(TableInfo * tblinfo, int numTables) { - int i,j; - for(i=0;i<numTables;++i) { - - if(tblinfo[i].oid) free (tblinfo[i].oid); - if(tblinfo[i].relarch) free (tblinfo[i].relarch); - if(tblinfo[i].relacl) free (tblinfo[i].relacl); - if(tblinfo[i].usename) free (tblinfo[i].usename); - - /* skip archive tables */ - if (isArchiveName(tblinfo[i].relname)) - { - if(tblinfo[i].relname) free (tblinfo[i].relname); - continue; - } - if(tblinfo[i].relname) free (tblinfo[i].relname); - - if ( tblinfo[i].sequence ) - continue; - - /* Process Attributes */ - for(j=0;j<tblinfo[i].numatts;j++) { - if(tblinfo[i].attnames[j]) free (tblinfo[i].attnames[j]); - if(tblinfo[i].typnames[j]) free (tblinfo[i].typnames[j]); - } - if(tblinfo[i].attlen) free((int *)tblinfo[i].attlen); - if(tblinfo[i].inhAttrs) free((int *)tblinfo[i].inhAttrs); - if(tblinfo[i].attnames) free (tblinfo[i].attnames); - if(tblinfo[i].typnames) free (tblinfo[i].typnames); - if(tblinfo[i].notnull) free (tblinfo[i].notnull); - - } - free(tblinfo); + int i, + j; + + for (i = 0; i < numTables; ++i) + { + + if (tblinfo[i].oid) + free(tblinfo[i].oid); + if (tblinfo[i].relarch) + free(tblinfo[i].relarch); + if (tblinfo[i].relacl) + free(tblinfo[i].relacl); + if (tblinfo[i].usename) + free(tblinfo[i].usename); + + /* skip archive tables */ + if (isArchiveName(tblinfo[i].relname)) + { + if (tblinfo[i].relname) + free(tblinfo[i].relname); + continue; + } + if (tblinfo[i].relname) + free(tblinfo[i].relname); + + if (tblinfo[i].sequence) + continue; + + /* Process Attributes */ + for (j = 0; j < tblinfo[i].numatts; j++) + { + if (tblinfo[i].attnames[j]) + free(tblinfo[i].attnames[j]); + if (tblinfo[i].typnames[j]) + free(tblinfo[i].typnames[j]); + } + if (tblinfo[i].attlen) + free((int *) tblinfo[i].attlen); + if (tblinfo[i].inhAttrs) + free((int *) tblinfo[i].inhAttrs); + if (tblinfo[i].attnames) + free(tblinfo[i].attnames); + if (tblinfo[i].typnames) + free(tblinfo[i].typnames); + if (tblinfo[i].notnull) + free(tblinfo[i].notnull); + + } + free(tblinfo); } -void -clearInhInfo (InhInfo *inh, int numInherits) { - int i; - if(!inh) return; - for(i=0;i<numInherits;++i) { - if(inh[i].inhrel) free(inh[i].inhrel); - if(inh[i].inhparent) free(inh[i].inhparent); - } - free(inh); +void +clearInhInfo(InhInfo * inh, int numInherits) +{ + int i; + + if (!inh) + return; + for (i = 0; i < numInherits; ++i) + { + if (inh[i].inhrel) + free(inh[i].inhrel); + if (inh[i].inhparent) + free(inh[i].inhparent); + } + free(inh); } void -clearOprInfo(OprInfo *opr, int numOprs){ - int i; - if(!opr) return; - for(i=0;i<numOprs;++i) { - if(opr[i].oid) free(opr[i].oid); - if(opr[i].oprname) free(opr[i].oprname); - if(opr[i].oprkind) free(opr[i].oprkind); - if(opr[i].oprcode) free(opr[i].oprcode); - if(opr[i].oprleft) free(opr[i].oprleft); - if(opr[i].oprright) free(opr[i].oprright); - if(opr[i].oprcom) free(opr[i].oprcom); - if(opr[i].oprnegate) free(opr[i].oprnegate); - if(opr[i].oprrest) free(opr[i].oprrest); - if(opr[i].oprjoin) free(opr[i].oprjoin); - if(opr[i].oprcanhash) free(opr[i].oprcanhash); - if(opr[i].oprlsortop) free(opr[i].oprlsortop); - if(opr[i].oprrsortop) free(opr[i].oprrsortop); - if(opr[i].usename) free(opr[i].usename); - } - free(opr); +clearOprInfo(OprInfo * opr, int numOprs) +{ + int i; + + if (!opr) + return; + for (i = 0; i < numOprs; ++i) + { + if (opr[i].oid) + free(opr[i].oid); + if (opr[i].oprname) + free(opr[i].oprname); + if (opr[i].oprkind) + free(opr[i].oprkind); + if (opr[i].oprcode) + free(opr[i].oprcode); + if (opr[i].oprleft) + free(opr[i].oprleft); + if (opr[i].oprright) + free(opr[i].oprright); + if (opr[i].oprcom) + free(opr[i].oprcom); + if (opr[i].oprnegate) + free(opr[i].oprnegate); + if (opr[i].oprrest) + free(opr[i].oprrest); + if (opr[i].oprjoin) + free(opr[i].oprjoin); + if (opr[i].oprcanhash) + free(opr[i].oprcanhash); + if (opr[i].oprlsortop) + free(opr[i].oprlsortop); + if (opr[i].oprrsortop) + free(opr[i].oprrsortop); + if (opr[i].usename) + free(opr[i].usename); + } + free(opr); } void -clearIndInfo(IndInfo *ind, int numIndices) +clearIndInfo(IndInfo * ind, int numIndices) { - int i,a; - if(!ind) return; - for(i=0;i<numIndices;++i) { - if(ind[i].indexrelname) free(ind[i].indexrelname); - if(ind[i].indrelname) free(ind[i].indrelname); - if(ind[i].indamname) free(ind[i].indamname); - if(ind[i].indproc) free(ind[i].indproc); - if(ind[i].indisunique) free(ind[i].indisunique); - for(a=0;a<INDEX_MAX_KEYS;++a) { - if(ind[i].indkey[a]) free(ind[i].indkey[a]); - if(ind[i].indclass[a]) free(ind[i].indclass[a]); - } - } - free(ind); + int i, + a; + + if (!ind) + return; + for (i = 0; i < numIndices; ++i) + { + if (ind[i].indexrelname) + free(ind[i].indexrelname); + if (ind[i].indrelname) + free(ind[i].indrelname); + if (ind[i].indamname) + free(ind[i].indamname); + if (ind[i].indproc) + free(ind[i].indproc); + if (ind[i].indisunique) + free(ind[i].indisunique); + for (a = 0; a < INDEX_MAX_KEYS; ++a) + { + if (ind[i].indkey[a]) + free(ind[i].indkey[a]); + if (ind[i].indclass[a]) + free(ind[i].indclass[a]); + } + } + free(ind); } void -clearAggInfo(AggInfo *agginfo, int numArgs) +clearAggInfo(AggInfo * agginfo, int numArgs) { - int i; - if(!agginfo) return; - for(i=0;i<numArgs;++i) { - if(agginfo[i].oid) free (agginfo[i].oid); - if(agginfo[i].aggname) free (agginfo[i].aggname); - if(agginfo[i].aggtransfn1) free (agginfo[i].aggtransfn1); - if(agginfo[i].aggtransfn2) free (agginfo[i].aggtransfn2); - if(agginfo[i].aggfinalfn) free (agginfo[i].aggfinalfn); - if(agginfo[i].aggtranstype1) free (agginfo[i].aggtranstype1); - if(agginfo[i].aggbasetype) free (agginfo[i].aggbasetype); - if(agginfo[i].aggtranstype2) free (agginfo[i].aggtranstype2); - if(agginfo[i].agginitval1) free (agginfo[i].agginitval1); - if(agginfo[i].agginitval2) free (agginfo[i].agginitval2); - if(agginfo[i].usename) free (agginfo[i].usename); - } - free (agginfo); + int i; + + if (!agginfo) + return; + for (i = 0; i < numArgs; ++i) + { + if (agginfo[i].oid) + free(agginfo[i].oid); + if (agginfo[i].aggname) + free(agginfo[i].aggname); + if (agginfo[i].aggtransfn1) + free(agginfo[i].aggtransfn1); + if (agginfo[i].aggtransfn2) + free(agginfo[i].aggtransfn2); + if (agginfo[i].aggfinalfn) + free(agginfo[i].aggfinalfn); + if (agginfo[i].aggtranstype1) + free(agginfo[i].aggtranstype1); + if (agginfo[i].aggbasetype) + free(agginfo[i].aggbasetype); + if (agginfo[i].aggtranstype2) + free(agginfo[i].aggtranstype2); + if (agginfo[i].agginitval1) + free(agginfo[i].agginitval1); + if (agginfo[i].agginitval2) + free(agginfo[i].agginitval2); + if (agginfo[i].usename) + free(agginfo[i].usename); + } + free(agginfo); } /* * getAggregates: - * read all the user-defined aggregates in the system catalogs and + * read all the user-defined aggregates in the system catalogs and * return them in the AggInfo* structure * - * numAggs is set to the number of aggregates read in - * + * numAggs is set to the number of aggregates read in + * * */ -AggInfo* +AggInfo * getAggregates(int *numAggs) { - PGresult* res; - int ntups; - int i; - char query[MAXQUERYLEN]; - AggInfo *agginfo; - - int i_oid; - int i_aggname; - int i_aggtransfn1; - int i_aggtransfn2; - int i_aggfinalfn; - int i_aggtranstype1; - int i_aggbasetype; - int i_aggtranstype2; - int i_agginitval1; - int i_agginitval2; - int i_usename; - - /* find all user-defined aggregates */ - - res = PQexec(g_conn, "begin"); - if (!res || - PQresultStatus(res) != PGRES_COMMAND_OK) { - fprintf(stderr,"BEGIN command failed\n"); - exit_nicely(g_conn); - } - PQclear(res); - - sprintf(query, - "SELECT pg_aggregate.oid, aggname, aggtransfn1, aggtransfn2, " - "aggfinalfn, aggtranstype1, aggbasetype, aggtranstype2, " - "agginitval1, agginitval2, usename from pg_aggregate, pg_user " - "where aggowner = usesysid"); - - res = PQexec(g_conn, query); - if (!res || - PQresultStatus(res) != PGRES_TUPLES_OK) { - fprintf(stderr,"getAggregates(): SELECT failed\n"); - exit_nicely(g_conn); - } - - ntups = PQntuples(res); - *numAggs = ntups; - - agginfo = (AggInfo*)malloc(ntups * sizeof(AggInfo)); - - i_oid = PQfnumber(res,"oid"); - i_aggname = PQfnumber(res,"aggname"); - i_aggtransfn1 = PQfnumber(res,"aggtransfn1"); - i_aggtransfn2 = PQfnumber(res,"aggtransfn2"); - i_aggfinalfn = PQfnumber(res,"aggfinalfn"); - i_aggtranstype1 = PQfnumber(res,"aggtranstype1"); - i_aggbasetype = PQfnumber(res,"aggbasetype"); - i_aggtranstype2 = PQfnumber(res,"aggtranstype2"); - i_agginitval1 = PQfnumber(res,"agginitval1"); - i_agginitval2 = PQfnumber(res,"agginitval2"); - i_usename = PQfnumber(res,"usename"); - - for (i=0;i<ntups;i++) { - agginfo[i].oid = strdup(PQgetvalue(res,i,i_oid)); - agginfo[i].aggname = strdup(PQgetvalue(res,i,i_aggname)); - agginfo[i].aggtransfn1 = strdup(PQgetvalue(res,i,i_aggtransfn1)); - agginfo[i].aggtransfn2 = strdup(PQgetvalue(res,i,i_aggtransfn2)); - agginfo[i].aggfinalfn = strdup(PQgetvalue(res,i,i_aggfinalfn)); - agginfo[i].aggtranstype1 = strdup(PQgetvalue(res,i,i_aggtranstype1)); - agginfo[i].aggbasetype = strdup(PQgetvalue(res,i,i_aggbasetype)); - agginfo[i].aggtranstype2 = strdup(PQgetvalue(res,i,i_aggtranstype2)); - agginfo[i].agginitval1 = strdup(PQgetvalue(res,i,i_agginitval1)); - agginfo[i].agginitval2 = strdup(PQgetvalue(res,i,i_agginitval2)); - agginfo[i].usename = strdup(PQgetvalue(res,i,i_usename)); - } - - PQclear(res); - - res = PQexec(g_conn, "end"); - PQclear(res); - return agginfo; + PGresult *res; + int ntups; + int i; + char query[MAXQUERYLEN]; + AggInfo *agginfo; + + int i_oid; + int i_aggname; + int i_aggtransfn1; + int i_aggtransfn2; + int i_aggfinalfn; + int i_aggtranstype1; + int i_aggbasetype; + int i_aggtranstype2; + int i_agginitval1; + int i_agginitval2; + int i_usename; + + /* find all user-defined aggregates */ + + res = PQexec(g_conn, "begin"); + if (!res || + PQresultStatus(res) != PGRES_COMMAND_OK) + { + fprintf(stderr, "BEGIN command failed\n"); + exit_nicely(g_conn); + } + PQclear(res); + + sprintf(query, + "SELECT pg_aggregate.oid, aggname, aggtransfn1, aggtransfn2, " + "aggfinalfn, aggtranstype1, aggbasetype, aggtranstype2, " + "agginitval1, agginitval2, usename from pg_aggregate, pg_user " + "where aggowner = usesysid"); + + res = PQexec(g_conn, query); + if (!res || + PQresultStatus(res) != PGRES_TUPLES_OK) + { + fprintf(stderr, "getAggregates(): SELECT failed\n"); + exit_nicely(g_conn); + } + + ntups = PQntuples(res); + *numAggs = ntups; + + agginfo = (AggInfo *) malloc(ntups * sizeof(AggInfo)); + + i_oid = PQfnumber(res, "oid"); + i_aggname = PQfnumber(res, "aggname"); + i_aggtransfn1 = PQfnumber(res, "aggtransfn1"); + i_aggtransfn2 = PQfnumber(res, "aggtransfn2"); + i_aggfinalfn = PQfnumber(res, "aggfinalfn"); + i_aggtranstype1 = PQfnumber(res, "aggtranstype1"); + i_aggbasetype = PQfnumber(res, "aggbasetype"); + i_aggtranstype2 = PQfnumber(res, "aggtranstype2"); + i_agginitval1 = PQfnumber(res, "agginitval1"); + i_agginitval2 = PQfnumber(res, "agginitval2"); + i_usename = PQfnumber(res, "usename"); + + for (i = 0; i < ntups; i++) + { + agginfo[i].oid = strdup(PQgetvalue(res, i, i_oid)); + agginfo[i].aggname = strdup(PQgetvalue(res, i, i_aggname)); + agginfo[i].aggtransfn1 = strdup(PQgetvalue(res, i, i_aggtransfn1)); + agginfo[i].aggtransfn2 = strdup(PQgetvalue(res, i, i_aggtransfn2)); + agginfo[i].aggfinalfn = strdup(PQgetvalue(res, i, i_aggfinalfn)); + agginfo[i].aggtranstype1 = strdup(PQgetvalue(res, i, i_aggtranstype1)); + agginfo[i].aggbasetype = strdup(PQgetvalue(res, i, i_aggbasetype)); + agginfo[i].aggtranstype2 = strdup(PQgetvalue(res, i, i_aggtranstype2)); + agginfo[i].agginitval1 = strdup(PQgetvalue(res, i, i_agginitval1)); + agginfo[i].agginitval2 = strdup(PQgetvalue(res, i, i_agginitval2)); + agginfo[i].usename = strdup(PQgetvalue(res, i, i_usename)); + } + + PQclear(res); + + res = PQexec(g_conn, "end"); + PQclear(res); + return agginfo; } /* * getFuncs: - * read all the user-defined functions in the system catalogs and + * read all the user-defined functions in the system catalogs and * return them in the FuncInfo* structure * - * numFuncs is set to the number of functions read in - * + * numFuncs is set to the number of functions read in + * * */ -FuncInfo* +FuncInfo * getFuncs(int *numFuncs) { - PGresult *res; - int ntups; - int i; - char query[MAXQUERYLEN]; - FuncInfo *finfo; - - int i_oid; - int i_proname; - int i_prolang; - int i_pronargs; - int i_proargtypes; - int i_prorettype; - int i_proretset; - int i_prosrc; - int i_probin; - int i_usename; - - /* find all user-defined funcs */ - - res = PQexec(g_conn, "begin"); - if (!res || - PQresultStatus(res) != PGRES_COMMAND_OK) { - fprintf(stderr,"BEGIN command failed\n"); - exit_nicely(g_conn); - } - PQclear(res); - - sprintf(query, - "SELECT pg_proc.oid, proname, prolang, pronargs, prorettype, " - "proretset, proargtypes, prosrc, probin, usename " - "from pg_proc, pg_user " - "where pg_proc.oid > '%d'::oid and proowner = usesysid", - g_last_builtin_oid); - - res = PQexec(g_conn, query); - if (!res || - PQresultStatus(res) != PGRES_TUPLES_OK) { - fprintf(stderr,"getFuncs(): SELECT failed\n"); - exit_nicely(g_conn); - } - - ntups = PQntuples(res); - - *numFuncs = ntups; - - finfo = (FuncInfo*)malloc(ntups * sizeof(FuncInfo)); - - i_oid = PQfnumber(res,"oid"); - i_proname = PQfnumber(res,"proname"); - i_prolang = PQfnumber(res,"prolang"); - i_pronargs = PQfnumber(res,"pronargs"); - i_proargtypes = PQfnumber(res,"proargtypes"); - i_prorettype = PQfnumber(res,"prorettype"); - i_proretset = PQfnumber(res,"proretset"); - i_prosrc = PQfnumber(res,"prosrc"); - i_probin = PQfnumber(res,"probin"); - i_usename = PQfnumber(res,"usename"); - - for (i=0;i<ntups;i++) { - finfo[i].oid = strdup(PQgetvalue(res,i,i_oid)); - finfo[i].proname = strdup(PQgetvalue(res,i,i_proname)); - - finfo[i].prosrc = checkForQuote(PQgetvalue(res,i,i_prosrc)); - finfo[i].probin = strdup(PQgetvalue(res,i,i_probin)); - - finfo[i].prorettype = strdup(PQgetvalue(res,i,i_prorettype)); - finfo[i].retset = (strcmp(PQgetvalue(res,i,i_proretset),"t") == 0); - finfo[i].nargs = atoi(PQgetvalue(res,i,i_pronargs)); - finfo[i].lang = (atoi(PQgetvalue(res,i,i_prolang)) == C_PROLANG_OID); - - finfo[i].usename = strdup(PQgetvalue(res,i,i_usename)); - - parseArgTypes(finfo[i].argtypes, PQgetvalue(res,i,i_proargtypes)); - - finfo[i].dumped = 0; - } - - PQclear(res); - res = PQexec(g_conn, "end"); - PQclear(res); - - return finfo; + PGresult *res; + int ntups; + int i; + char query[MAXQUERYLEN]; + FuncInfo *finfo; + + int i_oid; + int i_proname; + int i_prolang; + int i_pronargs; + int i_proargtypes; + int i_prorettype; + int i_proretset; + int i_prosrc; + int i_probin; + int i_usename; + + /* find all user-defined funcs */ + + res = PQexec(g_conn, "begin"); + if (!res || + PQresultStatus(res) != PGRES_COMMAND_OK) + { + fprintf(stderr, "BEGIN command failed\n"); + exit_nicely(g_conn); + } + PQclear(res); + + sprintf(query, + "SELECT pg_proc.oid, proname, prolang, pronargs, prorettype, " + "proretset, proargtypes, prosrc, probin, usename " + "from pg_proc, pg_user " + "where pg_proc.oid > '%d'::oid and proowner = usesysid", + g_last_builtin_oid); + + res = PQexec(g_conn, query); + if (!res || + PQresultStatus(res) != PGRES_TUPLES_OK) + { + fprintf(stderr, "getFuncs(): SELECT failed\n"); + exit_nicely(g_conn); + } + + ntups = PQntuples(res); + + *numFuncs = ntups; + + finfo = (FuncInfo *) malloc(ntups * sizeof(FuncInfo)); + + i_oid = PQfnumber(res, "oid"); + i_proname = PQfnumber(res, "proname"); + i_prolang = PQfnumber(res, "prolang"); + i_pronargs = PQfnumber(res, "pronargs"); + i_proargtypes = PQfnumber(res, "proargtypes"); + i_prorettype = PQfnumber(res, "prorettype"); + i_proretset = PQfnumber(res, "proretset"); + i_prosrc = PQfnumber(res, "prosrc"); + i_probin = PQfnumber(res, "probin"); + i_usename = PQfnumber(res, "usename"); + + for (i = 0; i < ntups; i++) + { + finfo[i].oid = strdup(PQgetvalue(res, i, i_oid)); + finfo[i].proname = strdup(PQgetvalue(res, i, i_proname)); + + finfo[i].prosrc = checkForQuote(PQgetvalue(res, i, i_prosrc)); + finfo[i].probin = strdup(PQgetvalue(res, i, i_probin)); + + finfo[i].prorettype = strdup(PQgetvalue(res, i, i_prorettype)); + finfo[i].retset = (strcmp(PQgetvalue(res, i, i_proretset), "t") == 0); + finfo[i].nargs = atoi(PQgetvalue(res, i, i_pronargs)); + finfo[i].lang = (atoi(PQgetvalue(res, i, i_prolang)) == C_PROLANG_OID); + + finfo[i].usename = strdup(PQgetvalue(res, i, i_usename)); + + parseArgTypes(finfo[i].argtypes, PQgetvalue(res, i, i_proargtypes)); + + finfo[i].dumped = 0; + } + + PQclear(res); + res = PQexec(g_conn, "end"); + PQclear(res); + + return finfo; } /* * getTables - * read all the user-defined tables (no indices, no catalogs) + * read all the user-defined tables (no indices, no catalogs) * in the system catalogs return them in the TableInfo* structure * - * numTables is set to the number of tables read in - * + * numTables is set to the number of tables read in + * * */ -TableInfo* +TableInfo * getTables(int *numTables) { - PGresult *res; - int ntups; - int i; - char query[MAXQUERYLEN]; - TableInfo *tblinfo; - - int i_oid; - int i_relname; - int i_relarch; - int i_relkind; - int i_relacl; - int i_usename; - - /* find all the user-defined tables (no indices and no catalogs), - ordering by oid is important so that we always process the parent - tables before the child tables when traversing the tblinfo* - - we ignore tables that start with xinv */ - - res = PQexec(g_conn, "begin"); - if (!res || - PQresultStatus(res) != PGRES_COMMAND_OK) { - fprintf(stderr,"BEGIN command failed\n"); - exit_nicely(g_conn); - } - PQclear(res); - - sprintf(query, - "SELECT pg_class.oid, relname, relarch, relkind, relacl, usename " - "from pg_class, pg_user " - "where relowner = usesysid and " - "(relkind = 'r' or relkind = 'S') and relname !~ '^pg_' " - "and relname !~ '^xin[xv][0-9]+' order by oid"); - - res = PQexec(g_conn, query); - if (!res || - PQresultStatus(res) != PGRES_TUPLES_OK) { - fprintf(stderr,"getTables(): SELECT failed\n"); - exit_nicely(g_conn); - } - - ntups = PQntuples(res); - - *numTables = ntups; - - tblinfo = (TableInfo*)malloc(ntups * sizeof(TableInfo)); - - i_oid = PQfnumber(res,"oid"); - i_relname = PQfnumber(res,"relname"); - i_relarch = PQfnumber(res,"relarch"); - i_relkind = PQfnumber(res,"relkind"); - i_relacl = PQfnumber(res,"relacl"); - i_usename = PQfnumber(res,"usename"); - - for (i=0;i<ntups;i++) { - tblinfo[i].oid = strdup(PQgetvalue(res,i,i_oid)); - tblinfo[i].relname = strdup(PQgetvalue(res,i,i_relname)); - tblinfo[i].relarch = strdup(PQgetvalue(res,i,i_relarch)); - tblinfo[i].relacl = strdup(PQgetvalue(res,i,i_relacl)); - tblinfo[i].sequence = (strcmp (PQgetvalue(res,i,i_relkind), "S") == 0); - tblinfo[i].usename = strdup(PQgetvalue(res,i,i_usename)); - } - - PQclear(res); - res = PQexec(g_conn, "end"); - PQclear(res); - - return tblinfo; + PGresult *res; + int ntups; + int i; + char query[MAXQUERYLEN]; + TableInfo *tblinfo; + + int i_oid; + int i_relname; + int i_relarch; + int i_relkind; + int i_relacl; + int i_usename; + + /* + * find all the user-defined tables (no indices and no catalogs), + * ordering by oid is important so that we always process the parent + * tables before the child tables when traversing the tblinfo* + * + * we ignore tables that start with xinv + */ + + res = PQexec(g_conn, "begin"); + if (!res || + PQresultStatus(res) != PGRES_COMMAND_OK) + { + fprintf(stderr, "BEGIN command failed\n"); + exit_nicely(g_conn); + } + PQclear(res); + + sprintf(query, + "SELECT pg_class.oid, relname, relarch, relkind, relacl, usename " + "from pg_class, pg_user " + "where relowner = usesysid and " + "(relkind = 'r' or relkind = 'S') and relname !~ '^pg_' " + "and relname !~ '^xin[xv][0-9]+' order by oid"); + + res = PQexec(g_conn, query); + if (!res || + PQresultStatus(res) != PGRES_TUPLES_OK) + { + fprintf(stderr, "getTables(): SELECT failed\n"); + exit_nicely(g_conn); + } + + ntups = PQntuples(res); + + *numTables = ntups; + + tblinfo = (TableInfo *) malloc(ntups * sizeof(TableInfo)); + + i_oid = PQfnumber(res, "oid"); + i_relname = PQfnumber(res, "relname"); + i_relarch = PQfnumber(res, "relarch"); + i_relkind = PQfnumber(res, "relkind"); + i_relacl = PQfnumber(res, "relacl"); + i_usename = PQfnumber(res, "usename"); + + for (i = 0; i < ntups; i++) + { + tblinfo[i].oid = strdup(PQgetvalue(res, i, i_oid)); + tblinfo[i].relname = strdup(PQgetvalue(res, i, i_relname)); + tblinfo[i].relarch = strdup(PQgetvalue(res, i, i_relarch)); + tblinfo[i].relacl = strdup(PQgetvalue(res, i, i_relacl)); + tblinfo[i].sequence = (strcmp(PQgetvalue(res, i, i_relkind), "S") == 0); + tblinfo[i].usename = strdup(PQgetvalue(res, i, i_usename)); + } + + PQclear(res); + res = PQexec(g_conn, "end"); + PQclear(res); + + return tblinfo; } /* * getInherits - * read all the inheritance information + * read all the inheritance information * from the system catalogs return them in the InhInfo* structure * - * numInherits is set to the number of tables read in - * + * numInherits is set to the number of tables read in + * * */ -InhInfo* +InhInfo * getInherits(int *numInherits) { - PGresult *res; - int ntups; - int i; - char query[MAXQUERYLEN]; - InhInfo *inhinfo; - - int i_inhrel; - int i_inhparent; - - /* find all the inheritance information */ - res = PQexec(g_conn, "begin"); - if (!res || - PQresultStatus(res) != PGRES_COMMAND_OK) { - fprintf(stderr,"BEGIN command failed\n"); - exit_nicely(g_conn); - } - PQclear(res); - - sprintf(query, "SELECT inhrel, inhparent from pg_inherits"); - - res = PQexec(g_conn, query); - if (!res || - PQresultStatus(res) != PGRES_TUPLES_OK) { - fprintf(stderr,"getInherits(): SELECT failed\n"); - exit_nicely(g_conn); - } - - ntups = PQntuples(res); - - *numInherits = ntups; - - inhinfo = (InhInfo*)malloc(ntups * sizeof(InhInfo)); - - i_inhrel = PQfnumber(res,"inhrel"); - i_inhparent = PQfnumber(res,"inhparent"); - - for (i=0;i<ntups;i++) { - inhinfo[i].inhrel = strdup(PQgetvalue(res,i,i_inhrel)); - inhinfo[i].inhparent = strdup(PQgetvalue(res,i,i_inhparent)); - } - - PQclear(res); - res = PQexec(g_conn, "end"); - PQclear(res); - return inhinfo; + PGresult *res; + int ntups; + int i; + char query[MAXQUERYLEN]; + InhInfo *inhinfo; + + int i_inhrel; + int i_inhparent; + + /* find all the inheritance information */ + res = PQexec(g_conn, "begin"); + if (!res || + PQresultStatus(res) != PGRES_COMMAND_OK) + { + fprintf(stderr, "BEGIN command failed\n"); + exit_nicely(g_conn); + } + PQclear(res); + + sprintf(query, "SELECT inhrel, inhparent from pg_inherits"); + + res = PQexec(g_conn, query); + if (!res || + PQresultStatus(res) != PGRES_TUPLES_OK) + { + fprintf(stderr, "getInherits(): SELECT failed\n"); + exit_nicely(g_conn); + } + + ntups = PQntuples(res); + + *numInherits = ntups; + + inhinfo = (InhInfo *) malloc(ntups * sizeof(InhInfo)); + + i_inhrel = PQfnumber(res, "inhrel"); + i_inhparent = PQfnumber(res, "inhparent"); + + for (i = 0; i < ntups; i++) + { + inhinfo[i].inhrel = strdup(PQgetvalue(res, i, i_inhrel)); + inhinfo[i].inhparent = strdup(PQgetvalue(res, i, i_inhparent)); + } + + PQclear(res); + res = PQexec(g_conn, "end"); + PQclear(res); + return inhinfo; } /* * getTableAttrs - - * for each table in tblinfo, read its attributes types and names - * + * for each table in tblinfo, read its attributes types and names + * * this is implemented in a very inefficient way right now, looping - * through the tblinfo and doing a join per table to find the attrs and their + * through the tblinfo and doing a join per table to find the attrs and their * types * - * modifies tblinfo + * modifies tblinfo */ void -getTableAttrs(TableInfo* tblinfo, int numTables) +getTableAttrs(TableInfo * tblinfo, int numTables) { - int i,j; - char q[MAXQUERYLEN]; - int i_attname; - int i_typname; - int i_attlen; - int i_attnotnull; - PGresult *res; - int ntups; - - for (i=0;i<numTables;i++) { - - /* skip archive tables */ - if (isArchiveName(tblinfo[i].relname)) - continue; - - if ( tblinfo[i].sequence ) - continue; - - /* find all the user attributes and their types*/ - /* we must read the attribute names in attribute number order! */ - /* because we will use the attnum to index into the attnames array - later */ - if (g_verbose) - fprintf(stderr,"%s finding the attrs and types for table: %s %s\n", - g_comment_start, - tblinfo[i].relname, - g_comment_end); - - sprintf(q,"SELECT a.attnum, a.attname, t.typname, a.attlen, a.attnotnull " - "from pg_attribute a, pg_type t " - "where a.attrelid = '%s'::oid and a.atttypid = t.oid " - "and a.attnum > 0 order by attnum", - tblinfo[i].oid); - res = PQexec(g_conn, q); - if (!res || - PQresultStatus(res) != PGRES_TUPLES_OK) { - fprintf(stderr,"getTableAttrs(): SELECT failed\n"); - exit_nicely(g_conn); - } - - ntups = PQntuples(res); - - i_attname = PQfnumber(res,"attname"); - i_typname = PQfnumber(res,"typname"); - i_attlen = PQfnumber(res,"attlen"); - i_attnotnull = PQfnumber(res,"attnotnull"); - - tblinfo[i].numatts = ntups; - tblinfo[i].attnames = (char**) malloc( ntups * sizeof(char*)); - tblinfo[i].typnames = (char**) malloc( ntups * sizeof(char*)); - tblinfo[i].attlen = (int*) malloc(ntups * sizeof(int)); - tblinfo[i].inhAttrs = (int*) malloc (ntups * sizeof(int)); - tblinfo[i].notnull = (bool*) malloc (ntups * sizeof(bool)); - tblinfo[i].parentRels = NULL; - tblinfo[i].numParents = 0; - for (j=0;j<ntups;j++) { - tblinfo[i].attnames[j] = strdup(PQgetvalue(res,j,i_attname)); - tblinfo[i].typnames[j] = strdup(PQgetvalue(res,j,i_typname)); - tblinfo[i].attlen[j] = atoi(PQgetvalue(res,j,i_attlen)); - if (tblinfo[i].attlen[j] > 0) - tblinfo[i].attlen[j] = tblinfo[i].attlen[j] - 4; - tblinfo[i].inhAttrs[j] = 0; /* this flag is set in flagInhAttrs()*/ - tblinfo[i].notnull[j] = (PQgetvalue(res,j,i_attnotnull)[0]=='t')?true:false; - } - PQclear(res); - } + int i, + j; + char q[MAXQUERYLEN]; + int i_attname; + int i_typname; + int i_attlen; + int i_attnotnull; + PGresult *res; + int ntups; + + for (i = 0; i < numTables; i++) + { + + /* skip archive tables */ + if (isArchiveName(tblinfo[i].relname)) + continue; + + if (tblinfo[i].sequence) + continue; + + /* find all the user attributes and their types */ + /* we must read the attribute names in attribute number order! */ + + /* + * because we will use the attnum to index into the attnames array + * later + */ + if (g_verbose) + fprintf(stderr, "%s finding the attrs and types for table: %s %s\n", + g_comment_start, + tblinfo[i].relname, + g_comment_end); + + sprintf(q, "SELECT a.attnum, a.attname, t.typname, a.attlen, a.attnotnull " + "from pg_attribute a, pg_type t " + "where a.attrelid = '%s'::oid and a.atttypid = t.oid " + "and a.attnum > 0 order by attnum", + tblinfo[i].oid); + res = PQexec(g_conn, q); + if (!res || + PQresultStatus(res) != PGRES_TUPLES_OK) + { + fprintf(stderr, "getTableAttrs(): SELECT failed\n"); + exit_nicely(g_conn); + } + + ntups = PQntuples(res); + + i_attname = PQfnumber(res, "attname"); + i_typname = PQfnumber(res, "typname"); + i_attlen = PQfnumber(res, "attlen"); + i_attnotnull = PQfnumber(res, "attnotnull"); + + tblinfo[i].numatts = ntups; + tblinfo[i].attnames = (char **) malloc(ntups * sizeof(char *)); + tblinfo[i].typnames = (char **) malloc(ntups * sizeof(char *)); + tblinfo[i].attlen = (int *) malloc(ntups * sizeof(int)); + tblinfo[i].inhAttrs = (int *) malloc(ntups * sizeof(int)); + tblinfo[i].notnull = (bool *) malloc(ntups * sizeof(bool)); + tblinfo[i].parentRels = NULL; + tblinfo[i].numParents = 0; + for (j = 0; j < ntups; j++) + { + tblinfo[i].attnames[j] = strdup(PQgetvalue(res, j, i_attname)); + tblinfo[i].typnames[j] = strdup(PQgetvalue(res, j, i_typname)); + tblinfo[i].attlen[j] = atoi(PQgetvalue(res, j, i_attlen)); + if (tblinfo[i].attlen[j] > 0) + tblinfo[i].attlen[j] = tblinfo[i].attlen[j] - 4; + tblinfo[i].inhAttrs[j] = 0; /* this flag is set in + * flagInhAttrs() */ + tblinfo[i].notnull[j] = (PQgetvalue(res, j, i_attnotnull)[0] == 't') ? true : false; + } + PQclear(res); + } } /* * getIndices - * read all the user-defined indices information + * read all the user-defined indices information * from the system catalogs return them in the InhInfo* structure * - * numIndices is set to the number of indices read in - * + * numIndices is set to the number of indices read in + * * */ -IndInfo* +IndInfo * getIndices(int *numIndices) { - int i; - char query[MAXQUERYLEN]; - PGresult *res; - int ntups; - IndInfo *indinfo; - - int i_indexrelname; - int i_indrelname; - int i_indamname; - int i_indproc; - int i_indkey; - int i_indclass; - int i_indisunique; - - /* - find all the user-defined indices. - We do not handle partial indices. - - skip 'Xinx*' - indices on inversion objects - - this is a 4-way join !! - */ - - res = PQexec(g_conn, "begin"); - if (!res || - PQresultStatus(res) != PGRES_COMMAND_OK) { - fprintf(stderr,"BEGIN command failed\n"); - exit_nicely(g_conn); - } - PQclear(res); - - sprintf(query, - "SELECT t1.relname as indexrelname, t2.relname as indrelname, " - "i.indproc, i.indkey, i.indclass, " - "a.amname as indamname, i.indisunique " - "from pg_index i, pg_class t1, pg_class t2, pg_am a " - "where t1.oid = i.indexrelid and t2.oid = i.indrelid " - "and t1.relam = a.oid and i.indexrelid > '%d'::oid " - "and t2.relname !~ '^pg_' and t1.relname !~ '^Xinx'", - g_last_builtin_oid); - - res = PQexec(g_conn, query); - if (!res || - PQresultStatus(res) != PGRES_TUPLES_OK) { - fprintf(stderr,"getIndices(): SELECT failed\n"); - exit_nicely(g_conn); - } - - ntups = PQntuples(res); - - *numIndices = ntups; - - indinfo = (IndInfo*)malloc(ntups * sizeof (IndInfo)); - - i_indexrelname = PQfnumber(res,"indexrelname"); - i_indrelname = PQfnumber(res,"indrelname"); - i_indamname = PQfnumber(res,"indamname"); - i_indproc = PQfnumber(res,"indproc"); - i_indkey = PQfnumber(res,"indkey"); - i_indclass = PQfnumber(res,"indclass"); - i_indisunique = PQfnumber(res,"indisunique"); - - for (i=0;i<ntups;i++) { - indinfo[i].indexrelname = strdup(PQgetvalue(res,i,i_indexrelname)); - indinfo[i].indrelname = strdup(PQgetvalue(res,i,i_indrelname)); - indinfo[i].indamname = strdup(PQgetvalue(res,i,i_indamname)); - indinfo[i].indproc = strdup(PQgetvalue(res,i,i_indproc)); - parseArgTypes ((char **)indinfo[i].indkey, - (const char*)PQgetvalue(res,i,i_indkey)); - parseArgTypes ((char **)indinfo[i].indclass, - (const char*)PQgetvalue(res,i,i_indclass)); - indinfo[i].indisunique = strdup(PQgetvalue(res,i,i_indisunique)); - } - PQclear(res); - res = PQexec(g_conn,"end"); - if(res) PQclear(res); - return indinfo; + int i; + char query[MAXQUERYLEN]; + PGresult *res; + int ntups; + IndInfo *indinfo; + + int i_indexrelname; + int i_indrelname; + int i_indamname; + int i_indproc; + int i_indkey; + int i_indclass; + int i_indisunique; + + /* + * find all the user-defined indices. We do not handle partial + * indices. + * + * skip 'Xinx*' - indices on inversion objects + * + * this is a 4-way join !! + */ + + res = PQexec(g_conn, "begin"); + if (!res || + PQresultStatus(res) != PGRES_COMMAND_OK) + { + fprintf(stderr, "BEGIN command failed\n"); + exit_nicely(g_conn); + } + PQclear(res); + + sprintf(query, + "SELECT t1.relname as indexrelname, t2.relname as indrelname, " + "i.indproc, i.indkey, i.indclass, " + "a.amname as indamname, i.indisunique " + "from pg_index i, pg_class t1, pg_class t2, pg_am a " + "where t1.oid = i.indexrelid and t2.oid = i.indrelid " + "and t1.relam = a.oid and i.indexrelid > '%d'::oid " + "and t2.relname !~ '^pg_' and t1.relname !~ '^Xinx'", + g_last_builtin_oid); + + res = PQexec(g_conn, query); + if (!res || + PQresultStatus(res) != PGRES_TUPLES_OK) + { + fprintf(stderr, "getIndices(): SELECT failed\n"); + exit_nicely(g_conn); + } + + ntups = PQntuples(res); + + *numIndices = ntups; + + indinfo = (IndInfo *) malloc(ntups * sizeof(IndInfo)); + + i_indexrelname = PQfnumber(res, "indexrelname"); + i_indrelname = PQfnumber(res, "indrelname"); + i_indamname = PQfnumber(res, "indamname"); + i_indproc = PQfnumber(res, "indproc"); + i_indkey = PQfnumber(res, "indkey"); + i_indclass = PQfnumber(res, "indclass"); + i_indisunique = PQfnumber(res, "indisunique"); + + for (i = 0; i < ntups; i++) + { + indinfo[i].indexrelname = strdup(PQgetvalue(res, i, i_indexrelname)); + indinfo[i].indrelname = strdup(PQgetvalue(res, i, i_indrelname)); + indinfo[i].indamname = strdup(PQgetvalue(res, i, i_indamname)); + indinfo[i].indproc = strdup(PQgetvalue(res, i, i_indproc)); + parseArgTypes((char **) indinfo[i].indkey, + (const char *) PQgetvalue(res, i, i_indkey)); + parseArgTypes((char **) indinfo[i].indclass, + (const char *) PQgetvalue(res, i, i_indclass)); + indinfo[i].indisunique = strdup(PQgetvalue(res, i, i_indisunique)); + } + PQclear(res); + res = PQexec(g_conn, "end"); + if (res) + PQclear(res); + return indinfo; } /* * dumpTypes - * writes out to fout the queries to recreate all the user-defined types + * writes out to fout the queries to recreate all the user-defined types * */ void -dumpTypes(FILE* fout, FuncInfo* finfo, int numFuncs, - TypeInfo* tinfo, int numTypes) +dumpTypes(FILE * fout, FuncInfo * finfo, int numFuncs, + TypeInfo * tinfo, int numTypes) { - int i; - char q[MAXQUERYLEN]; - int funcInd; - - for (i=0;i<numTypes;i++) { - - /* skip all the builtin types */ - if (atoi(tinfo[i].oid) < g_last_builtin_oid) - continue; - - /* skip relation types */ - if (atoi(tinfo[i].typrelid) != 0) - continue; - - /* skip all array types that start w/ underscore */ - if ( (tinfo[i].typname[0] == '_') && - (strcmp(tinfo[i].typinput, "array_in") == 0)) - continue; - - /* before we create a type, we need to create the input and - output functions for it, if they haven't been created already */ - funcInd = findFuncByName(finfo, numFuncs, tinfo[i].typinput); - if (funcInd != -1) - dumpOneFunc(fout,finfo,funcInd,tinfo,numTypes); - - funcInd = findFuncByName(finfo, numFuncs, tinfo[i].typoutput); - if (funcInd != -1) - dumpOneFunc(fout,finfo,funcInd,tinfo,numTypes); - - fprintf(fout,"\\connect - %s\n",tinfo[i].usename); - - sprintf(q, - "CREATE TYPE %s " - "( internallength = %s, externallength = %s, input = %s, " - "output = %s, send = %s, receive = %s, default = '%s'", - tinfo[i].typname, - tinfo[i].typlen, - tinfo[i].typprtlen, - tinfo[i].typinput, - tinfo[i].typoutput, - tinfo[i].typsend, - tinfo[i].typreceive, - tinfo[i].typdefault); - - if (tinfo[i].isArray) { - char* elemType; - - elemType = findTypeByOid(tinfo, numTypes, tinfo[i].typelem); - - sprintf(q,"%s, element = %s, delimiter = '%s'", - q, elemType,tinfo[i].typdelim); - } - if (tinfo[i].passedbyvalue) - strcat(q,",passedbyvalue);\n"); - else - strcat(q,");\n"); - - fputs(q,fout); - } + int i; + char q[MAXQUERYLEN]; + int funcInd; + + for (i = 0; i < numTypes; i++) + { + + /* skip all the builtin types */ + if (atoi(tinfo[i].oid) < g_last_builtin_oid) + continue; + + /* skip relation types */ + if (atoi(tinfo[i].typrelid) != 0) + continue; + + /* skip all array types that start w/ underscore */ + if ((tinfo[i].typname[0] == '_') && + (strcmp(tinfo[i].typinput, "array_in") == 0)) + continue; + + /* + * before we create a type, we need to create the input and output + * functions for it, if they haven't been created already + */ + funcInd = findFuncByName(finfo, numFuncs, tinfo[i].typinput); + if (funcInd != -1) + dumpOneFunc(fout, finfo, funcInd, tinfo, numTypes); + + funcInd = findFuncByName(finfo, numFuncs, tinfo[i].typoutput); + if (funcInd != -1) + dumpOneFunc(fout, finfo, funcInd, tinfo, numTypes); + + fprintf(fout, "\\connect - %s\n", tinfo[i].usename); + + sprintf(q, + "CREATE TYPE %s " + "( internallength = %s, externallength = %s, input = %s, " + "output = %s, send = %s, receive = %s, default = '%s'", + tinfo[i].typname, + tinfo[i].typlen, + tinfo[i].typprtlen, + tinfo[i].typinput, + tinfo[i].typoutput, + tinfo[i].typsend, + tinfo[i].typreceive, + tinfo[i].typdefault); + + if (tinfo[i].isArray) + { + char *elemType; + + elemType = findTypeByOid(tinfo, numTypes, tinfo[i].typelem); + + sprintf(q, "%s, element = %s, delimiter = '%s'", + q, elemType, tinfo[i].typdelim); + } + if (tinfo[i].passedbyvalue) + strcat(q, ",passedbyvalue);\n"); + else + strcat(q, ");\n"); + + fputs(q, fout); + } } /* * dumpFuncs - * writes out to fout the queries to recreate all the user-defined functions + * writes out to fout the queries to recreate all the user-defined functions * */ void -dumpFuncs(FILE* fout, FuncInfo* finfo, int numFuncs, - TypeInfo *tinfo, int numTypes) +dumpFuncs(FILE * fout, FuncInfo * finfo, int numFuncs, + TypeInfo * tinfo, int numTypes) { - int i; - for (i=0;i<numFuncs;i++) { - dumpOneFunc(fout,finfo,i,tinfo,numTypes); - } + int i; + + for (i = 0; i < numFuncs; i++) + { + dumpOneFunc(fout, finfo, i, tinfo, numTypes); + } } /* * dumpOneFunc: - * dump out only one function, the index of which is given in the third - * argument + * dump out only one function, the index of which is given in the third + * argument * */ static void -dumpOneFunc(FILE* fout, FuncInfo* finfo, int i, - TypeInfo *tinfo, int numTypes) +dumpOneFunc(FILE * fout, FuncInfo * finfo, int i, + TypeInfo * tinfo, int numTypes) { - char q[MAXQUERYLEN]; - int j; - - if (finfo[i].dumped) - return; - else - finfo[i].dumped = 1; - - fprintf(fout,"\\connect - %s\n",finfo[i].usename); - - sprintf(q,"CREATE FUNCTION %s (",finfo[i].proname); - for (j=0;j<finfo[i].nargs;j++) { - char* typname; - typname = findTypeByOid(tinfo, numTypes, finfo[i].argtypes[j]); - sprintf(q, "%s%s%s", - q, - (j > 0) ? "," : "", - typname); - } - sprintf(q,"%s ) RETURNS %s%s AS '%s' LANGUAGE '%s';\n", - q, - (finfo[i].retset) ? " SETOF " : "", - findTypeByOid(tinfo, numTypes, finfo[i].prorettype), - (finfo[i].lang) ? finfo[i].probin : finfo[i].prosrc, - (finfo[i].lang) ? "C" : "SQL"); - - fputs(q,fout); + char q[MAXQUERYLEN]; + int j; + + if (finfo[i].dumped) + return; + else + finfo[i].dumped = 1; + + fprintf(fout, "\\connect - %s\n", finfo[i].usename); + + sprintf(q, "CREATE FUNCTION %s (", finfo[i].proname); + for (j = 0; j < finfo[i].nargs; j++) + { + char *typname; + + typname = findTypeByOid(tinfo, numTypes, finfo[i].argtypes[j]); + sprintf(q, "%s%s%s", + q, + (j > 0) ? "," : "", + typname); + } + sprintf(q, "%s ) RETURNS %s%s AS '%s' LANGUAGE '%s';\n", + q, + (finfo[i].retset) ? " SETOF " : "", + findTypeByOid(tinfo, numTypes, finfo[i].prorettype), + (finfo[i].lang) ? finfo[i].probin : finfo[i].prosrc, + (finfo[i].lang) ? "C" : "SQL"); + + fputs(q, fout); } /* * dumpOprs - * writes out to fout the queries to recreate all the user-defined operators + * writes out to fout the queries to recreate all the user-defined operators * */ -void -dumpOprs(FILE* fout, OprInfo* oprinfo, int numOperators, - TypeInfo *tinfo, int numTypes) +void +dumpOprs(FILE * fout, OprInfo * oprinfo, int numOperators, + TypeInfo * tinfo, int numTypes) { - int i; - char q[MAXQUERYLEN]; - char leftarg[MAXQUERYLEN]; - char rightarg[MAXQUERYLEN]; - char commutator[MAXQUERYLEN]; - char negator[MAXQUERYLEN]; - char restrict[MAXQUERYLEN]; - char join[MAXQUERYLEN]; - char sortop[MAXQUERYLEN]; - - for (i=0;i<numOperators;i++) { - - /* skip all the builtin oids */ - if (atoi(oprinfo[i].oid) < g_last_builtin_oid) - continue; - - /* some operator are invalid because they were the result - of user defining operators before commutators exist */ - if (strcmp(oprinfo[i].oprcode, "-") == 0) - continue; - - leftarg[0] = '\0'; - rightarg[0] = '\0'; - /* right unary means there's a left arg - and left unary means there's a right arg */ - if (strcmp(oprinfo[i].oprkind, "r") == 0 || - strcmp(oprinfo[i].oprkind, "b") == 0 ) { - sprintf(leftarg, ", LEFTARG = %s ", - findTypeByOid(tinfo, numTypes, oprinfo[i].oprleft)); - } - if (strcmp(oprinfo[i].oprkind, "l") == 0 || - strcmp(oprinfo[i].oprkind, "b") == 0 ) { - sprintf(rightarg, ", RIGHTARG = %s ", - findTypeByOid(tinfo, numTypes, oprinfo[i].oprright)); - } - if (strcmp(oprinfo[i].oprcom, "0") == 0) - commutator[0] = '\0'; - else - sprintf(commutator,", COMMUTATOR = %s ", - findOprByOid(oprinfo, numOperators, oprinfo[i].oprcom)); - - if (strcmp(oprinfo[i].oprnegate, "0") == 0) - negator[0] = '\0'; - else - sprintf(negator,", NEGATOR = %s ", - findOprByOid(oprinfo, numOperators, oprinfo[i].oprnegate)); - - if (strcmp(oprinfo[i].oprrest, "-") == 0) - restrict[0] = '\0'; - else - sprintf(restrict,", RESTRICT = %s ", oprinfo[i].oprrest); - - if (strcmp(oprinfo[i].oprjoin,"-") == 0) - join[0] = '\0'; - else - sprintf(join,", JOIN = %s ", oprinfo[i].oprjoin); - - if (strcmp(oprinfo[i].oprlsortop, "0") == 0) - sortop[0] = '\0'; - else - { - sprintf(sortop,", SORT = %s ", - findOprByOid(oprinfo, numOperators, - oprinfo[i].oprlsortop)); - if (strcmp(oprinfo[i].oprrsortop, "0") != 0) - sprintf(sortop, "%s , %s", sortop, - findOprByOid(oprinfo, numOperators, - oprinfo[i].oprlsortop)); - } - - fprintf(fout,"\\connect - %s\n", oprinfo[i].usename); - - sprintf(q, - "CREATE OPERATOR %s " - "(PROCEDURE = %s %s %s %s %s %s %s %s %s);\n ", - oprinfo[i].oprname, - oprinfo[i].oprcode, - leftarg, - rightarg, - commutator, - negator, - restrict, - (strcmp(oprinfo[i].oprcanhash, "t")) ? ", HASHES" : "", - join, - sortop); - - fputs(q,fout); - } + int i; + char q[MAXQUERYLEN]; + char leftarg[MAXQUERYLEN]; + char rightarg[MAXQUERYLEN]; + char commutator[MAXQUERYLEN]; + char negator[MAXQUERYLEN]; + char restrict[MAXQUERYLEN]; + char join[MAXQUERYLEN]; + char sortop[MAXQUERYLEN]; + + for (i = 0; i < numOperators; i++) + { + + /* skip all the builtin oids */ + if (atoi(oprinfo[i].oid) < g_last_builtin_oid) + continue; + + /* + * some operator are invalid because they were the result of user + * defining operators before commutators exist + */ + if (strcmp(oprinfo[i].oprcode, "-") == 0) + continue; + + leftarg[0] = '\0'; + rightarg[0] = '\0'; + + /* + * right unary means there's a left arg and left unary means + * there's a right arg + */ + if (strcmp(oprinfo[i].oprkind, "r") == 0 || + strcmp(oprinfo[i].oprkind, "b") == 0) + { + sprintf(leftarg, ", LEFTARG = %s ", + findTypeByOid(tinfo, numTypes, oprinfo[i].oprleft)); + } + if (strcmp(oprinfo[i].oprkind, "l") == 0 || + strcmp(oprinfo[i].oprkind, "b") == 0) + { + sprintf(rightarg, ", RIGHTARG = %s ", + findTypeByOid(tinfo, numTypes, oprinfo[i].oprright)); + } + if (strcmp(oprinfo[i].oprcom, "0") == 0) + commutator[0] = '\0'; + else + sprintf(commutator, ", COMMUTATOR = %s ", + findOprByOid(oprinfo, numOperators, oprinfo[i].oprcom)); + + if (strcmp(oprinfo[i].oprnegate, "0") == 0) + negator[0] = '\0'; + else + sprintf(negator, ", NEGATOR = %s ", + findOprByOid(oprinfo, numOperators, oprinfo[i].oprnegate)); + + if (strcmp(oprinfo[i].oprrest, "-") == 0) + restrict[0] = '\0'; + else + sprintf(restrict, ", RESTRICT = %s ", oprinfo[i].oprrest); + + if (strcmp(oprinfo[i].oprjoin, "-") == 0) + join[0] = '\0'; + else + sprintf(join, ", JOIN = %s ", oprinfo[i].oprjoin); + + if (strcmp(oprinfo[i].oprlsortop, "0") == 0) + sortop[0] = '\0'; + else + { + sprintf(sortop, ", SORT = %s ", + findOprByOid(oprinfo, numOperators, + oprinfo[i].oprlsortop)); + if (strcmp(oprinfo[i].oprrsortop, "0") != 0) + sprintf(sortop, "%s , %s", sortop, + findOprByOid(oprinfo, numOperators, + oprinfo[i].oprlsortop)); + } + + fprintf(fout, "\\connect - %s\n", oprinfo[i].usename); + + sprintf(q, + "CREATE OPERATOR %s " + "(PROCEDURE = %s %s %s %s %s %s %s %s %s);\n ", + oprinfo[i].oprname, + oprinfo[i].oprcode, + leftarg, + rightarg, + commutator, + negator, + restrict, + (strcmp(oprinfo[i].oprcanhash, "t")) ? ", HASHES" : "", + join, + sortop); + + fputs(q, fout); + } } /* * dumpAggs - * writes out to fout the queries to create all the user-defined aggregates + * writes out to fout the queries to create all the user-defined aggregates * */ void -dumpAggs(FILE* fout, AggInfo* agginfo, int numAggs, - TypeInfo *tinfo, int numTypes) +dumpAggs(FILE * fout, AggInfo * agginfo, int numAggs, + TypeInfo * tinfo, int numTypes) { - int i; - char q[MAXQUERYLEN]; - char sfunc1[MAXQUERYLEN]; - char sfunc2[MAXQUERYLEN]; - char finalfunc[MAXQUERYLEN]; - char comma1[2], comma2[2]; - - for (i=0;i<numAggs;i++) { - /* skip all the builtin oids */ - if (atoi(agginfo[i].oid) < g_last_builtin_oid) - continue; - - if ( strcmp(agginfo[i].aggtransfn1, "-") == 0) - sfunc1[0] = '\0'; - else { - sprintf(sfunc1, - "SFUNC1 = %s, BASETYPE = %s, STYPE1 = %s", - agginfo[i].aggtransfn1, - findTypeByOid(tinfo,numTypes,agginfo[i].aggbasetype), - findTypeByOid(tinfo,numTypes,agginfo[i].aggtranstype1)); - if (agginfo[i].agginitval1) - sprintf(sfunc1, "%s ,INITCOND1 = '%s'", - sfunc1, agginfo[i].agginitval1); - - } - - if ( strcmp(agginfo[i].aggtransfn2, "-") == 0) - sfunc2[0] = '\0'; - else { - sprintf(sfunc2, - "SFUNC2 = %s, STYPE2 = %s", - agginfo[i].aggtransfn2, - findTypeByOid(tinfo,numTypes,agginfo[i].aggtranstype2)); - if (agginfo[i].agginitval2) - sprintf(sfunc2,"%s ,INITCOND2 = '%s'", - sfunc2, agginfo[i].agginitval2); - } - - if ( strcmp(agginfo[i].aggfinalfn, "-") == 0) - finalfunc[0] = '\0'; - else { - sprintf(finalfunc, "FINALFUNC = %s", agginfo[i].aggfinalfn); - } - if (sfunc1[0] != '\0' && sfunc2[0] != '\0') { - comma1[0] = ','; comma1[1] = '\0'; - } else - comma1[0] = '\0'; - - if (finalfunc[0] != '\0' && (sfunc1[0] != '\0' || sfunc2[0] != '\0')) { - comma2[0] = ',';comma2[1] = '\0'; - } else - comma2[0] = '\0'; - - fprintf(fout,"\\connect - %s\n", agginfo[i].usename); - - sprintf(q,"CREATE AGGREGATE %s ( %s %s %s %s %s );\n", - agginfo[i].aggname, - sfunc1, - comma1, - sfunc2, - comma2, - finalfunc); - - fputs(q,fout); - } + int i; + char q[MAXQUERYLEN]; + char sfunc1[MAXQUERYLEN]; + char sfunc2[MAXQUERYLEN]; + char finalfunc[MAXQUERYLEN]; + char comma1[2], + comma2[2]; + + for (i = 0; i < numAggs; i++) + { + /* skip all the builtin oids */ + if (atoi(agginfo[i].oid) < g_last_builtin_oid) + continue; + + if (strcmp(agginfo[i].aggtransfn1, "-") == 0) + sfunc1[0] = '\0'; + else + { + sprintf(sfunc1, + "SFUNC1 = %s, BASETYPE = %s, STYPE1 = %s", + agginfo[i].aggtransfn1, + findTypeByOid(tinfo, numTypes, agginfo[i].aggbasetype), + findTypeByOid(tinfo, numTypes, agginfo[i].aggtranstype1)); + if (agginfo[i].agginitval1) + sprintf(sfunc1, "%s ,INITCOND1 = '%s'", + sfunc1, agginfo[i].agginitval1); + + } + + if (strcmp(agginfo[i].aggtransfn2, "-") == 0) + sfunc2[0] = '\0'; + else + { + sprintf(sfunc2, + "SFUNC2 = %s, STYPE2 = %s", + agginfo[i].aggtransfn2, + findTypeByOid(tinfo, numTypes, agginfo[i].aggtranstype2)); + if (agginfo[i].agginitval2) + sprintf(sfunc2, "%s ,INITCOND2 = '%s'", + sfunc2, agginfo[i].agginitval2); + } + + if (strcmp(agginfo[i].aggfinalfn, "-") == 0) + finalfunc[0] = '\0'; + else + { + sprintf(finalfunc, "FINALFUNC = %s", agginfo[i].aggfinalfn); + } + if (sfunc1[0] != '\0' && sfunc2[0] != '\0') + { + comma1[0] = ','; + comma1[1] = '\0'; + } + else + comma1[0] = '\0'; + + if (finalfunc[0] != '\0' && (sfunc1[0] != '\0' || sfunc2[0] != '\0')) + { + comma2[0] = ','; + comma2[1] = '\0'; + } + else + comma2[0] = '\0'; + + fprintf(fout, "\\connect - %s\n", agginfo[i].usename); + + sprintf(q, "CREATE AGGREGATE %s ( %s %s %s %s %s );\n", + agginfo[i].aggname, + sfunc1, + comma1, + sfunc2, + comma2, + finalfunc); + + fputs(q, fout); + } } /* * dumpTables: - * write out to fout all the user-define tables + * write out to fout all the user-define tables */ -void dumpTables(FILE* fout, TableInfo *tblinfo, int numTables, - InhInfo *inhinfo, int numInherits, - TypeInfo *tinfo, int numTypes, const char *tablename, - const bool acls) +void +dumpTables(FILE * fout, TableInfo * tblinfo, int numTables, + InhInfo * inhinfo, int numInherits, + TypeInfo * tinfo, int numTypes, const char *tablename, + const bool acls) { - int i,j,k; - char q[MAXQUERYLEN]; - char **parentRels; /* list of names of parent relations */ - int numParents; - int actual_atts; /* number of attrs in this CREATE statment */ - const char *archiveMode; - - for (i=0;i<numTables;i++) { - - if (!tablename || (!strcmp(tblinfo[i].relname,tablename))) { - - /* Skip VIEW relations */ - if (isViewRule(tblinfo[i].relname)) - continue; - - /* skip archive names*/ - if (isArchiveName(tblinfo[i].relname)) - continue; - - if ( tblinfo[i].sequence ) - { - dumpSequence (fout, tblinfo[i]); - continue; - } - - parentRels = tblinfo[i].parentRels; - numParents = tblinfo[i].numParents; - - fprintf(fout, "\\connect - %s\n", tblinfo[i].usename); - - sprintf(q, "CREATE TABLE %s (", tblinfo[i].relname); - actual_atts = 0; - for (j=0;j<tblinfo[i].numatts;j++) { - if (tblinfo[i].inhAttrs[j] == 0) { - - /* Show lengths on bpchar and varchar */ - if (!strcmp(tblinfo[i].typnames[j],"bpchar")) { - sprintf(q, "%s%s%s char", - q, - (actual_atts > 0) ? ", " : "", - tblinfo[i].attnames[j]); - - /* stored length can be -1 (variable) */ - if (tblinfo[i].attlen[j] > 0) - sprintf(q, "%s(%d)", - q, - tblinfo[i].attlen[j]); - actual_atts++; - } - else if (!strcmp(tblinfo[i].typnames[j],"varchar")) { - sprintf(q, "%s%s%s %s", - q, - (actual_atts > 0) ? ", " : "", - tblinfo[i].attnames[j], - tblinfo[i].typnames[j]); - - /* stored length can be -1 (variable) */ - if (tblinfo[i].attlen[j] > 0) - sprintf(q, "%s(%d)", - q, - tblinfo[i].attlen[j]); - actual_atts++; - } - else { - sprintf(q, "%s%s%s %s", - q, - (actual_atts > 0) ? ", " : "", - tblinfo[i].attnames[j], - tblinfo[i].typnames[j]); - actual_atts++; - } - if (tblinfo[i].notnull[j]) - sprintf(q, "%s NOT NULL", q); - } - } - - strcat(q,")"); - - if (numParents > 0) { - sprintf(q, "%s inherits ( ",q); - for (k=0;k<numParents;k++){ - sprintf(q, "%s%s%s", - q, - (k>0) ? ", " : "", - parentRels[k]); - } - strcat(q,")"); - } - - switch(tblinfo[i].relarch[0]) { - case 'n': - archiveMode = "none"; - break; - case 'h': - archiveMode = "heavy"; - break; - case 'l': - archiveMode = "light"; - break; - default: - fprintf(stderr, "unknown archive mode\n"); - archiveMode = "none"; - break; - } - - sprintf(q, "%s archive = %s;\n", - q, - archiveMode); - fputs(q,fout); - - if(acls) - fprintf(fout, - "UPDATE pg_class SET relacl='%s' where relname='%s';\n", - tblinfo[i].relacl, tblinfo[i].relname); - } - } + int i, + j, + k; + char q[MAXQUERYLEN]; + char **parentRels; /* list of names of parent relations */ + int numParents; + int actual_atts;/* number of attrs in this CREATE statment */ + const char *archiveMode; + + for (i = 0; i < numTables; i++) + { + + if (!tablename || (!strcmp(tblinfo[i].relname, tablename))) + { + + /* Skip VIEW relations */ + if (isViewRule(tblinfo[i].relname)) + continue; + + /* skip archive names */ + if (isArchiveName(tblinfo[i].relname)) + continue; + + if (tblinfo[i].sequence) + { + dumpSequence(fout, tblinfo[i]); + continue; + } + + parentRels = tblinfo[i].parentRels; + numParents = tblinfo[i].numParents; + + fprintf(fout, "\\connect - %s\n", tblinfo[i].usename); + + sprintf(q, "CREATE TABLE %s (", tblinfo[i].relname); + actual_atts = 0; + for (j = 0; j < tblinfo[i].numatts; j++) + { + if (tblinfo[i].inhAttrs[j] == 0) + { + + /* Show lengths on bpchar and varchar */ + if (!strcmp(tblinfo[i].typnames[j], "bpchar")) + { + sprintf(q, "%s%s%s char", + q, + (actual_atts > 0) ? ", " : "", + tblinfo[i].attnames[j]); + + /* stored length can be -1 (variable) */ + if (tblinfo[i].attlen[j] > 0) + sprintf(q, "%s(%d)", + q, + tblinfo[i].attlen[j]); + actual_atts++; + } + else if (!strcmp(tblinfo[i].typnames[j], "varchar")) + { + sprintf(q, "%s%s%s %s", + q, + (actual_atts > 0) ? ", " : "", + tblinfo[i].attnames[j], + tblinfo[i].typnames[j]); + + /* stored length can be -1 (variable) */ + if (tblinfo[i].attlen[j] > 0) + sprintf(q, "%s(%d)", + q, + tblinfo[i].attlen[j]); + actual_atts++; + } + else + { + sprintf(q, "%s%s%s %s", + q, + (actual_atts > 0) ? ", " : "", + tblinfo[i].attnames[j], + tblinfo[i].typnames[j]); + actual_atts++; + } + if (tblinfo[i].notnull[j]) + sprintf(q, "%s NOT NULL", q); + } + } + + strcat(q, ")"); + + if (numParents > 0) + { + sprintf(q, "%s inherits ( ", q); + for (k = 0; k < numParents; k++) + { + sprintf(q, "%s%s%s", + q, + (k > 0) ? ", " : "", + parentRels[k]); + } + strcat(q, ")"); + } + + switch (tblinfo[i].relarch[0]) + { + case 'n': + archiveMode = "none"; + break; + case 'h': + archiveMode = "heavy"; + break; + case 'l': + archiveMode = "light"; + break; + default: + fprintf(stderr, "unknown archive mode\n"); + archiveMode = "none"; + break; + } + + sprintf(q, "%s archive = %s;\n", + q, + archiveMode); + fputs(q, fout); + + if (acls) + fprintf(fout, + "UPDATE pg_class SET relacl='%s' where relname='%s';\n", + tblinfo[i].relacl, tblinfo[i].relname); + } + } } /* * dumpIndices: - * write out to fout all the user-define indices + * write out to fout all the user-define indices */ -void -dumpIndices(FILE* fout, IndInfo* indinfo, int numIndices, - TableInfo* tblinfo, int numTables, const char *tablename) +void +dumpIndices(FILE * fout, IndInfo * indinfo, int numIndices, + TableInfo * tblinfo, int numTables, const char *tablename) { - int i, k; - int tableInd; - char attlist[1000]; - char *classname[INDEX_MAX_KEYS]; - char *funcname; /* the name of the function to comput the index key from*/ - int indkey, indclass; - int nclass; - - char q[MAXQUERYLEN]; - PGresult *res; - - for (i=0;i<numIndices;i++) { - tableInd = findTableByName(tblinfo, numTables, - indinfo[i].indrelname); - - if (strcmp(indinfo[i].indproc,"0") == 0) { - funcname = NULL; - } else { - /* the funcname is an oid which we use to - find the name of the pg_proc. We need to do this - because getFuncs() only reads in the user-defined funcs - not all the funcs. We might not find what we want - by looking in FuncInfo**/ - sprintf(q, - "SELECT proname from pg_proc " - "where pg_proc.oid = '%s'::oid", - indinfo[i].indproc); - res = PQexec(g_conn, q); - if ( !res || PQresultStatus(res) != PGRES_TUPLES_OK ) - { - fprintf(stderr,"dumpIndices(): SELECT (funcname) failed\n"); - exit_nicely(g_conn); - } - funcname = strdup(PQgetvalue(res, 0, - PQfnumber(res,"proname"))); - PQclear(res); - } - - /* convert opclass oid(s) into names */ - for (nclass = 0; nclass < INDEX_MAX_KEYS; nclass++) - { - indclass = atoi(indinfo[i].indclass[nclass]); - if ( indclass == 0 ) - break; - sprintf(q, - "SELECT opcname from pg_opclass " - "where pg_opclass.oid = '%u'::oid", - indclass); - res = PQexec(g_conn, q); - if ( !res || PQresultStatus(res) != PGRES_TUPLES_OK ) - { - fprintf(stderr,"dumpIndices(): SELECT (classname) failed\n"); - exit_nicely(g_conn); - } - classname[nclass] = strdup(PQgetvalue(res, 0, - PQfnumber(res,"opcname"))); - PQclear(res); - } - - if ( funcname && nclass != 1 ) - { - fprintf(stderr,"dumpIndices(): Must be exactly one OpClass " - "for functional index %s\n", indinfo[i].indexrelname); - exit_nicely(g_conn); - } - - /* convert attribute numbers into attribute list */ - for (k = 0, attlist[0] = 0; k < INDEX_MAX_KEYS; k++) - { - char * attname; - - indkey = atoi(indinfo[i].indkey[k]); - if ( indkey == 0 ) - break; - indkey--; - if (indkey == ObjectIdAttributeNumber - 1) - attname = "oid"; - else - attname = tblinfo[tableInd].attnames[indkey]; - if ( funcname ) - sprintf (attlist + strlen(attlist), "%s%s", - ( k == 0 ) ? "" : ", ", attname); - else - { - if ( k >= nclass ) - { - fprintf(stderr,"dumpIndices(): OpClass not found for " - "attribute %s of index %s\n", - attname, indinfo[i].indexrelname); - exit_nicely(g_conn); - } - sprintf (attlist + strlen(attlist), "%s%s %s", - ( k == 0 ) ? "" : ", ", attname, classname[k]); - free (classname[k]); - } - } - - if (!tablename || (!strcmp(indinfo[i].indrelname,tablename))) { - - sprintf(q,"CREATE %s INDEX %s on %s using %s (", - (strcmp(indinfo[i].indisunique, "t") == 0) ? "UNIQUE" : "", - indinfo[i].indexrelname, - indinfo[i].indrelname, - indinfo[i].indamname); - if (funcname) { - sprintf(q, "%s %s (%s) %s );\n", - q, funcname, attlist, classname[0]); - free(funcname); - free(classname[0]); - } else - sprintf(q, "%s %s );\n", - q, attlist); - - fputs(q,fout); - } - } + int i, + k; + int tableInd; + char attlist[1000]; + char *classname[INDEX_MAX_KEYS]; + char *funcname; /* the name of the function to comput the + * index key from */ + int indkey, + indclass; + int nclass; + + char q[MAXQUERYLEN]; + PGresult *res; + + for (i = 0; i < numIndices; i++) + { + tableInd = findTableByName(tblinfo, numTables, + indinfo[i].indrelname); + + if (strcmp(indinfo[i].indproc, "0") == 0) + { + funcname = NULL; + } + else + { + + /* + * the funcname is an oid which we use to find the name of the + * pg_proc. We need to do this because getFuncs() only reads + * in the user-defined funcs not all the funcs. We might not + * find what we want by looking in FuncInfo* + */ + sprintf(q, + "SELECT proname from pg_proc " + "where pg_proc.oid = '%s'::oid", + indinfo[i].indproc); + res = PQexec(g_conn, q); + if (!res || PQresultStatus(res) != PGRES_TUPLES_OK) + { + fprintf(stderr, "dumpIndices(): SELECT (funcname) failed\n"); + exit_nicely(g_conn); + } + funcname = strdup(PQgetvalue(res, 0, + PQfnumber(res, "proname"))); + PQclear(res); + } + + /* convert opclass oid(s) into names */ + for (nclass = 0; nclass < INDEX_MAX_KEYS; nclass++) + { + indclass = atoi(indinfo[i].indclass[nclass]); + if (indclass == 0) + break; + sprintf(q, + "SELECT opcname from pg_opclass " + "where pg_opclass.oid = '%u'::oid", + indclass); + res = PQexec(g_conn, q); + if (!res || PQresultStatus(res) != PGRES_TUPLES_OK) + { + fprintf(stderr, "dumpIndices(): SELECT (classname) failed\n"); + exit_nicely(g_conn); + } + classname[nclass] = strdup(PQgetvalue(res, 0, + PQfnumber(res, "opcname"))); + PQclear(res); + } + + if (funcname && nclass != 1) + { + fprintf(stderr, "dumpIndices(): Must be exactly one OpClass " + "for functional index %s\n", indinfo[i].indexrelname); + exit_nicely(g_conn); + } + + /* convert attribute numbers into attribute list */ + for (k = 0, attlist[0] = 0; k < INDEX_MAX_KEYS; k++) + { + char *attname; + + indkey = atoi(indinfo[i].indkey[k]); + if (indkey == 0) + break; + indkey--; + if (indkey == ObjectIdAttributeNumber - 1) + attname = "oid"; + else + attname = tblinfo[tableInd].attnames[indkey]; + if (funcname) + sprintf(attlist + strlen(attlist), "%s%s", + (k == 0) ? "" : ", ", attname); + else + { + if (k >= nclass) + { + fprintf(stderr, "dumpIndices(): OpClass not found for " + "attribute %s of index %s\n", + attname, indinfo[i].indexrelname); + exit_nicely(g_conn); + } + sprintf(attlist + strlen(attlist), "%s%s %s", + (k == 0) ? "" : ", ", attname, classname[k]); + free(classname[k]); + } + } + + if (!tablename || (!strcmp(indinfo[i].indrelname, tablename))) + { + + sprintf(q, "CREATE %s INDEX %s on %s using %s (", + (strcmp(indinfo[i].indisunique, "t") == 0) ? "UNIQUE" : "", + indinfo[i].indexrelname, + indinfo[i].indrelname, + indinfo[i].indamname); + if (funcname) + { + sprintf(q, "%s %s (%s) %s );\n", + q, funcname, attlist, classname[0]); + free(funcname); + free(classname[0]); + } + else + sprintf(q, "%s %s );\n", + q, attlist); + + fputs(q, fout); + } + } } + /* * dumpTuples -- - * prints out the tuples in ASCII representation. The output is a valid - * input to COPY FROM stdin. + * prints out the tuples in ASCII representation. The output is a valid + * input to COPY FROM stdin. + * + * We only need to do this for POSTGRES 4.2 databases since the + * COPY TO statment doesn't escape newlines properly. It's been fixed + * in Postgres95. * - * We only need to do this for POSTGRES 4.2 databases since the - * COPY TO statment doesn't escape newlines properly. It's been fixed - * in Postgres95. - * * the attrmap passed in tells how to map the attributes copied in to the * attributes copied out */ #ifdef NOT_USED void -dumpTuples(PGresult *res, FILE *fout, int* attrmap) +dumpTuples(PGresult * res, FILE * fout, int *attrmap) { - int j, k; - int m, n; - char **outVals = NULL; /* values to copy out */ - - n = PQntuples(res); - m = PQnfields(res); - - if ( m > 0 ) { - /* - * Print out the tuples but only print tuples with at least - * 1 field. - */ - outVals = (char**)malloc(m * sizeof(char*)); - - for (j = 0; j < n; j++) { - for (k = 0; k < m; k++) { - outVals[attrmap[k]] = PQgetvalue(res, j, k); - } - for (k = 0; k < m; k++) { - char *pval = outVals[k]; - - if (k!=0) - fputc('\t', fout); /* delimiter for attribute */ - - if (pval) { - while (*pval != '\0') { - /* escape tabs, newlines and backslashes */ - if (*pval=='\t' || *pval=='\n' || *pval=='\\') - fputc('\\', fout); - fputc(*pval, fout); - pval++; - } - } - } - fputc('\n', fout); /* delimiter for a tuple */ - } - free (outVals); - } + int j, + k; + int m, + n; + char **outVals = NULL; /* values to copy out */ + + n = PQntuples(res); + m = PQnfields(res); + + if (m > 0) + { + + /* + * Print out the tuples but only print tuples with at least 1 + * field. + */ + outVals = (char **) malloc(m * sizeof(char *)); + + for (j = 0; j < n; j++) + { + for (k = 0; k < m; k++) + { + outVals[attrmap[k]] = PQgetvalue(res, j, k); + } + for (k = 0; k < m; k++) + { + char *pval = outVals[k]; + + if (k != 0) + fputc('\t', fout); /* delimiter for attribute */ + + if (pval) + { + while (*pval != '\0') + { + /* escape tabs, newlines and backslashes */ + if (*pval == '\t' || *pval == '\n' || *pval == '\\') + fputc('\\', fout); + fputc(*pval, fout); + pval++; + } + } + } + fputc('\n', fout); /* delimiter for a tuple */ + } + free(outVals); + } } + #endif /* @@ -2015,173 +2271,187 @@ dumpTuples(PGresult *res, FILE *fout, int* attrmap) */ static void -setMaxOid(FILE *fout) +setMaxOid(FILE * fout) { - PGresult *res; - Oid max_oid; - - res = PQexec(g_conn, "CREATE TABLE pgdump_oid (dummy int4)"); - if (!res || - PQresultStatus(res) != PGRES_COMMAND_OK) { - fprintf(stderr,"Can not create pgdump_oid table\n"); - exit_nicely(g_conn); - } - PQclear(res); - res = PQexec(g_conn, "INSERT INTO pgdump_oid VALUES (0)"); - if (!res || - PQresultStatus(res) != PGRES_COMMAND_OK) { - fprintf(stderr,"Can not insert into pgdump_oid table\n"); - exit_nicely(g_conn); - } - max_oid = atol(PQoidStatus(res)); - if (max_oid == 0) { - fprintf(stderr,"Invalid max id in setMaxOid\n"); - exit_nicely(g_conn); - } - PQclear(res); - res = PQexec(g_conn, "DROP TABLE pgdump_oid;"); - if (!res || - PQresultStatus(res) != PGRES_COMMAND_OK) { - fprintf(stderr,"Can not drop pgdump_oid table\n"); - exit_nicely(g_conn); - } - PQclear(res); - if (g_verbose) - fprintf(stderr, "%s maximum system oid is %d %s\n", - g_comment_start, max_oid, g_comment_end); - fprintf(fout, "CREATE TABLE pgdump_oid (dummy int4);\n"); - fprintf(fout, "COPY pgdump_oid WITH OIDS FROM stdin;\n"); - fprintf(fout, "%-d\t0\n", max_oid); - fprintf(fout, "\\.\n"); - fprintf(fout, "DROP TABLE pgdump_oid;\n"); -} + PGresult *res; + Oid max_oid; + + res = PQexec(g_conn, "CREATE TABLE pgdump_oid (dummy int4)"); + if (!res || + PQresultStatus(res) != PGRES_COMMAND_OK) + { + fprintf(stderr, "Can not create pgdump_oid table\n"); + exit_nicely(g_conn); + } + PQclear(res); + res = PQexec(g_conn, "INSERT INTO pgdump_oid VALUES (0)"); + if (!res || + PQresultStatus(res) != PGRES_COMMAND_OK) + { + fprintf(stderr, "Can not insert into pgdump_oid table\n"); + exit_nicely(g_conn); + } + max_oid = atol(PQoidStatus(res)); + if (max_oid == 0) + { + fprintf(stderr, "Invalid max id in setMaxOid\n"); + exit_nicely(g_conn); + } + PQclear(res); + res = PQexec(g_conn, "DROP TABLE pgdump_oid;"); + if (!res || + PQresultStatus(res) != PGRES_COMMAND_OK) + { + fprintf(stderr, "Can not drop pgdump_oid table\n"); + exit_nicely(g_conn); + } + PQclear(res); + if (g_verbose) + fprintf(stderr, "%s maximum system oid is %d %s\n", + g_comment_start, max_oid, g_comment_end); + fprintf(fout, "CREATE TABLE pgdump_oid (dummy int4);\n"); + fprintf(fout, "COPY pgdump_oid WITH OIDS FROM stdin;\n"); + fprintf(fout, "%-d\t0\n", max_oid); + fprintf(fout, "\\.\n"); + fprintf(fout, "DROP TABLE pgdump_oid;\n"); +} /* * findLastBuiltInOid - - * find the last built in oid + * find the last built in oid * we do this by looking up the oid of 'template1' in pg_database, - * this is probably not foolproof but comes close + * this is probably not foolproof but comes close */ static int findLastBuiltinOid(void) { - PGresult* res; - int ntups; - int last_oid; - - res = PQexec(g_conn, - "SELECT oid from pg_database where datname = 'template1'"); - if (res == NULL || - PQresultStatus(res) != PGRES_TUPLES_OK) { - fprintf(stderr,"pg_dump error in finding the template1 database\n"); - exit_nicely(g_conn); - } - ntups = PQntuples(res); - if (ntups != 1) { - fprintf(stderr,"pg_dump: couldn't find the template1 database. " - "You are really hosed.\nGiving up.\n"); - exit_nicely(g_conn); - } - last_oid = atoi(PQgetvalue(res, 0, PQfnumber(res, "oid"))); - PQclear(res); - return last_oid; + PGresult *res; + int ntups; + int last_oid; + + res = PQexec(g_conn, + "SELECT oid from pg_database where datname = 'template1'"); + if (res == NULL || + PQresultStatus(res) != PGRES_TUPLES_OK) + { + fprintf(stderr, "pg_dump error in finding the template1 database\n"); + exit_nicely(g_conn); + } + ntups = PQntuples(res); + if (ntups != 1) + { + fprintf(stderr, "pg_dump: couldn't find the template1 database. " + "You are really hosed.\nGiving up.\n"); + exit_nicely(g_conn); + } + last_oid = atoi(PQgetvalue(res, 0, PQfnumber(res, "oid"))); + PQclear(res); + return last_oid; } /* * checkForQuote: - * checks a string for quote characters and quotes them + * checks a string for quote characters and quotes them */ -static char* -checkForQuote(const char* s) +static char * +checkForQuote(const char *s) { - char *r; - char c; - char *result; + char *r; + char c; + char *result; - int j = 0; + int j = 0; - r = malloc(strlen(s)*3 + 1); /* definitely long enough */ + r = malloc(strlen(s) * 3 + 1); /* definitely long enough */ - while ( (c = *s) != '\0') { + while ((c = *s) != '\0') + { - if (c == '\'') { - r[j++] = '\''; /* quote the single quotes */ - } - r[j++] = c; - s++; - } - r[j] = '\0'; + if (c == '\'') + { + r[j++] = '\''; /* quote the single quotes */ + } + r[j++] = c; + s++; + } + r[j] = '\0'; + + result = strdup(r); + free(r); - result = strdup(r); - free(r); + return result; - return result; - } -static void dumpSequence (FILE* fout, TableInfo tbinfo) +static void +dumpSequence(FILE * fout, TableInfo tbinfo) { - PGresult *res; - int4 last, incby, maxv, minv, cache; - char cycled, called, *t; - char query[MAXQUERYLEN]; - - sprintf (query, - "SELECT sequence_name, last_value, increment_by, max_value, " - "min_value, cache_value, is_cycled, is_called from %s", - tbinfo.relname); - - res = PQexec (g_conn, query); - if ( !res || PQresultStatus(res) != PGRES_TUPLES_OK ) - { - fprintf (stderr,"dumpSequence(%s): SELECT failed\n", tbinfo.relname); - exit_nicely (g_conn); - } - - if ( PQntuples (res) != 1 ) - { - fprintf (stderr,"dumpSequence(%s): %d (!= 1) tuples returned by SELECT\n", - tbinfo.relname, PQntuples(res)); - exit_nicely (g_conn); - } - - if ( strcmp (PQgetvalue (res,0,0), tbinfo.relname) != 0 ) - { - fprintf (stderr, "dumpSequence(%s): different sequence name " - "returned by SELECT: %s\n", - tbinfo.relname, PQgetvalue (res,0,0)); - exit_nicely (g_conn); - } - - - last = atoi (PQgetvalue (res,0,1)); - incby = atoi (PQgetvalue (res,0,2)); - maxv = atoi (PQgetvalue (res,0,3)); - minv = atoi (PQgetvalue (res,0,4)); - cache = atoi (PQgetvalue (res,0,5)); - t = PQgetvalue (res,0,6); - cycled = *t; - t = PQgetvalue (res,0,7); - called = *t; - - PQclear (res); - - sprintf (query, - "CREATE SEQUENCE %s start %d increment %d maxvalue %d " - "minvalue %d cache %d %s;\n", - tbinfo.relname, last, incby, maxv, minv, cache, - (cycled == 't') ? "cycle" : ""); - - fputs (query, fout); - - if ( called == 'f' ) - return; /* nothing to do more */ - - sprintf (query, "SELECT nextval ('%s');\n", tbinfo.relname); - fputs (query, fout); + PGresult *res; + int4 last, + incby, + maxv, + minv, + cache; + char cycled, + called, + *t; + char query[MAXQUERYLEN]; + + sprintf(query, + "SELECT sequence_name, last_value, increment_by, max_value, " + "min_value, cache_value, is_cycled, is_called from %s", + tbinfo.relname); + + res = PQexec(g_conn, query); + if (!res || PQresultStatus(res) != PGRES_TUPLES_OK) + { + fprintf(stderr, "dumpSequence(%s): SELECT failed\n", tbinfo.relname); + exit_nicely(g_conn); + } + + if (PQntuples(res) != 1) + { + fprintf(stderr, "dumpSequence(%s): %d (!= 1) tuples returned by SELECT\n", + tbinfo.relname, PQntuples(res)); + exit_nicely(g_conn); + } + + if (strcmp(PQgetvalue(res, 0, 0), tbinfo.relname) != 0) + { + fprintf(stderr, "dumpSequence(%s): different sequence name " + "returned by SELECT: %s\n", + tbinfo.relname, PQgetvalue(res, 0, 0)); + exit_nicely(g_conn); + } + + + last = atoi(PQgetvalue(res, 0, 1)); + incby = atoi(PQgetvalue(res, 0, 2)); + maxv = atoi(PQgetvalue(res, 0, 3)); + minv = atoi(PQgetvalue(res, 0, 4)); + cache = atoi(PQgetvalue(res, 0, 5)); + t = PQgetvalue(res, 0, 6); + cycled = *t; + t = PQgetvalue(res, 0, 7); + called = *t; + + PQclear(res); + + sprintf(query, + "CREATE SEQUENCE %s start %d increment %d maxvalue %d " + "minvalue %d cache %d %s;\n", + tbinfo.relname, last, incby, maxv, minv, cache, + (cycled == 't') ? "cycle" : ""); + + fputs(query, fout); + + if (called == 'f') + return; /* nothing to do more */ + + sprintf(query, "SELECT nextval ('%s');\n", tbinfo.relname); + fputs(query, fout); } - diff --git a/src/bin/pg_dump/pg_dump.h b/src/bin/pg_dump/pg_dump.h index a537a3ff6ba..b59e4d82997 100644 --- a/src/bin/pg_dump/pg_dump.h +++ b/src/bin/pg_dump/pg_dump.h @@ -1,21 +1,21 @@ /*------------------------------------------------------------------------- * * pg_dump.h - * header file for the pg_dump utility + * header file for the pg_dump utility * * Copyright (c) 1994, Regents of the University of California * - * $Id: pg_dump.h,v 1.19 1997/08/19 21:36:45 momjian Exp $ + * $Id: pg_dump.h,v 1.20 1997/09/07 04:54:42 momjian Exp $ * * Modifications - 6/12/96 - dave@bensoft.com - version 1.13.dhb.2 * - * - Fixed dumpTable output to output lengths for char and varchar types! - * - Added single. quote to twin single quote expansion for 'insert' string - * mode. + * - Fixed dumpTable output to output lengths for char and varchar types! + * - Added single. quote to twin single quote expansion for 'insert' string + * mode. * * Modifications - 6/1/97 - igor@sba.miami.edu * - Added extern's for the functions that clear allocated memory - * in pg_dump.c + * in pg_dump.c *------------------------------------------------------------------------- */ @@ -23,192 +23,218 @@ /* The *Info data structures run-time C structures used to store system catalog information */ - -typedef struct _typeInfo { - char* oid; - char* typowner; - char* typname; - char* typlen; - char* typprtlen; - char* typinput; - char* typoutput; - char* typreceive; - char* typsend; - char* typelem; - char* typdelim; - char* typdefault; - char* typrelid; - char* usename; - int passedbyvalue; - int isArray; -} TypeInfo; - -typedef struct _funcInfo { - char* oid; - char* proname; - char* proowner; - int lang; /* 1 if C, else SQL */ - int nargs; - char* argtypes[8]; /* should be derived from obj/fmgr.h instead of hardwired*/ - char* prorettype; - int retset; /* 1 if the function returns a set, 0 otherwise */ - char* prosrc; - char* probin; - char* usename; - int dumped; /* 1 if already dumped */ -} FuncInfo; - -typedef struct _tableInfo { - char *oid; - char *relname; - char *relarch; - char *relacl; - bool sequence; - int numatts; /* number of attributes */ - int *inhAttrs; /* an array of flags, one for each attribute - if the value is 1, then this attribute is - an inherited attribute */ - char **attnames; /* the attribute names */ - char **typnames; /* fill out attributes */ - bool *notnull; /* Not null constraints of an attribute */ - int numParents; /* number of (immediate) parent supertables */ - char **parentRels; /* names of parent relations, NULL - if numParents == 0 */ - char **out_attnames; /* the attribute names, in the order they would - be in, when the table is created in the - target query language. - this is needed because the SQL tables will - not have the same order of attributes as - the POSTQUEL tables */ - int *attlen; /* attribute lengths */ - char* usename; - -} TableInfo; - -typedef struct _inhInfo { - char *inhrel; - char *inhparent; -} InhInfo; - -typedef struct _indInfo { - char *indexrelname; /* name of the secondary index class */ - char *indrelname; /* name of the indexed heap class */ - char *indamname; /* name of the access method (e.g. btree, rtree, etc.) */ - char *indproc; /* oid of the function to compute the index, 0 if none*/ - char *indkey[INDEX_MAX_KEYS]; /* attribute numbers of the key attributes */ - char *indclass[INDEX_MAX_KEYS]; /* opclass of the keys */ - char *indisunique; /* is this index unique? */ -} IndInfo; - -typedef struct _aggInfo { - char *oid; - char *aggname; - char *aggtransfn1; - char *aggtransfn2; - char *aggfinalfn; - char *aggtranstype1; - char *aggbasetype; - char *aggtranstype2; - char *agginitval1; - char *agginitval2; - char* usename; -} AggInfo; - -typedef struct _oprInfo { - char *oid; - char *oprname; - char *oprkind; /* "b" = binary, "l" = left unary, "r" = right unary */ - char *oprcode; /* operator function name */ - char *oprleft; /* left operand type */ - char *oprright; /* right operand type */ - char *oprcom; /* oid of the commutator operator */ - char *oprnegate; /* oid of the negator operator */ - char *oprrest; /* name of the function to calculate operator restriction - selectivity */ - char *oprjoin; /* name of the function to calculate operator join - selectivity */ - char *oprcanhash; /* can we use hash join strategy ? */ - char *oprlsortop; /* oid's of the left and right sort operators */ - char *oprrsortop; - char* usename; -} OprInfo; + +typedef struct _typeInfo +{ + char *oid; + char *typowner; + char *typname; + char *typlen; + char *typprtlen; + char *typinput; + char *typoutput; + char *typreceive; + char *typsend; + char *typelem; + char *typdelim; + char *typdefault; + char *typrelid; + char *usename; + int passedbyvalue; + int isArray; +} TypeInfo; + +typedef struct _funcInfo +{ + char *oid; + char *proname; + char *proowner; + int lang; /* 1 if C, else SQL */ + int nargs; + char *argtypes[8];/* should be derived from obj/fmgr.h + * instead of hardwired */ + char *prorettype; + int retset; /* 1 if the function returns a set, 0 + * otherwise */ + char *prosrc; + char *probin; + char *usename; + int dumped; /* 1 if already dumped */ +} FuncInfo; + +typedef struct _tableInfo +{ + char *oid; + char *relname; + char *relarch; + char *relacl; + bool sequence; + int numatts; /* number of attributes */ + int *inhAttrs; /* an array of flags, one for each + * attribute if the value is 1, then this + * attribute is an inherited attribute */ + char **attnames; /* the attribute names */ + char **typnames; /* fill out attributes */ + bool *notnull; /* Not null constraints of an attribute */ + int numParents; /* number of (immediate) parent + * supertables */ + char **parentRels; /* names of parent relations, NULL if + * numParents == 0 */ + char **out_attnames; /* the attribute names, in the + * order they would be in, when + * the table is created in the + * target query language. this is + * needed because the SQL tables + * will not have the same order of + * attributes as the POSTQUEL + * tables */ + int *attlen; /* attribute lengths */ + char *usename; + +} TableInfo; + +typedef struct _inhInfo +{ + char *inhrel; + char *inhparent; +} InhInfo; + +typedef struct _indInfo +{ + char *indexrelname; /* name of the secondary index + * class */ + char *indrelname; /* name of the indexed heap class */ + char *indamname; /* name of the access method (e.g. btree, + * rtree, etc.) */ + char *indproc; /* oid of the function to compute the + * index, 0 if none */ + char *indkey[INDEX_MAX_KEYS]; /* attribute numbers of + * the key attributes */ + char *indclass[INDEX_MAX_KEYS]; /* opclass of the keys */ + char *indisunique;/* is this index unique? */ +} IndInfo; + +typedef struct _aggInfo +{ + char *oid; + char *aggname; + char *aggtransfn1; + char *aggtransfn2; + char *aggfinalfn; + char *aggtranstype1; + char *aggbasetype; + char *aggtranstype2; + char *agginitval1; + char *agginitval2; + char *usename; +} AggInfo; + +typedef struct _oprInfo +{ + char *oid; + char *oprname; + char *oprkind; /* "b" = binary, "l" = left unary, "r" = + * right unary */ + char *oprcode; /* operator function name */ + char *oprleft; /* left operand type */ + char *oprright; /* right operand type */ + char *oprcom; /* oid of the commutator operator */ + char *oprnegate; /* oid of the negator operator */ + char *oprrest; /* name of the function to calculate + * operator restriction selectivity */ + char *oprjoin; /* name of the function to calculate + * operator join selectivity */ + char *oprcanhash; /* can we use hash join strategy ? */ + char *oprlsortop; /* oid's of the left and right sort + * operators */ + char *oprrsortop; + char *usename; +} OprInfo; /* global decls */ -extern bool g_verbose; /* verbose flag */ -extern int g_last_builtin_oid; /* value of the last builtin oid */ -extern FILE *g_fout; /* the script file */ +extern bool g_verbose; /* verbose flag */ +extern int g_last_builtin_oid; /* value of the last builtin oid */ +extern FILE *g_fout; /* the script file */ /* placeholders for comment starting and ending delimiters */ -extern char g_comment_start[10]; -extern char g_comment_end[10]; +extern char g_comment_start[10]; +extern char g_comment_end[10]; -extern char g_opaque_type[10]; /* name for the opaque type */ +extern char g_opaque_type[10]; /* name for the opaque type */ /* pg_dump is really two programs in one - one version works with postgres v4r2 - and the other works with postgres95 - the common routines are declared here + one version works with postgres v4r2 + and the other works with postgres95 + the common routines are declared here */ /* - * common utility functions + * common utility functions */ -extern TableInfo* dumpSchema(FILE* fout, - int *numTablesPtr, - const char *tablename, - const bool acls); -extern void dumpSchemaIdx(FILE* fout, - int *numTablesPtr, +extern TableInfo * +dumpSchema(FILE * fout, + int *numTablesPtr, + const char *tablename, + const bool acls); +extern void +dumpSchemaIdx(FILE * fout, + int *numTablesPtr, const char *tablename, - TableInfo* tblinfo, + TableInfo * tblinfo, int numTables); -extern char* findTypeByOid(TypeInfo* tinfo, int numTypes, const char* oid); -extern char* findOprByOid(OprInfo *oprinfo, int numOprs, const char *oid); -extern int findFuncByName(FuncInfo* finfo, int numFuncs, const char* name); -extern int findTableByName(TableInfo *tbinfo, int numTables, const char *relname); +extern char *findTypeByOid(TypeInfo * tinfo, int numTypes, const char *oid); +extern char *findOprByOid(OprInfo * oprinfo, int numOprs, const char *oid); +extern int findFuncByName(FuncInfo * finfo, int numFuncs, const char *name); +extern int findTableByName(TableInfo * tbinfo, int numTables, const char *relname); -extern void check_conn_and_db(void); -extern void parseArgTypes(char **argtypes, const char* str); -extern int isArchiveName(const char*); +extern void check_conn_and_db(void); +extern void parseArgTypes(char **argtypes, const char *str); +extern int isArchiveName(const char *); /* - * version specific routines + * version specific routines */ -extern TypeInfo* getTypes(int *numTypes); -extern FuncInfo* getFuncs(int *numFuncs); -extern AggInfo* getAggregates(int *numAggregates); - -extern void clearAggInfo(AggInfo*, int); -extern void clearFuncInfo(FuncInfo*, int); -extern void clearInhInfo(InhInfo*, int); -extern void clearIndInfo(IndInfo*, int); -extern void clearOprInfo(OprInfo*, int); -extern void clearTypeInfo(TypeInfo*, int); - -extern OprInfo* getOperators(int *numOperators); -extern TableInfo* getTables(int *numTables); -extern InhInfo* getInherits(int *numInherits); -extern void getTableAttrs(TableInfo* tbinfo, int numTables); -extern IndInfo* getIndices(int *numIndices); -extern void dumpTypes(FILE* fout, FuncInfo* finfo, int numFuncs, - TypeInfo* tinfo, int numTypes); -extern void dumpFuncs(FILE* fout, FuncInfo* finfo, int numFuncs, - TypeInfo *tinfo, int numTypes); -extern void dumpAggs(FILE* fout, AggInfo* agginfo, int numAggregates, - TypeInfo *tinfo, int numTypes); -extern void dumpOprs(FILE* fout, OprInfo* agginfo, int numOperators, - TypeInfo *tinfo, int numTypes); -extern void dumpTables(FILE* fout, TableInfo* tbinfo, int numTables, - InhInfo *inhinfo, int numInherits, - TypeInfo *tinfo, int numTypes, const char *tablename, - const bool acls); -extern void dumpIndices(FILE* fout, IndInfo* indinfo, int numIndices, - TableInfo* tbinfo, int numTables, const char *tablename); +extern TypeInfo *getTypes(int *numTypes); +extern FuncInfo *getFuncs(int *numFuncs); +extern AggInfo *getAggregates(int *numAggregates); + +extern void clearAggInfo(AggInfo *, int); +extern void clearFuncInfo(FuncInfo *, int); +extern void clearInhInfo(InhInfo *, int); +extern void clearIndInfo(IndInfo *, int); +extern void clearOprInfo(OprInfo *, int); +extern void clearTypeInfo(TypeInfo *, int); + +extern OprInfo *getOperators(int *numOperators); +extern TableInfo *getTables(int *numTables); +extern InhInfo *getInherits(int *numInherits); +extern void getTableAttrs(TableInfo * tbinfo, int numTables); +extern IndInfo *getIndices(int *numIndices); +extern void +dumpTypes(FILE * fout, FuncInfo * finfo, int numFuncs, + TypeInfo * tinfo, int numTypes); +extern void +dumpFuncs(FILE * fout, FuncInfo * finfo, int numFuncs, + TypeInfo * tinfo, int numTypes); +extern void +dumpAggs(FILE * fout, AggInfo * agginfo, int numAggregates, + TypeInfo * tinfo, int numTypes); +extern void +dumpOprs(FILE * fout, OprInfo * agginfo, int numOperators, + TypeInfo * tinfo, int numTypes); +extern void +dumpTables(FILE * fout, TableInfo * tbinfo, int numTables, + InhInfo * inhinfo, int numInherits, + TypeInfo * tinfo, int numTypes, const char *tablename, + const bool acls); +extern void +dumpIndices(FILE * fout, IndInfo * indinfo, int numIndices, + TableInfo * tbinfo, int numTables, const char *tablename); /* largest query string size */ #define MAXQUERYLEN 5000 /* these voodoo constants are from the backend */ -#define C_PROLANG_OID 13 +#define C_PROLANG_OID 13 diff --git a/src/bin/pg_id/pg_id.c b/src/bin/pg_id/pg_id.c index 4364fc1cf29..b782b091a3e 100644 --- a/src/bin/pg_id/pg_id.c +++ b/src/bin/pg_id/pg_id.c @@ -1,15 +1,15 @@ /*------------------------------------------------------------------------- * * pg_id.c-- - * Print the user ID for the login name passed as argument, - * or the real user ID of the caller if no argument. If the - * login name doesn't exist, print "NOUSER" and exit 1. + * Print the user ID for the login name passed as argument, + * or the real user ID of the caller if no argument. If the + * login name doesn't exist, print "NOUSER" and exit 1. * * Copyright (c) 1994, Regents of the University of California * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/bin/pg_id/Attic/pg_id.c,v 1.3 1996/11/08 06:01:12 momjian Exp $ + * $Header: /cvsroot/pgsql/src/bin/pg_id/Attic/pg_id.c,v 1.4 1997/09/07 04:54:46 momjian Exp $ * *------------------------------------------------------------------------- */ @@ -23,33 +23,39 @@ int main(int argc, char **argv) { - struct passwd *pw; - int ch; - extern int optind; + struct passwd *pw; + int ch; + extern int optind; - while ((ch = getopt(argc, argv, "")) != EOF) - switch (ch) { - case '?': - default: - fprintf(stderr, "usage: pg_id [login]\n"); - exit(1); - } - argc -= optind; - argv += optind; + while ((ch = getopt(argc, argv, "")) != EOF) + switch (ch) + { + case '?': + default: + fprintf(stderr, "usage: pg_id [login]\n"); + exit(1); + } + argc -= optind; + argv += optind; - if (argc > 0) { - if (argc > 1) { - fprintf(stderr, "usage: pg_id [login]\n"); - exit(1); + if (argc > 0) + { + if (argc > 1) + { + fprintf(stderr, "usage: pg_id [login]\n"); + exit(1); + } + if ((pw = getpwnam(argv[0])) == NULL) + { + printf("NOUSER\n"); + exit(1); + } + printf("%ld\n", (long) pw->pw_uid); } - if ((pw = getpwnam(argv[0])) == NULL) { - printf("NOUSER\n"); - exit(1); + else + { + printf("%ld\n", (long) getuid()); } - printf("%ld\n", (long)pw->pw_uid); - } else { - printf("%ld\n", (long)getuid()); - } - exit(0); + exit(0); } diff --git a/src/bin/pg_passwd/pg_passwd.c b/src/bin/pg_passwd/pg_passwd.c index c1e752a586f..9a99b45b69e 100644 --- a/src/bin/pg_passwd/pg_passwd.c +++ b/src/bin/pg_passwd/pg_passwd.c @@ -1,5 +1,5 @@ /* - * @(#) pg_passwd.c 1.8 09:13:16 97/07/02 Y. Ichikawa + * @(#) pg_passwd.c 1.8 09:13:16 97/07/02 Y. Ichikawa */ #include <stdio.h> @@ -19,309 +19,364 @@ #ifdef HAVE_CRYPT_H #include <crypt.h> #else -extern char *crypt(const char *, const char *); -#endif +extern char *crypt(const char *, const char *); -char *comname; -void usage(FILE *stream); -void read_pwd_file(char *filename); -void write_pwd_file(char *filename, char *bkname); -void encrypt_pwd(char key[9], char salt[3], char passwd[14]); -int check_pwd(char key[9], char passwd[14]); -void prompt_for_username(char *username); -void prompt_for_password(char *prompt, char *password); +#endif -void usage(FILE *stream) +char *comname; +void usage(FILE * stream); +void read_pwd_file(char *filename); +void write_pwd_file(char *filename, char *bkname); +void encrypt_pwd(char key[9], char salt[3], char passwd[14]); +int check_pwd(char key[9], char passwd[14]); +void prompt_for_username(char *username); +void prompt_for_password(char *prompt, char *password); + +void +usage(FILE * stream) { fprintf(stream, "Usage: %s <password file>\n", comname); } -typedef struct { - char *uname; - char *pwd; - char *rest; -} pg_pwd; +typedef struct +{ + char *uname; + char *pwd; + char *rest; +} pg_pwd; -#define MAXPWDS 1024 +#define MAXPWDS 1024 -pg_pwd pwds[MAXPWDS]; -int npwds = 0; +pg_pwd pwds[MAXPWDS]; +int npwds = 0; -void read_pwd_file(char *filename) +void +read_pwd_file(char *filename) { - FILE *fp; - static char line[512]; - static char ans[128]; - int i; - - try_again: - fp = fopen(filename, "r"); - if (fp == NULL) { - if (errno == ENOENT) { - printf("File \"%s\" does not exist. Create? (y/n): ", filename); - fflush(stdout); - fgets(ans, 128, stdin); - switch (ans[0]) { - case 'y': case 'Y': - fp = fopen(filename, "w"); - if (fp == NULL) { - perror(filename); - exit(1); + FILE *fp; + static char line[512]; + static char ans[128]; + int i; + +try_again: + fp = fopen(filename, "r"); + if (fp == NULL) + { + if (errno == ENOENT) + { + printf("File \"%s\" does not exist. Create? (y/n): ", filename); + fflush(stdout); + fgets(ans, 128, stdin); + switch (ans[0]) + { + case 'y': + case 'Y': + fp = fopen(filename, "w"); + if (fp == NULL) + { + perror(filename); + exit(1); + } + fclose(fp); + goto try_again; + default: + /* cannot continue */ + exit(1); + } + } + else + { + perror(filename); + exit(1); } - fclose(fp); - goto try_again; - default: - /* cannot continue */ - exit(1); - } - } else { - perror(filename); - exit(1); - } - } - - /* read all the entries */ - for (npwds = 0; npwds < MAXPWDS && fgets(line, 512, fp) != NULL; ++npwds) { - int l; - char *p, *q; - l = strlen(line); - if (line[l-1] == '\n') - line[l-1] = '\0'; - else { /* too long */ - fprintf(stderr, "%s: line %d: line too long.\n", - filename, npwds + 1); - exit(1); } - /* get user name */ - p = line; - if ((q = index(p, ':')) == NULL) { - fprintf(stderr, "%s: line %d: illegal format.\n", - filename, npwds + 1); - exit(1); - } - *(q++) = '\0'; - if (strlen(p) == 0) { - fprintf(stderr, "%s: line %d: null user name.\n", - filename, npwds + 1); - exit(1); + /* read all the entries */ + for (npwds = 0; npwds < MAXPWDS && fgets(line, 512, fp) != NULL; ++npwds) + { + int l; + char *p, + *q; + + l = strlen(line); + if (line[l - 1] == '\n') + line[l - 1] = '\0'; + else + { /* too long */ + fprintf(stderr, "%s: line %d: line too long.\n", + filename, npwds + 1); + exit(1); + } + + /* get user name */ + p = line; + if ((q = index(p, ':')) == NULL) + { + fprintf(stderr, "%s: line %d: illegal format.\n", + filename, npwds + 1); + exit(1); + } + *(q++) = '\0'; + if (strlen(p) == 0) + { + fprintf(stderr, "%s: line %d: null user name.\n", + filename, npwds + 1); + exit(1); + } + pwds[npwds].uname = strdup(p); + + /* check duplicate */ + for (i = 0; i < npwds; ++i) + { + if (strcmp(pwds[i].uname, pwds[npwds].uname) == 0) + { + fprintf(stderr, "%s: duplicated entry.\n", pwds[npwds].uname); + exit(1); + } + } + + /* get password field */ + p = q; + q = index(p, ':'); + + /* + * --- don't care ----- if ((q = index(p, ':')) == NULL) { + * fprintf(stderr, "%s: line %d: illegal format.\n", filename, + * npwds + 1); exit(1); } + */ + + if (q != NULL) + *(q++) = '\0'; + if (strlen(p) != 13) + { + fprintf(stderr, "WARNING: %s: line %d: illegal password length.\n", + filename, npwds + 1); + } + pwds[npwds].pwd = strdup(p); + + /* rest of the line is treated as is */ + if (q == NULL) + pwds[npwds].rest = NULL; + else + pwds[npwds].rest = strdup(q); } - pwds[npwds].uname = strdup(p); - /* check duplicate */ - for (i = 0; i < npwds; ++i) { - if (strcmp(pwds[i].uname, pwds[npwds].uname) == 0) { - fprintf(stderr, "%s: duplicated entry.\n", pwds[npwds].uname); + fclose(fp); +} + +void +write_pwd_file(char *filename, char *bkname) +{ + FILE *fp; + int i; + + /* make the backup file */ +link_again: + if (link(filename, bkname)) + { + if (errno == EEXIST) + { + unlink(bkname); + goto link_again; + } + perror(bkname); exit(1); - } } - - /* get password field */ - p = q; - q = index(p, ':'); - /* - * --- don't care ----- - if ((q = index(p, ':')) == NULL) { - fprintf(stderr, "%s: line %d: illegal format.\n", - filename, npwds + 1); - exit(1); + if (unlink(filename)) + { + perror(filename); + exit(1); } - */ - if (q != NULL) *(q++) = '\0'; - if (strlen(p) != 13) { - fprintf(stderr, "WARNING: %s: line %d: illegal password length.\n", - filename, npwds + 1); + /* open file */ + if ((fp = fopen(filename, "w")) == NULL) + { + perror(filename); + exit(1); } - pwds[npwds].pwd = strdup(p); - /* rest of the line is treated as is */ - if (q == NULL) - pwds[npwds].rest = NULL; - else - pwds[npwds].rest = strdup(q); - } + /* write file */ + for (i = 0; i < npwds; ++i) + { + fprintf(fp, "%s:%s%s%s\n", pwds[i].uname, pwds[i].pwd, + pwds[i].rest ? ":" : "", + pwds[i].rest ? pwds[i].rest : ""); + } - fclose(fp); + fclose(fp); } -void write_pwd_file(char *filename, char *bkname) +void +encrypt_pwd(char key[9], char salt[3], char passwd[14]) { - FILE* fp; - int i; - - /* make the backup file */ - link_again: - if (link(filename, bkname)) { - if (errno == EEXIST) { - unlink(bkname); - goto link_again; + int n; + + /* get encrypted password */ + if (salt[0] == '\0') + { + struct timeval tm; + + gettimeofday(&tm, NULL); + srand(tm.tv_sec ? tm.tv_sec : 1); + do + { + n = rand() % 256; + } while (!issaltchar(n)); + salt[0] = n; + do + { + n = rand() % 256; + } while (!issaltchar(n)); + salt[1] = n; + salt[2] = '\0'; } - perror(bkname); - exit(1); - } - if (unlink(filename)) { - perror(filename); - exit(1); - } - - /* open file */ - if ((fp = fopen(filename, "w")) == NULL) { - perror(filename); - exit(1); - } - - /* write file */ - for (i = 0; i < npwds; ++i) { - fprintf(fp, "%s:%s%s%s\n", pwds[i].uname, pwds[i].pwd, - pwds[i].rest ? ":" : "", - pwds[i].rest ? pwds[i].rest : ""); - } - - fclose(fp); + strcpy(passwd, crypt(key, salt)); + + /* show it */ + + /* + * fprintf(stderr, "key = %s, salt = %s, password = %s\n", key, salt, + * passwd); + */ } -void encrypt_pwd(char key[9], char salt[3], char passwd[14]) +int +check_pwd(char key[9], char passwd[14]) { - int n; - - /* get encrypted password */ - if (salt[0] == '\0') { - struct timeval tm; - gettimeofday(&tm, NULL); - srand(tm.tv_sec ? tm.tv_sec : 1); - do { - n = rand() % 256; - } while (! issaltchar(n)); - salt[0] = n; - do { - n = rand() % 256; - } while (! issaltchar(n)); - salt[1] = n; + char shouldbe[14]; + char salt[3]; + + salt[0] = passwd[0]; + salt[1] = passwd[1]; salt[2] = '\0'; - } - strcpy(passwd, crypt(key, salt)); + encrypt_pwd(key, salt, shouldbe); - /* show it */ - /* fprintf(stderr, "key = %s, salt = %s, password = %s\n", - key, salt, passwd); */ + return strncmp(shouldbe, passwd, 13) == 0 ? 1 : 0; } -int check_pwd(char key[9], char passwd[14]) +void +prompt_for_username(char *username) { - char shouldbe[14]; - char salt[3]; + int length; - salt[0] = passwd[0]; - salt[1] = passwd[1]; - salt[2] = '\0'; - encrypt_pwd(key, salt, shouldbe); + printf("Username: "); + fgets(username, 9, stdin); + length = strlen(username); - return strncmp(shouldbe, passwd, 13) == 0 ? 1 : 0; -} + /* skip rest of the line */ + if (length > 0 && username[length - 1] != '\n') + { + static char buf[512]; -void prompt_for_username(char *username) -{ - int length; - - printf("Username: "); - fgets(username, 9, stdin); - length = strlen(username); - - /* skip rest of the line */ - if (length > 0 && username[length-1] != '\n') { - static char buf[512]; - do { - fgets(buf, 512, stdin); - } while (buf[strlen(buf)-1] != '\n'); - } - if(length > 0 && username[length-1] == '\n') username[length-1] = '\0'; + do + { + fgets(buf, 512, stdin); + } while (buf[strlen(buf) - 1] != '\n'); + } + if (length > 0 && username[length - 1] == '\n') + username[length - 1] = '\0'; } -void prompt_for_password(char *prompt, char *password) +void +prompt_for_password(char *prompt, char *password) { - int length; + int length; + #ifdef HAVE_TERMIOS_H - struct termios t_orig, t; + struct termios t_orig, + t; + #endif - printf(prompt); + printf(prompt); #ifdef HAVE_TERMIOS_H - tcgetattr(0, &t); - t_orig = t; - t.c_lflag &= ~ECHO; - tcsetattr(0, TCSADRAIN, &t); + tcgetattr(0, &t); + t_orig = t; + t.c_lflag &= ~ECHO; + tcsetattr(0, TCSADRAIN, &t); #endif - fgets(password, 9, stdin); + fgets(password, 9, stdin); #ifdef HAVE_TERMIOS_H - tcsetattr(0, TCSADRAIN, &t_orig); + tcsetattr(0, TCSADRAIN, &t_orig); #endif - length = strlen(password); - /* skip rest of the line */ - if (length > 0 && password[length-1] != '\n') { - static char buf[512]; - do { - fgets(buf, 512, stdin); - } while (buf[strlen(buf)-1] != '\n'); - } - if(length > 0 && password[length-1] == '\n') password[length-1] = '\0'; - printf("\n"); + length = strlen(password); + /* skip rest of the line */ + if (length > 0 && password[length - 1] != '\n') + { + static char buf[512]; + + do + { + fgets(buf, 512, stdin); + } while (buf[strlen(buf) - 1] != '\n'); + } + if (length > 0 && password[length - 1] == '\n') + password[length - 1] = '\0'; + printf("\n"); } -int main(int argc, char *argv[]) +int +main(int argc, char *argv[]) { - static char bkname[512]; - char username[9]; - char salt[3]; - char key[9], key2[9]; - char e_passwd[14]; - int i; - - comname = argv[0]; - if (argc != 2) { - usage(stderr); - exit(1); - } - - - /* open file */ - read_pwd_file(argv[1]); - - /* ask for the user name and the password */ - prompt_for_username(username); - prompt_for_password("New password: ", key); - prompt_for_password("Re-enter new password: ", key2); - if (strncmp(key, key2, 8) != 0) { - fprintf(stderr, "Password mismatch.\n"); - exit(1); - } - salt[0] = '\0'; - encrypt_pwd(key, salt, e_passwd); - - /* check password entry */ - for (i = 0; i < npwds; ++i) { - if (strcmp(pwds[i].uname, username) == 0) { /* found */ - pwds[i].pwd = strdup(e_passwd); - break; + static char bkname[512]; + char username[9]; + char salt[3]; + char key[9], + key2[9]; + char e_passwd[14]; + int i; + + comname = argv[0]; + if (argc != 2) + { + usage(stderr); + exit(1); } - } - if (i == npwds) { /* did not exist */ - if (npwds == MAXPWDS) { - fprintf(stderr, "%s: cannot handle so may entries.\n", comname); - exit(1); + + + /* open file */ + read_pwd_file(argv[1]); + + /* ask for the user name and the password */ + prompt_for_username(username); + prompt_for_password("New password: ", key); + prompt_for_password("Re-enter new password: ", key2); + if (strncmp(key, key2, 8) != 0) + { + fprintf(stderr, "Password mismatch.\n"); + exit(1); + } + salt[0] = '\0'; + encrypt_pwd(key, salt, e_passwd); + + /* check password entry */ + for (i = 0; i < npwds; ++i) + { + if (strcmp(pwds[i].uname, username) == 0) + { /* found */ + pwds[i].pwd = strdup(e_passwd); + break; + } + } + if (i == npwds) + { /* did not exist */ + if (npwds == MAXPWDS) + { + fprintf(stderr, "%s: cannot handle so may entries.\n", comname); + exit(1); + } + pwds[npwds].uname = strdup(username); + pwds[npwds].pwd = strdup(e_passwd); + pwds[npwds].rest = NULL; + ++npwds; } - pwds[npwds].uname = strdup(username); - pwds[npwds].pwd = strdup(e_passwd); - pwds[npwds].rest = NULL; - ++npwds; - } - /* write back the file */ - sprintf(bkname, "%s.bk", argv[1]); - write_pwd_file(argv[1], bkname); + /* write back the file */ + sprintf(bkname, "%s.bk", argv[1]); + write_pwd_file(argv[1], bkname); - return 0; + return 0; } diff --git a/src/bin/pg_version/pg_version.c b/src/bin/pg_version/pg_version.c index 5cdf3cad5d0..314ddddeb2d 100644 --- a/src/bin/pg_version/pg_version.c +++ b/src/bin/pg_version/pg_version.c @@ -1,40 +1,45 @@ /*------------------------------------------------------------------------- * * pg_version.c-- - * + * * * Copyright (c) 1994, Regents of the University of California * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/bin/pg_version/Attic/pg_version.c,v 1.6 1996/11/12 06:47:00 bryanh Exp $ + * $Header: /cvsroot/pgsql/src/bin/pg_version/Attic/pg_version.c,v 1.7 1997/09/07 04:54:56 momjian Exp $ * *------------------------------------------------------------------------- */ #include <stdlib.h> #include <stdio.h> -#include <version.h> /* interface to SetPgVersion */ +#include <version.h> /* interface to SetPgVersion */ int main(int argc, char **argv) { - int retcode; /* our eventual return code */ - char *reason; /* Reason that SetPgVersion failed, NULL if it didn't. */ + int retcode; /* our eventual return code */ + char *reason; /* Reason that SetPgVersion failed, NULL + * if it didn't. */ - if (argc < 2) { - fprintf(stderr, "pg_version: missing argument\n"); - exit(1); - } - SetPgVersion(argv[1], &reason); - if (reason) { - fprintf(stderr, - "pg_version is unable to create the PG_VERSION file. " - "SetPgVersion gave this reason: %s\n", - reason); - retcode = 10; - } else retcode = 0; - return(retcode); + if (argc < 2) + { + fprintf(stderr, "pg_version: missing argument\n"); + exit(1); + } + SetPgVersion(argv[1], &reason); + if (reason) + { + fprintf(stderr, + "pg_version is unable to create the PG_VERSION file. " + "SetPgVersion gave this reason: %s\n", + reason); + retcode = 10; + } + else + retcode = 0; + return (retcode); } diff --git a/src/bin/pgtclsh/pgtclAppInit.c b/src/bin/pgtclsh/pgtclAppInit.c index b44a46f6811..1c9040fbd53 100644 --- a/src/bin/pgtclsh/pgtclAppInit.c +++ b/src/bin/pgtclsh/pgtclAppInit.c @@ -1,8 +1,8 @@ -/* +/* * pgtclAppInit.c -- * - * a skeletal Tcl_AppInit that provides pgtcl initialization - * to create a tclsh that can talk to pglite backends + * a skeletal Tcl_AppInit that provides pgtcl initialization + * to create a tclsh that can talk to pglite backends * * Copyright (c) 1993 The Regents of the University of California. * Copyright (c) 1994 Sun Microsystems, Inc. @@ -21,23 +21,25 @@ */ #ifdef NEED_MATHERR -extern int matherr(); -int *tclDummyMathPtr = (int *) matherr; +extern int matherr(); +int *tclDummyMathPtr = (int *) matherr; + #endif - + + /* *---------------------------------------------------------------------- * * main -- * - * This is the main program for the application. + * This is the main program for the application. * * Results: - * None: Tcl_Main never returns here, so this procedure never - * returns either. + * None: Tcl_Main never returns here, so this procedure never + * returns either. * * Side effects: - * Whatever the application does. + * Whatever the application does. * *---------------------------------------------------------------------- */ @@ -45,68 +47,71 @@ int *tclDummyMathPtr = (int *) matherr; int main(int argc, char **argv) { - Tcl_Main(argc, argv, Tcl_AppInit); - return 0; /* Needed only to prevent compiler warning. */ + Tcl_Main(argc, argv, Tcl_AppInit); + return 0; /* Needed only to prevent compiler + * warning. */ } - + + /* *---------------------------------------------------------------------- * * Tcl_AppInit -- * - * This procedure performs application-specific initialization. - * Most applications, especially those that incorporate additional - * packages, will have their own version of this procedure. + * This procedure performs application-specific initialization. + * Most applications, especially those that incorporate additional + * packages, will have their own version of this procedure. * * Results: - * Returns a standard Tcl completion code, and leaves an error - * message in interp->result if an error occurs. + * Returns a standard Tcl completion code, and leaves an error + * message in interp->result if an error occurs. * * Side effects: - * Depends on the startup script. + * Depends on the startup script. * *---------------------------------------------------------------------- */ int -Tcl_AppInit(Tcl_Interp *interp) +Tcl_AppInit(Tcl_Interp * interp) { - if (Tcl_Init(interp) == TCL_ERROR) { - return TCL_ERROR; - } - - /* - * Call the init procedures for included packages. Each call should - * look like this: - * - * if (Mod_Init(interp) == TCL_ERROR) { - * return TCL_ERROR; - * } - * - * where "Mod" is the name of the module. - */ - - if (Pgtcl_Init(interp) == TCL_ERROR) { - return TCL_ERROR; - } - - /* - * Call Tcl_CreateCommand for application-specific commands, if - * they weren't already created by the init procedures called above. - */ - - /* - * Specify a user-specific startup file to invoke if the application - * is run interactively. Typically the startup file is "~/.apprc" - * where "app" is the name of the application. If this line is deleted - * then no user-specific startup file will be run under any conditions. - */ + if (Tcl_Init(interp) == TCL_ERROR) + { + return TCL_ERROR; + } + + /* + * Call the init procedures for included packages. Each call should + * look like this: + * + * if (Mod_Init(interp) == TCL_ERROR) { return TCL_ERROR; } + * + * where "Mod" is the name of the module. + */ + + if (Pgtcl_Init(interp) == TCL_ERROR) + { + return TCL_ERROR; + } + + /* + * Call Tcl_CreateCommand for application-specific commands, if they + * weren't already created by the init procedures called above. + */ + + /* + * Specify a user-specific startup file to invoke if the application + * is run interactively. Typically the startup file is "~/.apprc" + * where "app" is the name of the application. If this line is + * deleted then no user-specific startup file will be run under any + * conditions. + */ #if (TCL_MAJOR_VERSION <= 7) && (TCL_MINOR_VERSION < 5) - tcl_RcFileName = "~/.tclshrc"; + tcl_RcFileName = "~/.tclshrc"; #else - Tcl_SetVar(interp, "tcl_rcFileName", "~/.tclshrc", TCL_GLOBAL_ONLY); + Tcl_SetVar(interp, "tcl_rcFileName", "~/.tclshrc", TCL_GLOBAL_ONLY); #endif - return TCL_OK; + return TCL_OK; } diff --git a/src/bin/pgtclsh/pgtkAppInit.c b/src/bin/pgtclsh/pgtkAppInit.c index 5be20ec589c..fbca4cca2e5 100644 --- a/src/bin/pgtclsh/pgtkAppInit.c +++ b/src/bin/pgtclsh/pgtkAppInit.c @@ -1,8 +1,8 @@ -/* +/* * pgtkAppInit.c -- * - * a skeletal Tcl_AppInit that provides pgtcl initialization - * to create a tclsh that can talk to pglite backends + * a skeletal Tcl_AppInit that provides pgtcl initialization + * to create a tclsh that can talk to pglite backends * * Copyright (c) 1993 The Regents of the University of California. * Copyright (c) 1994 Sun Microsystems, Inc. @@ -20,23 +20,25 @@ */ #ifdef NEED_MATHERR -extern int matherr(); -int *tclDummyMathPtr = (int *) matherr; +extern int matherr(); +int *tclDummyMathPtr = (int *) matherr; + #endif - + + /* *---------------------------------------------------------------------- * * main -- * - * This is the main program for the application. + * This is the main program for the application. * * Results: - * None: Tk_Main never returns here, so this procedure never - * returns either. + * None: Tk_Main never returns here, so this procedure never + * returns either. * * Side effects: - * Whatever the application does. + * Whatever the application does. * *---------------------------------------------------------------------- */ @@ -44,70 +46,75 @@ int *tclDummyMathPtr = (int *) matherr; int main(int argc, char **argv) { - Tk_Main(argc, argv, Tcl_AppInit); - return 0; /* Needed only to prevent compiler warning. */ + Tk_Main(argc, argv, Tcl_AppInit); + return 0; /* Needed only to prevent compiler + * warning. */ } - + + /* *---------------------------------------------------------------------- * * Tcl_AppInit -- * - * This procedure performs application-specific initialization. - * Most applications, especially those that incorporate additional - * packages, will have their own version of this procedure. + * This procedure performs application-specific initialization. + * Most applications, especially those that incorporate additional + * packages, will have their own version of this procedure. * * Results: - * Returns a standard Tcl completion code, and leaves an error - * message in interp->result if an error occurs. + * Returns a standard Tcl completion code, and leaves an error + * message in interp->result if an error occurs. * * Side effects: - * Depends on the startup script. + * Depends on the startup script. * *---------------------------------------------------------------------- */ int -Tcl_AppInit(Tcl_Interp *interp) +Tcl_AppInit(Tcl_Interp * interp) { - if (Tcl_Init(interp) == TCL_ERROR) { - return TCL_ERROR; - } - if (Tk_Init(interp) == TCL_ERROR) { - return TCL_ERROR; - } - - /* - * Call the init procedures for included packages. Each call should - * look like this: - * - * if (Mod_Init(interp) == TCL_ERROR) { - * return TCL_ERROR; - * } - * - * where "Mod" is the name of the module. - */ - - if (Pgtcl_Init(interp) == TCL_ERROR) { - return TCL_ERROR; - } - /* - * Call Tcl_CreateCommand for application-specific commands, if - * they weren't already created by the init procedures called above. - */ - - /* - * Specify a user-specific startup file to invoke if the application - * is run interactively. Typically the startup file is "~/.apprc" - * where "app" is the name of the application. If this line is deleted - * then no user-specific startup file will be run under any conditions. - */ + if (Tcl_Init(interp) == TCL_ERROR) + { + return TCL_ERROR; + } + if (Tk_Init(interp) == TCL_ERROR) + { + return TCL_ERROR; + } + + /* + * Call the init procedures for included packages. Each call should + * look like this: + * + * if (Mod_Init(interp) == TCL_ERROR) { return TCL_ERROR; } + * + * where "Mod" is the name of the module. + */ + + if (Pgtcl_Init(interp) == TCL_ERROR) + { + return TCL_ERROR; + } + + /* + * Call Tcl_CreateCommand for application-specific commands, if they + * weren't already created by the init procedures called above. + */ + + /* + * Specify a user-specific startup file to invoke if the application + * is run interactively. Typically the startup file is "~/.apprc" + * where "app" is the name of the application. If this line is + * deleted then no user-specific startup file will be run under any + * conditions. + */ #if (TCL_MAJOR_VERSION <= 7) && (TCL_MINOR_VERSION < 5) - tcl_RcFileName = "~/.wishrc"; + tcl_RcFileName = "~/.wishrc"; #else - Tcl_SetVar(interp, "tcl_rcFileName", "~/.wishrc", TCL_GLOBAL_ONLY); + Tcl_SetVar(interp, "tcl_rcFileName", "~/.wishrc", TCL_GLOBAL_ONLY); #endif - return TCL_OK; + return TCL_OK; } diff --git a/src/bin/psql/psql.c b/src/bin/psql/psql.c index 0b77a3ff5f1..3a58f8ad321 100644 --- a/src/bin/psql/psql.c +++ b/src/bin/psql/psql.c @@ -1,13 +1,13 @@ /*------------------------------------------------------------------------- * * psql.c-- - * an interactive front-end to postgreSQL + * an interactive front-end to postgreSQL * * Copyright (c) 1996, Regents of the University of California * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/bin/psql/Attic/psql.c,v 1.90 1997/09/05 00:09:30 momjian Exp $ + * $Header: /cvsroot/pgsql/src/bin/psql/Attic/psql.c,v 1.91 1997/09/07 04:55:20 momjian Exp $ * *------------------------------------------------------------------------- */ @@ -17,7 +17,7 @@ #include <signal.h> #include <errno.h> #include <sys/types.h> -#include <sys/param.h> /* for MAXPATHLEN */ +#include <sys/param.h> /* for MAXPATHLEN */ #include <sys/stat.h> #include <unistd.h> #include <fcntl.h> @@ -35,17 +35,17 @@ #endif #ifdef HAVE_LIBREADLINE -# ifdef HAVE_READLINE_H -# include <readline.h> -# if defined(HAVE_HISTORY) -# include <history.h> -# endif -# else -# include <readline/readline.h> -# if defined(HAVE_READLINE_HISTORY_H) -# include <readline/history.h> -# endif -# endif +#ifdef HAVE_READLINE_H +#include <readline.h> +#if defined(HAVE_HISTORY) +#include <history.h> +#endif +#else +#include <readline/readline.h> +#if defined(HAVE_READLINE_HISTORY_H) +#include <readline/history.h> +#endif +#endif #endif /* This prompt string is assumed to have at least 3 characters by code in MainLoop(). @@ -54,80 +54,84 @@ #define PROMPT "=> " #define PROMPT_READY '=' -#define PROMPT_CONTINUE '-' +#define PROMPT_CONTINUE '-' #define PROMPT_COMMENT '*' #define PROMPT_QUOTE '\'' /* Backslash command handling: - * 0 - send currently constructed query to backend (i.e. we got a \g) - * 1 - skip processing of this line, continue building up query - * 2 - terminate processing of this query entirely - * 3 - new query supplied by edit + * 0 - send currently constructed query to backend (i.e. we got a \g) + * 1 - skip processing of this line, continue building up query + * 2 - terminate processing of this query entirely + * 3 - new query supplied by edit */ -#define CMD_UNKNOWN -1 -#define CMD_SEND 0 +#define CMD_UNKNOWN -1 +#define CMD_SEND 0 #define CMD_SKIP_LINE 1 #define CMD_TERMINATE 2 -#define CMD_NEWEDIT 3 +#define CMD_NEWEDIT 3 #define MAX_QUERY_BUFFER 20000 -#define COPYBUFSIZ 8192 +#define COPYBUFSIZ 8192 #define DEFAULT_FIELD_SEP "|" -#define DEFAULT_EDITOR "vi" +#define DEFAULT_EDITOR "vi" #define DEFAULT_SHELL "/bin/sh" -typedef struct _psqlSettings { - PGconn *db; /* connection to backend */ - FILE *queryFout; /* where to send the query results */ - PQprintOpt opt; /* options to be passed to PQprint */ - char *prompt; /* prompt to display */ - char *gfname; /* one-shot file output argument for \g */ - bool notty; /* input or output is not a tty */ - bool pipe; /* queryFout is from a popen() */ - bool echoQuery; /* echo the query before sending it */ - bool quiet; /* run quietly, no messages, no promt */ - bool singleStep; /* prompt before for each query */ - bool singleLineMode; /* query terminated by newline */ - bool useReadline;/* use libreadline routines */ - bool getPassword;/* prompt the user for a username and password */ -} PsqlSettings; +typedef struct _psqlSettings +{ + PGconn *db; /* connection to backend */ + FILE *queryFout; /* where to send the query results */ + PQprintOpt opt; /* options to be passed to PQprint */ + char *prompt; /* prompt to display */ + char *gfname; /* one-shot file output argument for \g */ + bool notty; /* input or output is not a tty */ + bool pipe; /* queryFout is from a popen() */ + bool echoQuery; /* echo the query before sending it */ + bool quiet; /* run quietly, no messages, no promt */ + bool singleStep; /* prompt before for each query */ + bool singleLineMode; /* query terminated by newline */ + bool useReadline;/* use libreadline routines */ + bool getPassword;/* prompt the user for a username and + * password */ +} PsqlSettings; /* declarations for functions in this file */ -static void usage(char *progname); -static void slashUsage(); -static void handleCopyOut(PGresult * res, bool quiet, FILE * copystream); +static void usage(char *progname); +static void slashUsage(); +static void handleCopyOut(PGresult * res, bool quiet, FILE * copystream); static void handleCopyIn(PGresult * res, const bool mustprompt, - FILE * copystream); -static int tableList(PsqlSettings * ps, bool deep_tablelist, char info_type); -static int tableDesc(PsqlSettings * ps, char *table); -static int rightsList(PsqlSettings * ps); -static void prompt_for_password(char *username, char *password); -static char * make_connect_string(char *host, char *port, char *dbname, - char *username, char *password); - -static char *gets_noreadline(char *prompt, FILE * source); -static char *gets_readline(char *prompt, FILE * source); -static char *gets_fromFile(char *prompt, FILE * source); -static int listAllDbs(PsqlSettings * settings); + FILE * copystream); +static int tableList(PsqlSettings * ps, bool deep_tablelist, char info_type); +static int tableDesc(PsqlSettings * ps, char *table); +static int rightsList(PsqlSettings * ps); +static void prompt_for_password(char *username, char *password); +static char * +make_connect_string(char *host, char *port, char *dbname, + char *username, char *password); + +static char *gets_noreadline(char *prompt, FILE * source); +static char *gets_readline(char *prompt, FILE * source); +static char *gets_fromFile(char *prompt, FILE * source); +static int listAllDbs(PsqlSettings * settings); static void SendQuery(bool * success_p, PsqlSettings * settings, const char *query, - const bool copy_in, const bool copy_out, FILE * copystream); + const bool copy_in, const bool copy_out, FILE * copystream); static int HandleSlashCmds(PsqlSettings * settings, - char *line, - char *query); -static int MainLoop(PsqlSettings * settings, FILE * source); + char *line, + char *query); +static int MainLoop(PsqlSettings * settings, FILE * source); + /* probably should move this into libpq */ void PQprint(FILE * fp, - PGresult * res, - PQprintOpt * po + PGresult * res, + PQprintOpt * po ); -static FILE *setFout(PsqlSettings * ps, char *fname); +static FILE *setFout(PsqlSettings * ps, char *fname); /* * usage print out usage for command line arguments @@ -136,28 +140,28 @@ static FILE *setFout(PsqlSettings * ps, char *fname); static void usage(char *progname) { - fprintf(stderr, "Usage: %s [options] [dbname]\n", progname); - fprintf(stderr, "\t -a authsvc set authentication service\n"); - fprintf(stderr, "\t -A turn off alignment when printing out attributes\n"); - fprintf(stderr, "\t -c query run single query (slash commands too)\n"); - fprintf(stderr, "\t -d dbName specify database name\n"); - fprintf(stderr, "\t -e echo the query sent to the backend\n"); - fprintf(stderr, "\t -f filename use file as a source of queries\n"); - fprintf(stderr, "\t -F sep set the field separator (default is '|')\n"); - fprintf(stderr, "\t -h host set database server host\n"); - fprintf(stderr, "\t -H turn on html3.0 table output\n"); - fprintf(stderr, "\t -l list available databases\n"); - fprintf(stderr, "\t -n don't use readline library\n"); - fprintf(stderr, "\t -o filename send output to filename or (|pipe)\n"); - fprintf(stderr, "\t -p port set port number\n"); - fprintf(stderr, "\t -q run quietly (no messages, no prompts)\n"); - fprintf(stderr, "\t -s single step mode (prompts for each query)\n"); - fprintf(stderr, "\t -S single line mode (i.e. query terminated by newline)\n"); - fprintf(stderr, "\t -t turn off printing of headings and row count\n"); - fprintf(stderr, "\t -T html set html3.0 table command options (cf. -H)\n"); - fprintf(stderr, "\t -u ask for a username and password for authentication\n"); - fprintf(stderr, "\t -x turn on expanded output (field names on left)\n"); - exit(1); + fprintf(stderr, "Usage: %s [options] [dbname]\n", progname); + fprintf(stderr, "\t -a authsvc set authentication service\n"); + fprintf(stderr, "\t -A turn off alignment when printing out attributes\n"); + fprintf(stderr, "\t -c query run single query (slash commands too)\n"); + fprintf(stderr, "\t -d dbName specify database name\n"); + fprintf(stderr, "\t -e echo the query sent to the backend\n"); + fprintf(stderr, "\t -f filename use file as a source of queries\n"); + fprintf(stderr, "\t -F sep set the field separator (default is '|')\n"); + fprintf(stderr, "\t -h host set database server host\n"); + fprintf(stderr, "\t -H turn on html3.0 table output\n"); + fprintf(stderr, "\t -l list available databases\n"); + fprintf(stderr, "\t -n don't use readline library\n"); + fprintf(stderr, "\t -o filename send output to filename or (|pipe)\n"); + fprintf(stderr, "\t -p port set port number\n"); + fprintf(stderr, "\t -q run quietly (no messages, no prompts)\n"); + fprintf(stderr, "\t -s single step mode (prompts for each query)\n"); + fprintf(stderr, "\t -S single line mode (i.e. query terminated by newline)\n"); + fprintf(stderr, "\t -t turn off printing of headings and row count\n"); + fprintf(stderr, "\t -T html set html3.0 table command options (cf. -H)\n"); + fprintf(stderr, "\t -u ask for a username and password for authentication\n"); + fprintf(stderr, "\t -x turn on expanded output (field names on left)\n"); + exit(1); } /* @@ -167,412 +171,458 @@ usage(char *progname) static char * on(bool f) { - return f ? "on" : "off"; + return f ? "on" : "off"; } static void slashUsage(PsqlSettings * ps) { - int usePipe = 0; - char *pagerenv; - FILE *fout; - - if (ps->notty == 0 && - (pagerenv = getenv("PAGER")) && - (pagerenv[0] != '\0') && - (fout = popen(pagerenv, "w"))) - { - usePipe = 1; - pqsignal(SIGPIPE, SIG_IGN); - } - else - fout = stdout; - - fprintf(fout, " \\? -- help\n"); - fprintf(fout, " \\a -- toggle field-alignment (currenty %s)\n", on(ps->opt.align)); - fprintf(fout, " \\C [<captn>] -- set html3 caption (currently '%s')\n", ps->opt.caption ? ps->opt.caption : ""); - fprintf(fout, " \\connect <dbname|-> <user> -- connect to new database (currently '%s')\n", PQdb(ps->db)); - fprintf(fout, " \\copy table {from | to} <fname>\n"); - fprintf(fout, " \\d [<table>] -- list tables and indices in database or columns in <table>, * for all\n"); - fprintf(fout, " \\di -- list only indices in database\n"); - fprintf(fout, " \\ds -- list only sequences in database\n"); - fprintf(fout, " \\dt -- list only tables in database\n"); - fprintf(fout, " \\e [<fname>] -- edit the current query buffer or <fname>, \\E execute too\n"); - fprintf(fout, " \\f [<sep>] -- change field separater (currently '%s')\n", ps->opt.fieldSep); - fprintf(fout, " \\g [<fname>] [|<cmd>] -- send query to backend [and results in <fname> or pipe]\n"); - fprintf(fout, " \\h [<cmd>] -- help on syntax of sql commands, * for all commands\n"); - fprintf(fout, " \\H -- toggle html3 output (currently %s)\n", on(ps->opt.html3)); - fprintf(fout, " \\i <fname> -- read and execute queries from filename\n"); - fprintf(fout, " \\l -- list all databases\n"); - fprintf(fout, " \\m -- toggle monitor-like table display (currently %s)\n", on(ps->opt.standard)); - fprintf(fout, " \\o [<fname>] [|<cmd>] -- send all query results to stdout, <fname>, or pipe\n"); - fprintf(fout, " \\p -- print the current query buffer\n"); - fprintf(fout, " \\q -- quit\n"); - fprintf(fout, " \\r -- reset(clear) the query buffer\n"); - fprintf(fout, " \\s [<fname>] -- print history or save it in <fname>\n"); - fprintf(fout, " \\t -- toggle table headings and row count (currently %s)\n", on(ps->opt.header)); - fprintf(fout, " \\T [<html>] -- set html3.0 <table ...> options (currently '%s')\n", ps->opt.tableOpt ? ps->opt.tableOpt : ""); - fprintf(fout, " \\x -- toggle expanded output (currently %s)\n", on(ps->opt.expanded)); - fprintf(fout, " \\z -- list current grant/revoke permissions\n"); - fprintf(fout, " \\! [<cmd>] -- shell escape or command\n"); - - if (usePipe) - { - pclose(fout); - pqsignal(SIGPIPE, SIG_DFL); - } + int usePipe = 0; + char *pagerenv; + FILE *fout; + + if (ps->notty == 0 && + (pagerenv = getenv("PAGER")) && + (pagerenv[0] != '\0') && + (fout = popen(pagerenv, "w"))) + { + usePipe = 1; + pqsignal(SIGPIPE, SIG_IGN); + } + else + fout = stdout; + + fprintf(fout, " \\? -- help\n"); + fprintf(fout, " \\a -- toggle field-alignment (currenty %s)\n", on(ps->opt.align)); + fprintf(fout, " \\C [<captn>] -- set html3 caption (currently '%s')\n", ps->opt.caption ? ps->opt.caption : ""); + fprintf(fout, " \\connect <dbname|-> <user> -- connect to new database (currently '%s')\n", PQdb(ps->db)); + fprintf(fout, " \\copy table {from | to} <fname>\n"); + fprintf(fout, " \\d [<table>] -- list tables and indices in database or columns in <table>, * for all\n"); + fprintf(fout, " \\di -- list only indices in database\n"); + fprintf(fout, " \\ds -- list only sequences in database\n"); + fprintf(fout, " \\dt -- list only tables in database\n"); + fprintf(fout, " \\e [<fname>] -- edit the current query buffer or <fname>, \\E execute too\n"); + fprintf(fout, " \\f [<sep>] -- change field separater (currently '%s')\n", ps->opt.fieldSep); + fprintf(fout, " \\g [<fname>] [|<cmd>] -- send query to backend [and results in <fname> or pipe]\n"); + fprintf(fout, " \\h [<cmd>] -- help on syntax of sql commands, * for all commands\n"); + fprintf(fout, " \\H -- toggle html3 output (currently %s)\n", on(ps->opt.html3)); + fprintf(fout, " \\i <fname> -- read and execute queries from filename\n"); + fprintf(fout, " \\l -- list all databases\n"); + fprintf(fout, " \\m -- toggle monitor-like table display (currently %s)\n", on(ps->opt.standard)); + fprintf(fout, " \\o [<fname>] [|<cmd>] -- send all query results to stdout, <fname>, or pipe\n"); + fprintf(fout, " \\p -- print the current query buffer\n"); + fprintf(fout, " \\q -- quit\n"); + fprintf(fout, " \\r -- reset(clear) the query buffer\n"); + fprintf(fout, " \\s [<fname>] -- print history or save it in <fname>\n"); + fprintf(fout, " \\t -- toggle table headings and row count (currently %s)\n", on(ps->opt.header)); + fprintf(fout, " \\T [<html>] -- set html3.0 <table ...> options (currently '%s')\n", ps->opt.tableOpt ? ps->opt.tableOpt : ""); + fprintf(fout, " \\x -- toggle expanded output (currently %s)\n", on(ps->opt.expanded)); + fprintf(fout, " \\z -- list current grant/revoke permissions\n"); + fprintf(fout, " \\! [<cmd>] -- shell escape or command\n"); + + if (usePipe) + { + pclose(fout); + pqsignal(SIGPIPE, SIG_DFL); + } } static PGresult * PSQLexec(PsqlSettings * ps, char *query) { - PGresult *res; - res = PQexec(ps->db, query); - if (!res) - fputs(PQerrorMessage(ps->db), stderr); - else { - if (PQresultStatus(res) == PGRES_COMMAND_OK || - PQresultStatus(res) == PGRES_TUPLES_OK) - return res; - if (!ps->quiet) - fputs(PQerrorMessage(ps->db), stderr); - PQclear(res); - } - return NULL; + PGresult *res; + + res = PQexec(ps->db, query); + if (!res) + fputs(PQerrorMessage(ps->db), stderr); + else + { + if (PQresultStatus(res) == PGRES_COMMAND_OK || + PQresultStatus(res) == PGRES_TUPLES_OK) + return res; + if (!ps->quiet) + fputs(PQerrorMessage(ps->db), stderr); + PQclear(res); + } + return NULL; } + /* * listAllDbs - * + * * list all the databases in the system returns 0 if all went well - * - * + * + * */ static int listAllDbs(PsqlSettings * ps) { - PGresult *results; - char *query = "select * from pg_database;"; - - if (!(results = PSQLexec(ps, query))) - return 1; - else { - PQprint(ps->queryFout, - results, - &ps->opt); - PQclear(results); - return 0; - } + PGresult *results; + char *query = "select * from pg_database;"; + + if (!(results = PSQLexec(ps, query))) + return 1; + else + { + PQprint(ps->queryFout, + results, + &ps->opt); + PQclear(results); + return 0; + } } /* * List The Database Tables returns 0 if all went well - * + * */ int tableList(PsqlSettings * ps, bool deep_tablelist, char info_type) { - char listbuf[256]; - int nColumns; - int i; - char *rk; - char *rr; - - PGresult *res; - - listbuf[0] = '\0'; - strcat(listbuf, "SELECT usename, relname, relkind, relhasrules"); - strcat(listbuf, " FROM pg_class, pg_user "); - switch (info_type) { - case 't': strcat(listbuf, "WHERE ( relkind = 'r') "); - break; - case 'i': strcat(listbuf, "WHERE ( relkind = 'i') "); - break; - case 'S': strcat(listbuf, "WHERE ( relkind = 'S') "); - break; - case 'b': - default: strcat(listbuf, "WHERE ( relkind = 'r' OR relkind = 'i' OR relkind = 'S') "); - break; - } + char listbuf[256]; + int nColumns; + int i; + char *rk; + char *rr; + + PGresult *res; + + listbuf[0] = '\0'; + strcat(listbuf, "SELECT usename, relname, relkind, relhasrules"); + strcat(listbuf, " FROM pg_class, pg_user "); + switch (info_type) + { + case 't': + strcat(listbuf, "WHERE ( relkind = 'r') "); + break; + case 'i': + strcat(listbuf, "WHERE ( relkind = 'i') "); + break; + case 'S': + strcat(listbuf, "WHERE ( relkind = 'S') "); + break; + case 'b': + default: + strcat(listbuf, "WHERE ( relkind = 'r' OR relkind = 'i' OR relkind = 'S') "); + break; + } strcat(listbuf, " and relname !~ '^pg_'"); strcat(listbuf, " and relname !~ '^xin[vx][0-9]+'"); - /* - * the usesysid = relowner won't work on stock 1.0 dbs, need to add in - * the int4oideq function - */ - strcat(listbuf, " and usesysid = relowner"); - strcat(listbuf, " ORDER BY relname "); - if (!(res = PSQLexec(ps, listbuf))) - return -1; - /* first, print out the attribute names */ - nColumns = PQntuples(res); - if (nColumns > 0) { - if (deep_tablelist) { - /* describe everything here */ - char **table; - table = (char **) malloc(nColumns * sizeof(char *)); - if (table == NULL) - perror("malloc"); - /* load table table */ - for (i = 0; i < nColumns; i++) { - table[i] = (char *) malloc(PQgetlength(res, i, 1) * sizeof(char) + 1); - if (table[i] == NULL) - perror("malloc"); - strcpy(table[i], PQgetvalue(res, i, 1)); - } - - PQclear(res); /* PURIFY */ - for (i = 0; i < nColumns; i++) { - tableDesc(ps, table[i]); - } - free(table); - } else { - /* Display the information */ - - printf("\nDatabase = %s\n", PQdb(ps->db)); - printf(" +------------------+----------------------------------+----------+\n"); - printf(" | Owner | Relation | Type |\n"); - printf(" +------------------+----------------------------------+----------+\n"); - - /* next, print out the instances */ - for (i = 0; i < PQntuples(res); i++) { - printf(" | %-16.16s", PQgetvalue(res, i, 0)); - printf(" | %-32.32s | ", PQgetvalue(res, i, 1)); - rk = PQgetvalue(res, i, 2); - rr = PQgetvalue(res, i, 3); - if (strcmp(rk, "r") == 0) - printf("%-8.8s |", (rr[0] == 't') ? "view?" : "table"); + /* + * the usesysid = relowner won't work on stock 1.0 dbs, need to add in + * the int4oideq function + */ + strcat(listbuf, " and usesysid = relowner"); + strcat(listbuf, " ORDER BY relname "); + if (!(res = PSQLexec(ps, listbuf))) + return -1; + /* first, print out the attribute names */ + nColumns = PQntuples(res); + if (nColumns > 0) + { + if (deep_tablelist) + { + /* describe everything here */ + char **table; + + table = (char **) malloc(nColumns * sizeof(char *)); + if (table == NULL) + perror("malloc"); + + /* load table table */ + for (i = 0; i < nColumns; i++) + { + table[i] = (char *) malloc(PQgetlength(res, i, 1) * sizeof(char) + 1); + if (table[i] == NULL) + perror("malloc"); + strcpy(table[i], PQgetvalue(res, i, 1)); + } + + PQclear(res); /* PURIFY */ + for (i = 0; i < nColumns; i++) + { + tableDesc(ps, table[i]); + } + free(table); + } else - if (strcmp(rk, "i") == 0) - printf("%-8.8s |", "index"); - else - printf("%-8.8s |", "sequence"); - printf("\n"); - } - printf(" +------------------+----------------------------------+----------+\n"); - PQclear(res); + { + /* Display the information */ + + printf("\nDatabase = %s\n", PQdb(ps->db)); + printf(" +------------------+----------------------------------+----------+\n"); + printf(" | Owner | Relation | Type |\n"); + printf(" +------------------+----------------------------------+----------+\n"); + + /* next, print out the instances */ + for (i = 0; i < PQntuples(res); i++) + { + printf(" | %-16.16s", PQgetvalue(res, i, 0)); + printf(" | %-32.32s | ", PQgetvalue(res, i, 1)); + rk = PQgetvalue(res, i, 2); + rr = PQgetvalue(res, i, 3); + if (strcmp(rk, "r") == 0) + printf("%-8.8s |", (rr[0] == 't') ? "view?" : "table"); + else if (strcmp(rk, "i") == 0) + printf("%-8.8s |", "index"); + else + printf("%-8.8s |", "sequence"); + printf("\n"); + } + printf(" +------------------+----------------------------------+----------+\n"); + PQclear(res); + } + return (0); + + } + else + { + PQclear(res); /* PURIFY */ + switch (info_type) + { + case 't': + fprintf(stderr, "Couldn't find any tables!\n"); + break; + case 'i': + fprintf(stderr, "Couldn't find any indices!\n"); + break; + case 'S': + fprintf(stderr, "Couldn't find any sequences!\n"); + break; + case 'b': + default: + fprintf(stderr, "Couldn't find any tables, sequences or indices!\n"); + break; + } + return (-1); } - return (0); - - } else { - PQclear(res); /* PURIFY */ - switch (info_type) { - case 't': fprintf(stderr, "Couldn't find any tables!\n"); - break; - case 'i': fprintf(stderr, "Couldn't find any indices!\n"); - break; - case 'S': fprintf(stderr, "Couldn't find any sequences!\n"); - break; - case 'b': - default: fprintf(stderr, "Couldn't find any tables, sequences or indices!\n"); - break; - } - return (-1); - } } /* * List Tables Grant/Revoke Permissions returns 0 if all went well - * + * */ int rightsList(PsqlSettings * ps) { - char listbuf[256]; - int nColumns; - int i; - - PGresult *res; - - listbuf[0] = '\0'; - strcat(listbuf, "SELECT relname, relacl"); - strcat(listbuf, " FROM pg_class, pg_user "); - strcat(listbuf, "WHERE ( relkind = 'r' OR relkind = 'i') "); - strcat(listbuf, " and relname !~ '^pg_'"); - strcat(listbuf, " and relname !~ '^xin[vx][0-9]+'"); - strcat(listbuf, " and usesysid = relowner"); - strcat(listbuf, " ORDER BY relname "); - if (!(res = PSQLexec(ps, listbuf))) - return -1; - - nColumns = PQntuples(res); - if(nColumns > 0) { - /* Display the information */ - - printf("\nDatabase = %s\n", PQdb(ps->db)); - printf(" +------------------+----------------------------------------------------+\n"); - printf(" | Relation | Grant/Revoke Permissions |\n"); - printf(" +------------------+----------------------------------------------------+\n"); - - /* next, print out the instances */ - for (i = 0; i < PQntuples(res); i++) { - printf(" | %-16.16s", PQgetvalue(res, i, 0)); - printf(" | %-50.50s | ", PQgetvalue(res, i, 1)); - printf("\n"); - } - printf(" +------------------+----------------------------------------------------+\n"); - PQclear(res); - return (0); - } else { - fprintf(stderr, "Couldn't find any tables!\n"); - return (-1); - } + char listbuf[256]; + int nColumns; + int i; + + PGresult *res; + + listbuf[0] = '\0'; + strcat(listbuf, "SELECT relname, relacl"); + strcat(listbuf, " FROM pg_class, pg_user "); + strcat(listbuf, "WHERE ( relkind = 'r' OR relkind = 'i') "); + strcat(listbuf, " and relname !~ '^pg_'"); + strcat(listbuf, " and relname !~ '^xin[vx][0-9]+'"); + strcat(listbuf, " and usesysid = relowner"); + strcat(listbuf, " ORDER BY relname "); + if (!(res = PSQLexec(ps, listbuf))) + return -1; + + nColumns = PQntuples(res); + if (nColumns > 0) + { + /* Display the information */ + + printf("\nDatabase = %s\n", PQdb(ps->db)); + printf(" +------------------+----------------------------------------------------+\n"); + printf(" | Relation | Grant/Revoke Permissions |\n"); + printf(" +------------------+----------------------------------------------------+\n"); + + /* next, print out the instances */ + for (i = 0; i < PQntuples(res); i++) + { + printf(" | %-16.16s", PQgetvalue(res, i, 0)); + printf(" | %-50.50s | ", PQgetvalue(res, i, 1)); + printf("\n"); + } + printf(" +------------------+----------------------------------------------------+\n"); + PQclear(res); + return (0); + } + else + { + fprintf(stderr, "Couldn't find any tables!\n"); + return (-1); + } } + /* * Describe a table - * + * * Describe the columns in a database table. returns 0 if all went well - * - * + * + * */ int tableDesc(PsqlSettings * ps, char *table) { - char descbuf[256]; - int nColumns; - char *rtype; - int i; - int rsize; - - PGresult *res; - - /* Build the query */ - - for(i = strlen(table); i >= 0; i--) - if (isupper(table[i])) - table[i] = tolower(table[i]); - - descbuf[0] = '\0'; - strcat(descbuf, "SELECT a.attnum, a.attname, t.typname, a.attlen, a.attnotnull"); - strcat(descbuf, " FROM pg_class c, pg_attribute a, pg_type t "); - strcat(descbuf, " WHERE c.relname = '"); - strcat(descbuf, table); - strcat(descbuf, "'"); - strcat(descbuf, " and a.attnum > 0 "); - strcat(descbuf, " and a.attrelid = c.oid "); - strcat(descbuf, " and a.atttypid = t.oid "); - strcat(descbuf, " ORDER BY attnum "); - if (!(res = PSQLexec(ps, descbuf))) - return -1; - /* first, print out the attribute names */ - nColumns = PQntuples(res); - if (nColumns > 0) { - /* - * * Display the information - */ + char descbuf[256]; + int nColumns; + char *rtype; + int i; + int rsize; + + PGresult *res; + + /* Build the query */ + + for (i = strlen(table); i >= 0; i--) + if (isupper(table[i])) + table[i] = tolower(table[i]); + + descbuf[0] = '\0'; + strcat(descbuf, "SELECT a.attnum, a.attname, t.typname, a.attlen, a.attnotnull"); + strcat(descbuf, " FROM pg_class c, pg_attribute a, pg_type t "); + strcat(descbuf, " WHERE c.relname = '"); + strcat(descbuf, table); + strcat(descbuf, "'"); + strcat(descbuf, " and a.attnum > 0 "); + strcat(descbuf, " and a.attrelid = c.oid "); + strcat(descbuf, " and a.atttypid = t.oid "); + strcat(descbuf, " ORDER BY attnum "); + if (!(res = PSQLexec(ps, descbuf))) + return -1; + /* first, print out the attribute names */ + nColumns = PQntuples(res); + if (nColumns > 0) + { - printf("\nTable = %s\n", table); - printf("+----------------------------------+----------------------------------+-------+\n"); - printf("| Field | Type | Length|\n"); - printf("+----------------------------------+----------------------------------+-------+\n"); - - /* next, print out the instances */ - for (i = 0; i < PQntuples(res); i++) { - printf("| %-32.32s | ", PQgetvalue(res, i, 1)); - rtype = PQgetvalue(res, i, 2); - rsize = atoi(PQgetvalue(res, i, 3)); - if (strcmp(rtype, "text") == 0) { - printf("%-32.32s |", rtype); - printf("%6s |", "var"); - } else if (strcmp(rtype, "bpchar") == 0) { - printf("%-32.32s |", "(bp)char"); - printf("%6i |", rsize > 0 ? rsize - 4 : 0); - } else if (strcmp(rtype, "varchar") == 0) { - printf("%-32.32s |", rtype); - printf("%6i |", rsize > 0 ? rsize - 4 : 0); - } else { - /* array types start with an underscore */ - if (rtype[0] != '_') - printf("%-32.32s |", rtype); - else { - char *newname; - newname = malloc(strlen(rtype) + 2); - strcpy(newname, rtype + 1); - strcat(newname, "[]"); - printf("%-32.32s |", newname); - free(newname); - } - if (rsize > 0) - printf("%6i |", rsize); - else - printf("%6s |", "var"); - } - printf("\n"); - } - printf("+----------------------------------+----------------------------------+-------+\n"); + /* + * * Display the information + */ + + printf("\nTable = %s\n", table); + printf("+----------------------------------+----------------------------------+-------+\n"); + printf("| Field | Type | Length|\n"); + printf("+----------------------------------+----------------------------------+-------+\n"); + + /* next, print out the instances */ + for (i = 0; i < PQntuples(res); i++) + { + printf("| %-32.32s | ", PQgetvalue(res, i, 1)); + rtype = PQgetvalue(res, i, 2); + rsize = atoi(PQgetvalue(res, i, 3)); + if (strcmp(rtype, "text") == 0) + { + printf("%-32.32s |", rtype); + printf("%6s |", "var"); + } + else if (strcmp(rtype, "bpchar") == 0) + { + printf("%-32.32s |", "(bp)char"); + printf("%6i |", rsize > 0 ? rsize - 4 : 0); + } + else if (strcmp(rtype, "varchar") == 0) + { + printf("%-32.32s |", rtype); + printf("%6i |", rsize > 0 ? rsize - 4 : 0); + } + else + { + /* array types start with an underscore */ + if (rtype[0] != '_') + printf("%-32.32s |", rtype); + else + { + char *newname; + + newname = malloc(strlen(rtype) + 2); + strcpy(newname, rtype + 1); + strcat(newname, "[]"); + printf("%-32.32s |", newname); + free(newname); + } + if (rsize > 0) + printf("%6i |", rsize); + else + printf("%6s |", "var"); + } + printf("\n"); + } + printf("+----------------------------------+----------------------------------+-------+\n"); - PQclear(res); - return (0); + PQclear(res); + return (0); - } else { - fprintf(stderr, "Couldn't find table %s!\n", table); - return (-1); - } + } + else + { + fprintf(stderr, "Couldn't find table %s!\n", table); + return (-1); + } } typedef char *(*READ_ROUTINE) (char *prompt, FILE * source); /* - * gets_noreadline prompt source gets a line of input without calling + * gets_noreadline prompt source gets a line of input without calling * readline, the source is ignored */ -static char * +static char * gets_noreadline(char *prompt, FILE * source) { - fputs(prompt, stdout); - fflush(stdout); - return (gets_fromFile(prompt, stdin)); + fputs(prompt, stdout); + fflush(stdout); + return (gets_fromFile(prompt, stdin)); } /* * gets_readline prompt source the routine to get input from GNU readline(), * the source is ignored the prompt argument is used as the prompting string */ -static char * +static char * gets_readline(char *prompt, FILE * source) { - char *s; + char *s; + #ifdef HAVE_LIBREADLINE - s = readline(prompt); + s = readline(prompt); #else - char buf[500]; - printf("%s", prompt); - s = fgets(buf, 500, stdin); + char buf[500]; + + printf("%s", prompt); + s = fgets(buf, 500, stdin); #endif - fputc('\r', stdout); - fflush(stdout); - return s; + fputc('\r', stdout); + fflush(stdout); + return s; } /* * gets_fromFile prompt source - * + * * the routine to read from a file, the prompt argument is ignored the source * argument is a FILE * */ -static char * +static char * gets_fromFile(char *prompt, FILE * source) { - char *line; - int len; + char *line; + int len; - line = malloc(MAX_QUERY_BUFFER + 1); + line = malloc(MAX_QUERY_BUFFER + 1); - /* read up to MAX_QUERY_BUFFER characters */ - if (fgets(line, MAX_QUERY_BUFFER, source) == NULL) + /* read up to MAX_QUERY_BUFFER characters */ + if (fgets(line, MAX_QUERY_BUFFER, source) == NULL) { - free(line); - return NULL; + free(line); + return NULL; } - line[MAX_QUERY_BUFFER - 1] = '\0'; - len = strlen(line); - if (len == MAX_QUERY_BUFFER) { - fprintf(stderr, "line read exceeds maximum length. Truncating at %d\n", - MAX_QUERY_BUFFER); - } - return line; + line[MAX_QUERY_BUFFER - 1] = '\0'; + len = strlen(line); + if (len == MAX_QUERY_BUFFER) + { + fprintf(stderr, "line read exceeds maximum length. Truncating at %d\n", + MAX_QUERY_BUFFER); + } + return line; } /* @@ -581,113 +631,131 @@ gets_fromFile(char *prompt, FILE * source) */ static void SendQuery(bool * success_p, PsqlSettings * settings, const char *query, - const bool copy_in, const bool copy_out, FILE * copystream) + const bool copy_in, const bool copy_out, FILE * copystream) { - PGresult *results; - PGnotify *notify; + PGresult *results; + PGnotify *notify; - if (settings->singleStep) - fprintf(stdout, "\n**************************************" - "*****************************************\n"); + if (settings->singleStep) + fprintf(stdout, "\n**************************************" + "*****************************************\n"); - if (settings->echoQuery || settings->singleStep) { - fprintf(stderr, "QUERY: %s\n", query); - fflush(stderr); - } - if (settings->singleStep) { - fprintf(stdout, "\n**************************************" - "*****************************************\n"); - fflush(stdout); - printf("\npress return to continue ..\n"); - gets_fromFile("", stdin); - } - results = PQexec(settings->db, query); - if (results == NULL) { - fprintf(stderr, "%s", PQerrorMessage(settings->db)); - *success_p = false; - } else { - switch (PQresultStatus(results)) { - case PGRES_TUPLES_OK: - if (settings->gfname) { - PsqlSettings ps = *settings; - FILE *fp; - ps.queryFout = stdout; - fp = setFout(&ps, settings->gfname); - if (!fp || fp == stdout) { - *success_p = false; - break; - } else - *success_p = true; - PQprint(fp, - results, - &(settings->opt)); - if (ps.pipe) - pclose(fp); - else - fclose(fp); - free(settings->gfname); - settings->gfname = NULL; - break; - } else { - *success_p = true; - PQprint(settings->queryFout, - results, - &(settings->opt)); - fflush(settings->queryFout); - } - break; - case PGRES_EMPTY_QUERY: - *success_p = true; - break; - case PGRES_COMMAND_OK: - *success_p = true; - if (!settings->quiet) - printf("%s\n", PQcmdStatus(results)); - break; - case PGRES_COPY_OUT: - *success_p = true; - if (copy_out) { - handleCopyOut(results, settings->quiet, copystream); - } else { - if (!settings->quiet) - printf("Copy command returns...\n"); - - handleCopyOut(results, settings->quiet, stdout); - } - break; - case PGRES_COPY_IN: - *success_p = true; - if (copy_in) - handleCopyIn(results, false, copystream); - else - handleCopyIn(results, !settings->quiet, stdin); - break; - case PGRES_NONFATAL_ERROR: - case PGRES_FATAL_ERROR: - case PGRES_BAD_RESPONSE: - *success_p = false; - fprintf(stderr, "%s", PQerrorMessage(settings->db)); - break; + if (settings->echoQuery || settings->singleStep) + { + fprintf(stderr, "QUERY: %s\n", query); + fflush(stderr); } - - if (PQstatus(settings->db) == CONNECTION_BAD) { - fprintf(stderr, - "We have lost the connection to the backend, so " - "further processing is impossible. " - "Terminating.\n"); - exit(2); /* we are out'ta here */ + if (settings->singleStep) + { + fprintf(stdout, "\n**************************************" + "*****************************************\n"); + fflush(stdout); + printf("\npress return to continue ..\n"); + gets_fromFile("", stdin); } - /* check for asynchronous returns */ - notify = PQnotifies(settings->db); - if (notify) { - fprintf(stderr, - "ASYNC NOTIFY of '%s' from backend pid '%d' received\n", - notify->relname, notify->be_pid); - free(notify); + results = PQexec(settings->db, query); + if (results == NULL) + { + fprintf(stderr, "%s", PQerrorMessage(settings->db)); + *success_p = false; + } + else + { + switch (PQresultStatus(results)) + { + case PGRES_TUPLES_OK: + if (settings->gfname) + { + PsqlSettings ps = *settings; + FILE *fp; + + ps.queryFout = stdout; + fp = setFout(&ps, settings->gfname); + if (!fp || fp == stdout) + { + *success_p = false; + break; + } + else + *success_p = true; + PQprint(fp, + results, + &(settings->opt)); + if (ps.pipe) + pclose(fp); + else + fclose(fp); + free(settings->gfname); + settings->gfname = NULL; + break; + } + else + { + *success_p = true; + PQprint(settings->queryFout, + results, + &(settings->opt)); + fflush(settings->queryFout); + } + break; + case PGRES_EMPTY_QUERY: + *success_p = true; + break; + case PGRES_COMMAND_OK: + *success_p = true; + if (!settings->quiet) + printf("%s\n", PQcmdStatus(results)); + break; + case PGRES_COPY_OUT: + *success_p = true; + if (copy_out) + { + handleCopyOut(results, settings->quiet, copystream); + } + else + { + if (!settings->quiet) + printf("Copy command returns...\n"); + + handleCopyOut(results, settings->quiet, stdout); + } + break; + case PGRES_COPY_IN: + *success_p = true; + if (copy_in) + handleCopyIn(results, false, copystream); + else + handleCopyIn(results, !settings->quiet, stdin); + break; + case PGRES_NONFATAL_ERROR: + case PGRES_FATAL_ERROR: + case PGRES_BAD_RESPONSE: + *success_p = false; + fprintf(stderr, "%s", PQerrorMessage(settings->db)); + break; + } + + if (PQstatus(settings->db) == CONNECTION_BAD) + { + fprintf(stderr, + "We have lost the connection to the backend, so " + "further processing is impossible. " + "Terminating.\n"); + exit(2); /* we are out'ta here */ + } + /* check for asynchronous returns */ + notify = PQnotifies(settings->db); + if (notify) + { + fprintf(stderr, + "ASYNC NOTIFY of '%s' from backend pid '%d' received\n", + notify->relname, notify->be_pid); + free(notify); + } + if (results) + PQclear(results); } - if(results) PQclear(results); - } } @@ -695,28 +763,30 @@ SendQuery(bool * success_p, PsqlSettings * settings, const char *query, static void editFile(char *fname) { - char *editorName; - char *sys; - editorName = getenv("EDITOR"); - if (!editorName) - editorName = DEFAULT_EDITOR; - sys = malloc(strlen(editorName) + strlen(fname) + 32 + 1); - if (!sys) { - perror("malloc"); - exit(1); - } - sprintf(sys, "exec '%s' '%s'", editorName, fname); - system(sys); - free(sys); + char *editorName; + char *sys; + + editorName = getenv("EDITOR"); + if (!editorName) + editorName = DEFAULT_EDITOR; + sys = malloc(strlen(editorName) + strlen(fname) + 32 + 1); + if (!sys) + { + perror("malloc"); + exit(1); + } + sprintf(sys, "exec '%s' '%s'", editorName, fname); + system(sys); + free(sys); } -static bool +static bool toggle(PsqlSettings * settings, bool * sw, char *msg) { - *sw = !*sw; - if (!settings->quiet) - printf("turned %s %s\n", on(*sw), msg); - return *sw; + *sw = !*sw; + if (!settings->quiet) + printf("turned %s %s\n", on(*sw), msg); + return *sw; } @@ -724,117 +794,138 @@ toggle(PsqlSettings * settings, bool * sw, char *msg) static void unescape(char *dest, const char *source) { - /*----------------------------------------------------------------------------- - Return as the string <dest> the value of string <source> with escape - sequences turned into the bytes they represent. - -----------------------------------------------------------------------------*/ - char *p; - bool esc; /* Last character we saw was the escape - * character (/) */ - - esc = false; /* Haven't seen escape character yet */ - for (p = (char *) source; *p; p++) { - char c; /* Our output character */ - - if (esc) { - switch (*p) { - case 'n': - c = '\n'; - break; - case 'r': - c = '\r'; - break; - case 't': - c = '\t'; - break; - case 'f': - c = '\f'; - break; - case '\\': - c = '\\'; - break; - default: - c = *p; - } - esc = false; - } else if (*p == '\\') { - esc = true; - c = ' '; /* meaningless, but compiler doesn't know - * that */ - } else { - c = *p; - esc = false; + /*----------------------------------------------------------------------------- + Return as the string <dest> the value of string <source> with escape + sequences turned into the bytes they represent. + -----------------------------------------------------------------------------*/ + char *p; + bool esc; /* Last character we saw was the escape + * character (/) */ + + esc = false; /* Haven't seen escape character yet */ + for (p = (char *) source; *p; p++) + { + char c; /* Our output character */ + + if (esc) + { + switch (*p) + { + case 'n': + c = '\n'; + break; + case 'r': + c = '\r'; + break; + case 't': + c = '\t'; + break; + case 'f': + c = '\f'; + break; + case '\\': + c = '\\'; + break; + default: + c = *p; + } + esc = false; + } + else if (*p == '\\') + { + esc = true; + c = ' '; /* meaningless, but compiler doesn't know + * that */ + } + else + { + c = *p; + esc = false; + } + if (!esc) + *dest++ = c; } - if (!esc) - *dest++ = c; - } - *dest = '\0'; /* Terminating null character */ + *dest = '\0'; /* Terminating null character */ } static void parse_slash_copy(const char *args, char *table, const int table_len, - char *file, const int file_len, - bool * from_p, bool * error_p) + char *file, const int file_len, + bool * from_p, bool * error_p) { - char work_args[200]; - /* - * A copy of the \copy command arguments, except that we modify it as we - * parse to suit our parsing needs. - */ - char *table_tok, *fromto_tok; - - strncpy(work_args, args, sizeof(work_args)); - work_args[sizeof(work_args) - 1] = '\0'; - - *error_p = false; /* initial assumption */ - - table_tok = strtok(work_args, " "); - if (table_tok == NULL) { - fprintf(stderr, "\\copy needs arguments.\n"); - *error_p = true; - } else { - strncpy(table, table_tok, table_len); - file[table_len - 1] = '\0'; - - fromto_tok = strtok(NULL, " "); - if (fromto_tok == NULL) { - fprintf(stderr, "'FROM' or 'TO' must follow table name.\n"); - *error_p = true; - } else { - if (strcasecmp(fromto_tok, "from") == 0) - *from_p = true; - else if (strcasecmp(fromto_tok, "to") == 0) - *from_p = false; - else { - fprintf(stderr, - "Unrecognized token found where " - "'FROM' or 'TO' expected: '%s'.\n", - fromto_tok); + char work_args[200]; + + /* + * A copy of the \copy command arguments, except that we modify it as + * we parse to suit our parsing needs. + */ + char *table_tok, + *fromto_tok; + + strncpy(work_args, args, sizeof(work_args)); + work_args[sizeof(work_args) - 1] = '\0'; + + *error_p = false; /* initial assumption */ + + table_tok = strtok(work_args, " "); + if (table_tok == NULL) + { + fprintf(stderr, "\\copy needs arguments.\n"); *error_p = true; - } - if (!*error_p) { - char *file_tok; - - file_tok = strtok(NULL, " "); - if (file_tok == NULL) { - fprintf(stderr, "A file pathname must follow '%s'.\n", - fromto_tok); - *error_p = true; - } else { - strncpy(file, file_tok, file_len); - file[file_len - 1] = '\0'; - if (strtok(NULL, " ") != NULL) { - fprintf(stderr, - "You have extra tokens after the filename.\n"); + } + else + { + strncpy(table, table_tok, table_len); + file[table_len - 1] = '\0'; + + fromto_tok = strtok(NULL, " "); + if (fromto_tok == NULL) + { + fprintf(stderr, "'FROM' or 'TO' must follow table name.\n"); *error_p = true; - } } - } + else + { + if (strcasecmp(fromto_tok, "from") == 0) + *from_p = true; + else if (strcasecmp(fromto_tok, "to") == 0) + *from_p = false; + else + { + fprintf(stderr, + "Unrecognized token found where " + "'FROM' or 'TO' expected: '%s'.\n", + fromto_tok); + *error_p = true; + } + if (!*error_p) + { + char *file_tok; + + file_tok = strtok(NULL, " "); + if (file_tok == NULL) + { + fprintf(stderr, "A file pathname must follow '%s'.\n", + fromto_tok); + *error_p = true; + } + else + { + strncpy(file, file_tok, file_len); + file[file_len - 1] = '\0'; + if (strtok(NULL, " ") != NULL) + { + fprintf(stderr, + "You have extra tokens after the filename.\n"); + *error_p = true; + } + } + } + } } - } } @@ -842,120 +933,140 @@ parse_slash_copy(const char *args, char *table, const int table_len, static void do_copy(const char *args, PsqlSettings * settings) { - /*--------------------------------------------------------------------------- - Execute a \copy command (frontend copy). We have to open a file, then - submit a COPY query to the backend and either feed it data from the - file or route its response into the file. - - We do a text copy with default (tab) column delimiters. Some day, we - should do all the things a backend copy can do. - - ----------------------------------------------------------------------------*/ - char query[200]; - /* The COPY command we send to the back end */ - bool from; - /* The direction of the copy is from a file to a table. */ - char file[MAXPATHLEN + 1]; - /* The pathname of the file from/to which we copy */ - char table[NAMEDATALEN]; - /* The name of the table from/to which we copy */ - bool syntax_error; - /* The \c command has invalid syntax */ - FILE *copystream; - - parse_slash_copy(args, table, sizeof(table), file, sizeof(file), - &from, &syntax_error); - - if (!syntax_error) { - strcpy(query, "COPY "); - strcat(query, table); - - if (from) - strcat(query, " FROM stdin"); - else - strcat(query, " TO stdout"); + /*--------------------------------------------------------------------------- + Execute a \copy command (frontend copy). We have to open a file, then + submit a COPY query to the backend and either feed it data from the + file or route its response into the file. - if (from) { - copystream = fopen(file, "r"); - } else { - copystream = fopen(file, "w"); - } - if (copystream == NULL) - fprintf(stderr, - "Unable to open file %s which to copy, errno = %s (%d).", - from ? "from" : "to", strerror(errno), errno); - else { - bool success; /* The query succeeded at the backend */ - - SendQuery(&success, settings, query, from, !from, copystream); - fclose(copystream); - if (!settings->quiet) { - if (success) - printf("Successfully copied.\n"); + We do a text copy with default (tab) column delimiters. Some day, we + should do all the things a backend copy can do. + + ----------------------------------------------------------------------------*/ + char query[200]; + + /* The COPY command we send to the back end */ + bool from; + + /* The direction of the copy is from a file to a table. */ + char file[MAXPATHLEN + 1]; + + /* The pathname of the file from/to which we copy */ + char table[NAMEDATALEN]; + + /* The name of the table from/to which we copy */ + bool syntax_error; + + /* The \c command has invalid syntax */ + FILE *copystream; + + parse_slash_copy(args, table, sizeof(table), file, sizeof(file), + &from, &syntax_error); + + if (!syntax_error) + { + strcpy(query, "COPY "); + strcat(query, table); + + if (from) + strcat(query, " FROM stdin"); + else + strcat(query, " TO stdout"); + + if (from) + { + copystream = fopen(file, "r"); + } else - printf("Copy failed.\n"); - } + { + copystream = fopen(file, "w"); + } + if (copystream == NULL) + fprintf(stderr, + "Unable to open file %s which to copy, errno = %s (%d).", + from ? "from" : "to", strerror(errno), errno); + else + { + bool success; /* The query succeeded at the + * backend */ + + SendQuery(&success, settings, query, from, !from, copystream); + fclose(copystream); + if (!settings->quiet) + { + if (success) + printf("Successfully copied.\n"); + else + printf("Copy failed.\n"); + } + } } - } } static void do_connect(const char *new_dbname, - const char *new_user, - PsqlSettings *settings) + const char *new_user, + PsqlSettings * settings) { - if (!new_dbname) - fprintf(stderr, "\\connect must be followed by a database name\n"); - else { - PGconn *olddb = settings->db; - static char *userenv = NULL; - char *old_userenv = NULL; - const char *dbparam; - - if (new_user != NULL) { - /* - PQsetdb() does not allow us to specify the user, - so we have to do it via PGUSER - */ - if (userenv != NULL) - old_userenv = userenv; - userenv = malloc(strlen("PGUSER=") + strlen(new_user) + 1); - sprintf(userenv,"PGUSER=%s",new_user); - /* putenv() may continue to use memory as part of environment */ - putenv(userenv); - /* can delete old memory if we malloc'ed it */ - if (old_userenv != NULL) - free(old_userenv); - } + if (!new_dbname) + fprintf(stderr, "\\connect must be followed by a database name\n"); + else + { + PGconn *olddb = settings->db; + static char *userenv = NULL; + char *old_userenv = NULL; + const char *dbparam; + + if (new_user != NULL) + { + + /* + * PQsetdb() does not allow us to specify the user, so we have + * to do it via PGUSER + */ + if (userenv != NULL) + old_userenv = userenv; + userenv = malloc(strlen("PGUSER=") + strlen(new_user) + 1); + sprintf(userenv, "PGUSER=%s", new_user); + /* putenv() may continue to use memory as part of environment */ + putenv(userenv); + /* can delete old memory if we malloc'ed it */ + if (old_userenv != NULL) + free(old_userenv); + } - if (strcmp(new_dbname,"-") != 0) - dbparam = new_dbname; - else dbparam = PQdb(olddb); - - settings->db = PQsetdb(PQhost(olddb), PQport(olddb), - NULL, NULL, dbparam); - if (!settings->quiet) { - if (!new_user) - printf("connecting to new database: %s\n", dbparam); - else if (dbparam != new_dbname) - printf("connecting as new user: %s\n", new_user); - else - printf("connecting to new database: %s as user: %s\n", - dbparam,new_user); - } + if (strcmp(new_dbname, "-") != 0) + dbparam = new_dbname; + else + dbparam = PQdb(olddb); - if (PQstatus(settings->db) == CONNECTION_BAD) { - fprintf(stderr, "%s\n", PQerrorMessage(settings->db)); - fprintf(stderr,"Could not connect to new database. exiting\n"); - exit(2); - } else { - PQfinish(olddb); - free(settings->prompt); - settings->prompt = malloc(strlen(PQdb(settings->db)) + 10); - sprintf(settings->prompt, "%s%s", PQdb(settings->db), PROMPT); + settings->db = PQsetdb(PQhost(olddb), PQport(olddb), + NULL, NULL, dbparam); + if (!settings->quiet) + { + if (!new_user) + printf("connecting to new database: %s\n", dbparam); + else if (dbparam != new_dbname) + printf("connecting as new user: %s\n", new_user); + else + printf("connecting to new database: %s as user: %s\n", + dbparam, new_user); + } + + if (PQstatus(settings->db) == CONNECTION_BAD) + { + fprintf(stderr, "%s\n", PQerrorMessage(settings->db)); + fprintf(stderr, "Could not connect to new database. exiting\n"); + exit(2); + } + else + { + PQfinish(olddb); + free(settings->prompt); + settings->prompt = malloc(strlen(PQdb(settings->db)) + 10); + sprintf(settings->prompt, "%s%s", PQdb(settings->db), PROMPT); + } } - } } @@ -963,66 +1074,83 @@ static void do_edit(const char *filename_arg, char *query, int *status_p) { - int fd; - char tmp[64]; - char *fname; - int cc; - const int ql = strlen(query); - bool error; - - if (filename_arg) { - fname = (char *) filename_arg; - error = false; - } else { - sprintf(tmp, "/tmp/psql.%ld.%ld", (long) geteuid(), (long) getpid()); - fname = tmp; - unlink(tmp); - if (ql > 0) { - if ((fd = open(tmp, O_EXCL | O_CREAT | O_WRONLY, 0600)) == -1) { - perror(tmp); - error = true; - } else { - if (query[ql - 1] != '\n') - strcat(query, "\n"); - if (write(fd, query, ql) != ql) { - perror(tmp); - close(fd); - unlink(tmp); - error = true; - } else - error = false; - close(fd); - } - } else - error = false; - } - - if (error) - *status_p = CMD_SKIP_LINE; - else { - editFile(fname); - if ((fd = open(fname, O_RDONLY)) == -1) { - perror(fname); - if (!filename_arg) - unlink(fname); - *status_p = CMD_SKIP_LINE; - } else { - if ((cc = read(fd, query, MAX_QUERY_BUFFER)) == -1) { - perror(fname); - close(fd); - if (!filename_arg) - unlink(fname); + int fd; + char tmp[64]; + char *fname; + int cc; + const int ql = strlen(query); + bool error; + + if (filename_arg) + { + fname = (char *) filename_arg; + error = false; + } + else + { + sprintf(tmp, "/tmp/psql.%ld.%ld", (long) geteuid(), (long) getpid()); + fname = tmp; + unlink(tmp); + if (ql > 0) + { + if ((fd = open(tmp, O_EXCL | O_CREAT | O_WRONLY, 0600)) == -1) + { + perror(tmp); + error = true; + } + else + { + if (query[ql - 1] != '\n') + strcat(query, "\n"); + if (write(fd, query, ql) != ql) + { + perror(tmp); + close(fd); + unlink(tmp); + error = true; + } + else + error = false; + close(fd); + } + } + else + error = false; + } + + if (error) *status_p = CMD_SKIP_LINE; - } else { - query[cc] = '\0'; - close(fd); - if (!filename_arg) - unlink(fname); - rightTrim(query); - *status_p = CMD_NEWEDIT; - } + else + { + editFile(fname); + if ((fd = open(fname, O_RDONLY)) == -1) + { + perror(fname); + if (!filename_arg) + unlink(fname); + *status_p = CMD_SKIP_LINE; + } + else + { + if ((cc = read(fd, query, MAX_QUERY_BUFFER)) == -1) + { + perror(fname); + close(fd); + if (!filename_arg) + unlink(fname); + *status_p = CMD_SKIP_LINE; + } + else + { + query[cc] = '\0'; + close(fd); + if (!filename_arg) + unlink(fname); + rightTrim(query); + *status_p = CMD_NEWEDIT; + } + } } - } } @@ -1031,78 +1159,85 @@ static void do_help(PsqlSettings * ps, const char *topic) { - if (!topic) { - char left_center_right; /* Which column we're - * displaying */ - int i; /* Index into QL_HELP[] */ - - printf("type \\h <cmd> where <cmd> is one of the following:\n"); - - left_center_right = 'L';/* Start with left column */ - i = 0; - while (QL_HELP[i].cmd != NULL) { - switch (left_center_right) { - case 'L': - printf(" %-25s", QL_HELP[i].cmd); - left_center_right = 'C'; - break; - case 'C': - printf("%-25s", QL_HELP[i].cmd); - left_center_right = 'R'; - break; - case 'R': - printf("%-25s\n", QL_HELP[i].cmd); - left_center_right = 'L'; - break; - }; - i++; - } - if (left_center_right != 'L') - puts("\n"); - printf("type \\h * for a complete description of all commands\n"); - } else { - int i; /* Index into QL_HELP[] */ - bool help_found; /* We found the help he asked for */ - - int usePipe = 0; - char *pagerenv; - FILE *fout; - - if (strcmp(topic, "*") == 0 && - (ps->notty == 0) && - (pagerenv = getenv("PAGER")) && - (pagerenv[0] != '\0') && - (fout = popen(pagerenv, "w"))) + if (!topic) { - usePipe = 1; - pqsignal(SIGPIPE, SIG_IGN); + char left_center_right; /* Which column we're + * displaying */ + int i; /* Index into QL_HELP[] */ + + printf("type \\h <cmd> where <cmd> is one of the following:\n"); + + left_center_right = 'L';/* Start with left column */ + i = 0; + while (QL_HELP[i].cmd != NULL) + { + switch (left_center_right) + { + case 'L': + printf(" %-25s", QL_HELP[i].cmd); + left_center_right = 'C'; + break; + case 'C': + printf("%-25s", QL_HELP[i].cmd); + left_center_right = 'R'; + break; + case 'R': + printf("%-25s\n", QL_HELP[i].cmd); + left_center_right = 'L'; + break; + }; + i++; + } + if (left_center_right != 'L') + puts("\n"); + printf("type \\h * for a complete description of all commands\n"); } else - fout = stdout; - - help_found = false; /* Haven't found it yet */ - for (i = 0; QL_HELP[i].cmd; i++) { - if (strcmp(QL_HELP[i].cmd, topic) == 0 || - strcmp(topic, "*") == 0) { - help_found = true; - fprintf(fout, "Command: %s\n", QL_HELP[i].cmd); - fprintf(fout, "Description: %s\n", QL_HELP[i].help); - fprintf(fout, "Syntax:\n"); - fprintf(fout, "%s\n", QL_HELP[i].syntax); - fprintf(fout, "\n"); - } - } - - if (usePipe) { - pclose(fout); - pqsignal(SIGPIPE, SIG_DFL); - } + int i; /* Index into QL_HELP[] */ + bool help_found; /* We found the help he asked for */ + + int usePipe = 0; + char *pagerenv; + FILE *fout; + + if (strcmp(topic, "*") == 0 && + (ps->notty == 0) && + (pagerenv = getenv("PAGER")) && + (pagerenv[0] != '\0') && + (fout = popen(pagerenv, "w"))) + { + usePipe = 1; + pqsignal(SIGPIPE, SIG_IGN); + } + else + fout = stdout; + + help_found = false; /* Haven't found it yet */ + for (i = 0; QL_HELP[i].cmd; i++) + { + if (strcmp(QL_HELP[i].cmd, topic) == 0 || + strcmp(topic, "*") == 0) + { + help_found = true; + fprintf(fout, "Command: %s\n", QL_HELP[i].cmd); + fprintf(fout, "Description: %s\n", QL_HELP[i].help); + fprintf(fout, "Syntax:\n"); + fprintf(fout, "%s\n", QL_HELP[i].syntax); + fprintf(fout, "\n"); + } + } + + if (usePipe) + { + pclose(fout); + pqsignal(SIGPIPE, SIG_DFL); + } - if (!help_found) - fprintf(stderr,"command not found, " - "try \\h with no arguments to see available help\n"); - } + if (!help_found) + fprintf(stderr, "command not found, " + "try \\h with no arguments to see available help\n"); + } } @@ -1111,813 +1246,955 @@ static void do_shell(const char *command) { - if (!command) { - char *sys; - char *shellName; - - shellName = getenv("SHELL"); - if (shellName == NULL) - shellName = DEFAULT_SHELL; - sys = malloc(strlen(shellName) + 16); - if (!sys) { - perror("malloc"); - exit(1); + if (!command) + { + char *sys; + char *shellName; + + shellName = getenv("SHELL"); + if (shellName == NULL) + shellName = DEFAULT_SHELL; + sys = malloc(strlen(shellName) + 16); + if (!sys) + { + perror("malloc"); + exit(1); + } + sprintf(sys, "exec %s", shellName); + system(sys); + free(sys); } - sprintf(sys, "exec %s", shellName); - system(sys); - free(sys); - } else - system(command); + else + system(command); } /* * HandleSlashCmds: - * + * * Handles all the different commands that start with \ db_ptr is a pointer to * the TgDb* structure line is the current input line prompt_ptr is a pointer * to the prompt string, a pointer is used because the prompt can be used * with a connection to a new database. * Returns a status: - * 0 - send currently constructed query to backend (i.e. we got a \g) - * 1 - skip processing of this line, continue building up query - * 2 - terminate processing of this query entirely - * 3 - new query supplied by edit + * 0 - send currently constructed query to backend (i.e. we got a \g) + * 1 - skip processing of this line, continue building up query + * 2 - terminate processing of this query entirely + * 3 - new query supplied by edit */ static int HandleSlashCmds(PsqlSettings * settings, - char *line, - char *query) + char *line, + char *query) { - int status = CMD_SKIP_LINE; - char *optarg; - /* - * Pointer inside the <cmd> string to the argument of the slash command, - * assuming it is a one-character slash command. If it's not a - * one-character command, this is meaningless. - */ - char *optarg2; - /* - * Pointer inside the <cmd> string to the argument of the slash command - * assuming it's not a one-character command. If it's a one-character - * command, this is meaningless. - */ - char *cmd; - /* - * String: value of the slash command, less the slash and with escape - * sequences decoded. - */ - int blank_loc; - /* Offset within <cmd> of first blank */ - - cmd = malloc(strlen(line)); /* unescaping better not make string grow. */ - - unescape(cmd, line + 1); /* sets cmd string */ - - if (strlen(cmd) >= 1 && cmd[strlen(cmd)-1] == ';') /* strip trailing ; */ - cmd[strlen(cmd)-1] = '\0'; - - /* - * Originally, there were just single character commands. Now, we define - * some longer, friendly commands, but we have to keep the old single - * character commands too. \c used to be what \connect is now. - * Complicating matters is the fact that with the single-character - * commands, you can start the argument right after the single character, - * so "\copy" would mean "connect to database named 'opy'". - */ - - if (strlen(cmd) > 1) - optarg = cmd + 1 + strspn(cmd + 1, " \t"); - else - optarg = NULL; - - blank_loc = strcspn(cmd, " \t"); - if (blank_loc == 0 || !cmd[blank_loc]) - optarg2 = NULL; - else - optarg2 = cmd + blank_loc + strspn(cmd + blank_loc, " \t"); - - switch (cmd[0]) { - case 'a': /* toggles to align fields on output */ - toggle(settings, &settings->opt.align, "field alignment"); - break; - case 'C': /* define new caption */ - if (settings->opt.caption) - { - free(settings->opt.caption); - settings->opt.caption = NULL; - } - if (optarg && !(settings->opt.caption = strdup(optarg))) { - perror("malloc"); - exit(CMD_TERMINATE); - } - break; - case 'c':{ - if (strncmp(cmd, "copy ", strlen("copy ")) == 0) - do_copy(optarg2, settings); - else if (strncmp(cmd, "connect ", strlen("connect ")) == 0 || - strcmp(cmd, "connect") == 0 /* issue error message */) { - char *optarg3 = NULL; - int blank_loc2; - - if (optarg2) { - blank_loc2 = strcspn(optarg2, " \t"); - if (blank_loc2 == 0 || *(optarg2 + blank_loc2) == '\0') - optarg3 = NULL; - else { - optarg3 = optarg2 + blank_loc2 + - strspn(optarg2 + blank_loc2, " \t"); - *(optarg2 + blank_loc2) = '\0'; - } - } - do_connect(optarg2, optarg3, settings); - } - else { - char *optarg3 = NULL; - int blank_loc2; - - if (optarg) { - blank_loc2 = strcspn(optarg, " \t"); - if (blank_loc2 == 0 || *(optarg + blank_loc2) == '\0') - optarg3 = NULL; - else { - optarg3 = optarg + blank_loc2 + - strspn(optarg + blank_loc2, " \t"); - *(optarg + blank_loc2) = '\0'; - } - } - do_connect(optarg, optarg3, settings); - } - } - break; - case 'd': /* \d describe tables or columns in a table */ - if (strncmp(cmd, "dt", 2) == 0) { /* only tables */ - tableList(settings, 0, 't'); - } else if (strncmp(cmd, "di", 2) == 0) { /* only indices */ - tableList(settings, 0, 'i'); - } else if (strncmp(cmd, "ds", 2) == 0) { /* only sequences */ - tableList(settings, 0, 'S'); - } else if (!optarg) { /* show tables, sequences and indices */ - tableList(settings, 0, 'b'); - } else if (strcmp(optarg, "*") == 0) { /* show everything */ - if (tableList(settings, 0, 'b') == 0) - tableList(settings, 1, 'b'); - } else { /* describe the specified table */ - tableDesc(settings, optarg); - } - break; - case 'e': /* edit */ - { - do_edit(optarg, query, &status); - break; - } - case 'E': + int status = CMD_SKIP_LINE; + char *optarg; + + /* + * Pointer inside the <cmd> string to the argument of the slash + * command, assuming it is a one-character slash command. If it's not + * a one-character command, this is meaningless. + */ + char *optarg2; + + /* + * Pointer inside the <cmd> string to the argument of the slash + * command assuming it's not a one-character command. If it's a + * one-character command, this is meaningless. + */ + char *cmd; + + /* + * String: value of the slash command, less the slash and with escape + * sequences decoded. + */ + int blank_loc; + + /* Offset within <cmd> of first blank */ + + cmd = malloc(strlen(line)); /* unescaping better not make string grow. */ + + unescape(cmd, line + 1); /* sets cmd string */ + + if (strlen(cmd) >= 1 && cmd[strlen(cmd) - 1] == ';') /* strip trailing ; */ + cmd[strlen(cmd) - 1] = '\0'; + + /* + * Originally, there were just single character commands. Now, we + * define some longer, friendly commands, but we have to keep the old + * single character commands too. \c used to be what \connect is now. + * Complicating matters is the fact that with the single-character + * commands, you can start the argument right after the single + * character, so "\copy" would mean "connect to database named 'opy'". + */ + + if (strlen(cmd) > 1) + optarg = cmd + 1 + strspn(cmd + 1, " \t"); + else + optarg = NULL; + + blank_loc = strcspn(cmd, " \t"); + if (blank_loc == 0 || !cmd[blank_loc]) + optarg2 = NULL; + else + optarg2 = cmd + blank_loc + strspn(cmd + blank_loc, " \t"); + + switch (cmd[0]) { - FILE *fd; - static char *lastfile; - struct stat st, st2; - if (optarg) { - if (lastfile) - free(lastfile); - lastfile = malloc(strlen(optarg + 1)); - if (!lastfile) { - perror("malloc"); - exit(CMD_TERMINATE); - } - strcpy(lastfile, optarg); - } else if (!lastfile) { - fprintf(stderr, "\\r must be followed by a file name initially\n"); + case 'a': /* toggles to align fields on output */ + toggle(settings, &settings->opt.align, "field alignment"); break; - } - stat(lastfile, &st); - editFile(lastfile); - if ((stat(lastfile, &st2) == -1) || ((fd = fopen(lastfile, "r")) == NULL)) { - perror(lastfile); + case 'C': /* define new caption */ + if (settings->opt.caption) + { + free(settings->opt.caption); + settings->opt.caption = NULL; + } + if (optarg && !(settings->opt.caption = strdup(optarg))) + { + perror("malloc"); + exit(CMD_TERMINATE); + } break; - } - if (st2.st_mtime == st.st_mtime) { - if (!settings->quiet) - fprintf(stderr, "warning: %s not modified. query not executed\n", lastfile); - fclose(fd); + case 'c': + { + if (strncmp(cmd, "copy ", strlen("copy ")) == 0) + do_copy(optarg2, settings); + else if (strncmp(cmd, "connect ", strlen("connect ")) == 0 || + strcmp(cmd, "connect") == 0 /* issue error message */ ) + { + char *optarg3 = NULL; + int blank_loc2; + + if (optarg2) + { + blank_loc2 = strcspn(optarg2, " \t"); + if (blank_loc2 == 0 || *(optarg2 + blank_loc2) == '\0') + optarg3 = NULL; + else + { + optarg3 = optarg2 + blank_loc2 + + strspn(optarg2 + blank_loc2, " \t"); + *(optarg2 + blank_loc2) = '\0'; + } + } + do_connect(optarg2, optarg3, settings); + } + else + { + char *optarg3 = NULL; + int blank_loc2; + + if (optarg) + { + blank_loc2 = strcspn(optarg, " \t"); + if (blank_loc2 == 0 || *(optarg + blank_loc2) == '\0') + optarg3 = NULL; + else + { + optarg3 = optarg + blank_loc2 + + strspn(optarg + blank_loc2, " \t"); + *(optarg + blank_loc2) = '\0'; + } + } + do_connect(optarg, optarg3, settings); + } + } break; - } - MainLoop(settings, fd); - fclose(fd); - break; - } - case 'f': - { - char *fs = DEFAULT_FIELD_SEP; - if (optarg) - fs = optarg; - if (settings->opt.fieldSep) - free(settings->opt.fieldSep); - if (!(settings->opt.fieldSep = strdup(fs))) { - perror("malloc"); - exit(CMD_TERMINATE); - } - if (!settings->quiet) - printf("field separator changed to '%s'\n", settings->opt.fieldSep); - break; - } - case 'g': /* \g means send query */ - if (!optarg) - settings->gfname = NULL; - else if (!(settings->gfname = strdup(optarg))) { - perror("malloc"); - exit(CMD_TERMINATE); - } - status = CMD_SEND; - break; - case 'h': /* help */ - { - do_help(settings, optarg); - break; - } - case 'i': /* \i is include file */ - { - FILE *fd; + case 'd': /* \d describe tables or columns in a + * table */ + if (strncmp(cmd, "dt", 2) == 0) + { /* only tables */ + tableList(settings, 0, 't'); + } + else if (strncmp(cmd, "di", 2) == 0) + { /* only indices */ + tableList(settings, 0, 'i'); + } + else if (strncmp(cmd, "ds", 2) == 0) + { /* only sequences */ + tableList(settings, 0, 'S'); + } + else if (!optarg) + { /* show tables, sequences and indices */ + tableList(settings, 0, 'b'); + } + else if (strcmp(optarg, "*") == 0) + { /* show everything */ + if (tableList(settings, 0, 'b') == 0) + tableList(settings, 1, 'b'); + } + else + { /* describe the specified table */ + tableDesc(settings, optarg); + } + break; + case 'e': /* edit */ + { + do_edit(optarg, query, &status); + break; + } + case 'E': + { + FILE *fd; + static char *lastfile; + struct stat st, + st2; + + if (optarg) + { + if (lastfile) + free(lastfile); + lastfile = malloc(strlen(optarg + 1)); + if (!lastfile) + { + perror("malloc"); + exit(CMD_TERMINATE); + } + strcpy(lastfile, optarg); + } + else if (!lastfile) + { + fprintf(stderr, "\\r must be followed by a file name initially\n"); + break; + } + stat(lastfile, &st); + editFile(lastfile); + if ((stat(lastfile, &st2) == -1) || ((fd = fopen(lastfile, "r")) == NULL)) + { + perror(lastfile); + break; + } + if (st2.st_mtime == st.st_mtime) + { + if (!settings->quiet) + fprintf(stderr, "warning: %s not modified. query not executed\n", lastfile); + fclose(fd); + break; + } + MainLoop(settings, fd); + fclose(fd); + break; + } + case 'f': + { + char *fs = DEFAULT_FIELD_SEP; + + if (optarg) + fs = optarg; + if (settings->opt.fieldSep) + free(settings->opt.fieldSep); + if (!(settings->opt.fieldSep = strdup(fs))) + { + perror("malloc"); + exit(CMD_TERMINATE); + } + if (!settings->quiet) + printf("field separator changed to '%s'\n", settings->opt.fieldSep); + break; + } + case 'g': /* \g means send query */ + if (!optarg) + settings->gfname = NULL; + else if (!(settings->gfname = strdup(optarg))) + { + perror("malloc"); + exit(CMD_TERMINATE); + } + status = CMD_SEND; + break; + case 'h': /* help */ + { + do_help(settings, optarg); + break; + } + case 'i': /* \i is include file */ + { + FILE *fd; - if (!optarg) { - fprintf(stderr, "\\i must be followed by a file name\n"); + if (!optarg) + { + fprintf(stderr, "\\i must be followed by a file name\n"); + break; + } + if ((fd = fopen(optarg, "r")) == NULL) + { + fprintf(stderr, "file named %s could not be opened\n", optarg); + break; + } + MainLoop(settings, fd); + fclose(fd); + break; + } + case 'l': /* \l is list database */ + listAllDbs(settings); break; - } - if ((fd = fopen(optarg, "r")) == NULL) { - fprintf(stderr, "file named %s could not be opened\n", optarg); + case 'H': + if (toggle(settings, &settings->opt.html3, "HTML3.0 tabular output")) + settings->opt.standard = 0; break; - } - MainLoop(settings, fd); - fclose(fd); - break; - } - case 'l': /* \l is list database */ - listAllDbs(settings); - break; - case 'H': - if (toggle(settings, &settings->opt.html3, "HTML3.0 tabular output")) - settings->opt.standard = 0; - break; - case 'o': - setFout(settings, optarg); - break; - case 'p': - if (query) { - fputs(query, stdout); - fputc('\n', stdout); - } - break; - case 'q': /* \q is quit */ - status = CMD_TERMINATE; - break; - case 'r': /* reset(clear) the buffer */ - query[0] = '\0'; - if (!settings->quiet) - printf("buffer reset(cleared)\n"); - break; - case 's': /* \s is save history to a file */ - if (!optarg) - optarg = "/dev/tty"; + case 'o': + setFout(settings, optarg); + break; + case 'p': + if (query) + { + fputs(query, stdout); + fputc('\n', stdout); + } + break; + case 'q': /* \q is quit */ + status = CMD_TERMINATE; + break; + case 'r': /* reset(clear) the buffer */ + query[0] = '\0'; + if (!settings->quiet) + printf("buffer reset(cleared)\n"); + break; + case 's': /* \s is save history to a file */ + if (!optarg) + optarg = "/dev/tty"; #ifdef HAVE_HISTORY - if (write_history(optarg) != 0) - fprintf(stderr, "cannot write history to %s\n", optarg); + if (write_history(optarg) != 0) + fprintf(stderr, "cannot write history to %s\n", optarg); #endif - break; - case 'm': /* monitor like type-setting */ - if (toggle(settings, &settings->opt.standard, "standard SQL separaters and padding")) { - settings->opt.html3 = settings->opt.expanded = 0; - settings->opt.align = settings->opt.header = 1; - if (settings->opt.fieldSep) - free(settings->opt.fieldSep); - settings->opt.fieldSep = strdup("|"); - if (!settings->quiet) - printf("field separator changed to '%s'\n", settings->opt.fieldSep); - } else { - if (settings->opt.fieldSep) - free(settings->opt.fieldSep); - settings->opt.fieldSep = strdup(DEFAULT_FIELD_SEP); - if (!settings->quiet) - printf("field separator changed to '%s'\n", settings->opt.fieldSep); - } - break; - case 'z': /* list table rights (grant/revoke) */ - rightsList(settings); - break; - case 't': /* toggle headers */ - toggle(settings, &settings->opt.header, "output headings and row count"); - break; - case 'T': /* define html <table ...> option */ - if (settings->opt.tableOpt) - free(settings->opt.tableOpt); - if (!optarg) - settings->opt.tableOpt = NULL; - else if (!(settings->opt.tableOpt = strdup(optarg))) { - perror("malloc"); - exit(CMD_TERMINATE); + break; + case 'm': /* monitor like type-setting */ + if (toggle(settings, &settings->opt.standard, "standard SQL separaters and padding")) + { + settings->opt.html3 = settings->opt.expanded = 0; + settings->opt.align = settings->opt.header = 1; + if (settings->opt.fieldSep) + free(settings->opt.fieldSep); + settings->opt.fieldSep = strdup("|"); + if (!settings->quiet) + printf("field separator changed to '%s'\n", settings->opt.fieldSep); + } + else + { + if (settings->opt.fieldSep) + free(settings->opt.fieldSep); + settings->opt.fieldSep = strdup(DEFAULT_FIELD_SEP); + if (!settings->quiet) + printf("field separator changed to '%s'\n", settings->opt.fieldSep); + } + break; + case 'z': /* list table rights (grant/revoke) */ + rightsList(settings); + break; + case 't': /* toggle headers */ + toggle(settings, &settings->opt.header, "output headings and row count"); + break; + case 'T': /* define html <table ...> option */ + if (settings->opt.tableOpt) + free(settings->opt.tableOpt); + if (!optarg) + settings->opt.tableOpt = NULL; + else if (!(settings->opt.tableOpt = strdup(optarg))) + { + perror("malloc"); + exit(CMD_TERMINATE); + } + break; + case 'x': + toggle(settings, &settings->opt.expanded, "expanded table representation"); + break; + case '!': + do_shell(optarg); + break; + default: + case '?': /* \? is help */ + slashUsage(settings); + break; } - break; - case 'x': - toggle(settings, &settings->opt.expanded, "expanded table representation"); - break; - case '!': - do_shell(optarg); - break; - default: - case '?': /* \? is help */ - slashUsage(settings); - break; - } - free(cmd); - return status; -} /* HandleSlashCmds() */ + free(cmd); + return status; +} /* HandleSlashCmds() */ /* MainLoop() * Main processing loop for reading lines of input - * and sending them to the backend. - * + * and sending them to the backend. + * * This loop is re-entrant. May be called by \i command - * which reads input from a file. + * which reads input from a file. * db_ptr must be initialized and set. */ static int MainLoop(PsqlSettings * settings, FILE * source) { - char *line; /* line of input */ - char *xcomment; /* start of extended comment */ - int len; /* length of the line */ - char query[MAX_QUERY_BUFFER]; /* multi-line query storage */ - int successResult = 1; - int slashCmdStatus = CMD_SEND; - /* - * slashCmdStatus can be: - * CMD_UNKNOWN - send currently constructed query to backend (i.e. we got a \g) - * CMD_SEND - send currently constructed query to backend (i.e. we got a \g) - * CMD_SKIP_LINE - skip processing of this line, continue building up query - * CMD_TERMINATE - terminate processing of this query entirely - * CMD_NEWEDIT - new query supplied by edit - */ - - bool querySent = false; - bool interactive; - READ_ROUTINE GetNextLine; - bool eof = 0; - /* We've reached the end of our command input. */ - bool success; - bool in_quote; - int paren_level; - char *query_start; - - interactive = ((source == stdin) && !settings->notty); - if (interactive) { - if (settings->prompt) - free(settings->prompt); - settings->prompt = - malloc(strlen(PQdb(settings->db)) + strlen(PROMPT) + 1); - if (settings->quiet) - settings->prompt[0] = '\0'; - else - sprintf(settings->prompt, "%s%s", PQdb(settings->db), PROMPT); - if (settings->useReadline) { -#ifdef HAVE_HISTORY - using_history(); -#endif - GetNextLine = gets_readline; - } else - GetNextLine = gets_noreadline; - } else - GetNextLine = gets_fromFile; - - query[0] = '\0'; - xcomment = NULL; - in_quote = false; - paren_level = 0; - slashCmdStatus = CMD_UNKNOWN; /* set default */ - - /* main loop to get queries and execute them */ - while (!eof) { - /* just returned from editing the line? then just copy to the input buffer */ - if (slashCmdStatus == CMD_NEWEDIT) { - paren_level = 0; - line = strdup(query); - query[0] = '\0'; - - /* otherwise, get another line and set interactive prompt if necessary */ - } else { - if (interactive && !settings->quiet) { - if (in_quote) - settings->prompt[strlen(settings->prompt)-3] = PROMPT_QUOTE; - else if (xcomment != NULL) - settings->prompt[strlen(settings->prompt)-3] = PROMPT_COMMENT; - else if (query[0] != '\0' && !querySent) - settings->prompt[strlen(settings->prompt)-3] = PROMPT_CONTINUE; + char *line; /* line of input */ + char *xcomment; /* start of extended comment */ + int len; /* length of the line */ + char query[MAX_QUERY_BUFFER]; /* multi-line query + * storage */ + int successResult = 1; + int slashCmdStatus = CMD_SEND; + + /* + * slashCmdStatus can be: CMD_UNKNOWN - send currently constructed + * query to backend (i.e. we got a \g) CMD_SEND - send + * currently constructed query to backend (i.e. we got a \g) + * CMD_SKIP_LINE - skip processing of this line, continue building + * up query CMD_TERMINATE - terminate processing of this query + * entirely CMD_NEWEDIT - new query supplied by edit + */ + + bool querySent = false; + bool interactive; + READ_ROUTINE GetNextLine; + bool eof = 0; + + /* We've reached the end of our command input. */ + bool success; + bool in_quote; + int paren_level; + char *query_start; + + interactive = ((source == stdin) && !settings->notty); + if (interactive) + { + if (settings->prompt) + free(settings->prompt); + settings->prompt = + malloc(strlen(PQdb(settings->db)) + strlen(PROMPT) + 1); + if (settings->quiet) + settings->prompt[0] = '\0'; else - settings->prompt[strlen(settings->prompt)-3] = PROMPT_READY; - } - line = GetNextLine(settings->prompt, source); + sprintf(settings->prompt, "%s%s", PQdb(settings->db), PROMPT); + if (settings->useReadline) + { #ifdef HAVE_HISTORY - if (interactive && settings->useReadline && line != NULL) - add_history(line); /* save non-empty lines in history */ + using_history(); #endif + GetNextLine = gets_readline; + } + else + GetNextLine = gets_noreadline; } + else + GetNextLine = gets_fromFile; - /* query - pointer to current command - * query_start - placeholder for next command - */ + query[0] = '\0'; + xcomment = NULL; + in_quote = false; + paren_level = 0; + slashCmdStatus = CMD_UNKNOWN; /* set default */ - /* not currently inside an extended comment? */ - if (xcomment == NULL) { - query_start = line; - - /* otherwise, continue the extended comment... */ - } else { - query_start = line; - xcomment = line; - }; - - if (line == NULL) { /* No more input. Time to quit */ - if (!settings->quiet) - printf("EOF\n"); /* Goes on prompt line */ - eof = true; - } else { - /* remove whitespaces on the right, incl. \n's */ - line = rightTrim(line); - - /* echo back if input is from file */ - if (!interactive && !settings->singleStep && !settings->quiet) - fprintf(stderr, "%s\n", line); - - /* nothing on line after trimming? then ignore */ - if (line[0] == '\0') { - free(line); - continue; - } + /* main loop to get queries and execute them */ + while (!eof) + { - len = strlen(line); + /* + * just returned from editing the line? then just copy to the + * input buffer + */ + if (slashCmdStatus == CMD_NEWEDIT) + { + paren_level = 0; + line = strdup(query); + query[0] = '\0'; - if (settings->singleLineMode) { - SendQuery(&success, settings, line, false, false, 0); - successResult &= success; - querySent = true; + /* + * otherwise, get another line and set interactive prompt if + * necessary + */ + } + else + { + if (interactive && !settings->quiet) + { + if (in_quote) + settings->prompt[strlen(settings->prompt) - 3] = PROMPT_QUOTE; + else if (xcomment != NULL) + settings->prompt[strlen(settings->prompt) - 3] = PROMPT_COMMENT; + else if (query[0] != '\0' && !querySent) + settings->prompt[strlen(settings->prompt) - 3] = PROMPT_CONTINUE; + else + settings->prompt[strlen(settings->prompt) - 3] = PROMPT_READY; + } + line = GetNextLine(settings->prompt, source); +#ifdef HAVE_HISTORY + if (interactive && settings->useReadline && line != NULL) + add_history(line); /* save non-empty lines in history */ +#endif + } - } else { - int i; + /* + * query - pointer to current command query_start - placeholder + * for next command + */ - for (i = 0; i < len; i++) { - if (querySent && !isspace(line[i])) { - query[0] = '\0'; - querySent = false; - } - - /* inside a quote? */ - if (in_quote && (line[i] != '\'')) { - continue; - - /* inside an extended comment? */ - } else if (xcomment != NULL) { - if (line[i] == '*' && line[i+1] == '/') { - xcomment = NULL; - i++; - }; - continue; - - /* possible backslash command? */ - } else if (line[i] == '\\') { - char hold_char = line[i]; - - line[i] = '\0'; - if (query_start[0] != '\0') { - if (query[0] != '\0') { - strcat(query, "\n"); - strcat(query, query_start); - } else { - strcpy(query, query_start); - }; - } - line[i] = hold_char; - query_start = line + i; - break; /* handle command */ + /* not currently inside an extended comment? */ + if (xcomment == NULL) + { + query_start = line; - /* start an extended comment? */ - } else if (line[i] == '/' && line[i+1] == '*') { - xcomment = line + i; - i++; - continue; - - /* single-line comment? truncate line */ - } else if ((line[i] == '-' && line[i+1] == '-') || - (line[i] == '/' && line[i+1] == '/')) { - /* print comment at top of query */ - if (settings->singleStep) - fprintf(stdout, "%s\n", line + i); - line[i] = '\0'; /* remove comment */ - break; + /* otherwise, continue the extended comment... */ + } + else + { + query_start = line; + xcomment = line; + }; + + if (line == NULL) + { /* No more input. Time to quit */ + if (!settings->quiet) + printf("EOF\n");/* Goes on prompt line */ + eof = true; + } + else + { + /* remove whitespaces on the right, incl. \n's */ + line = rightTrim(line); + + /* echo back if input is from file */ + if (!interactive && !settings->singleStep && !settings->quiet) + fprintf(stderr, "%s\n", line); + + /* nothing on line after trimming? then ignore */ + if (line[0] == '\0') + { + free(line); + continue; + } - } else if (line[i] == '\'') { - in_quote ^= 1; + len = strlen(line); - /* semi-colon? then send query now */ - } else if (!paren_level && line[i] == ';') { - char hold_char = line[i + 1]; + if (settings->singleLineMode) + { + SendQuery(&success, settings, line, false, false, 0); + successResult &= success; + querySent = true; - line[i + 1] = '\0'; - if (query_start[0] != '\0') { - if (query[0] != '\0') { - strcat(query, "\n"); - strcat(query, query_start); - } else - strcpy(query, query_start); } - SendQuery(&success, settings, query, false, false, 0); - successResult &= success; - line[i + 1] = hold_char; - query_start = line + i + 1; - querySent = true; + else + { + int i; + + for (i = 0; i < len; i++) + { + if (querySent && !isspace(line[i])) + { + query[0] = '\0'; + querySent = false; + } + + /* inside a quote? */ + if (in_quote && (line[i] != '\'')) + { + continue; + + /* inside an extended comment? */ + } + else if (xcomment != NULL) + { + if (line[i] == '*' && line[i + 1] == '/') + { + xcomment = NULL; + i++; + }; + continue; + + /* possible backslash command? */ + } + else if (line[i] == '\\') + { + char hold_char = line[i]; + + line[i] = '\0'; + if (query_start[0] != '\0') + { + if (query[0] != '\0') + { + strcat(query, "\n"); + strcat(query, query_start); + } + else + { + strcpy(query, query_start); + }; + } + line[i] = hold_char; + query_start = line + i; + break; /* handle command */ + + /* start an extended comment? */ + } + else if (line[i] == '/' && line[i + 1] == '*') + { + xcomment = line + i; + i++; + continue; + + /* single-line comment? truncate line */ + } + else if ((line[i] == '-' && line[i + 1] == '-') || + (line[i] == '/' && line[i + 1] == '/')) + { + /* print comment at top of query */ + if (settings->singleStep) + fprintf(stdout, "%s\n", line + i); + line[i] = '\0'; /* remove comment */ + break; + + } + else if (line[i] == '\'') + { + in_quote ^= 1; + + /* semi-colon? then send query now */ + } + else if (!paren_level && line[i] == ';') + { + char hold_char = line[i + 1]; + + line[i + 1] = '\0'; + if (query_start[0] != '\0') + { + if (query[0] != '\0') + { + strcat(query, "\n"); + strcat(query, query_start); + } + else + strcpy(query, query_start); + } + SendQuery(&success, settings, query, false, false, 0); + successResult &= success; + line[i + 1] = hold_char; + query_start = line + i + 1; + querySent = true; + + } + else if (line[i] == '(') + { + paren_level++; + + } + else if (paren_level && line[i] == ')') + { + paren_level--; + }; + } + } - } else if (line[i] == '(') { - paren_level++; + /* nothing on line after trimming? then ignore */ + if (line[0] == '\0') + { + free(line); + continue; + } - } else if (paren_level && line[i] == ')') { - paren_level--; - }; - } - } + slashCmdStatus = CMD_UNKNOWN; + if (!in_quote && query_start[0] == '\\') + { + slashCmdStatus = HandleSlashCmds(settings, + query_start, + query); + if (slashCmdStatus == CMD_SKIP_LINE) + { + if (query[0] == '\0') + paren_level = 0; + free(line); + continue; + } + if (slashCmdStatus == CMD_TERMINATE) + { + free(line); + break; + } + free(line); + } + else if (strlen(query) + strlen(query_start) > MAX_QUERY_BUFFER) + { + fprintf(stderr, "query buffer max length of %d exceeded\n", + MAX_QUERY_BUFFER); + fprintf(stderr, "query line ignored\n"); + free(line); + } + else + { + if (query_start[0] != '\0') + { + + querySent = false; + if (query[0] != '\0') + { + strcat(query, "\n"); + strcat(query, query_start); + } + else + strcpy(query, query_start); + } + free(line); /* PURIFY */ + } - /* nothing on line after trimming? then ignore */ - if (line[0] == '\0') { - free(line); - continue; - } - - slashCmdStatus = CMD_UNKNOWN; - if (!in_quote && query_start[0] == '\\') { - slashCmdStatus = HandleSlashCmds(settings, - query_start, - query); - if (slashCmdStatus == CMD_SKIP_LINE) { - if (query[0] == '\0') - paren_level = 0; - free(line); - continue; - } - if (slashCmdStatus == CMD_TERMINATE) { - free(line); - break; - } - free(line); - } else if (strlen(query) + strlen(query_start) > MAX_QUERY_BUFFER) { - fprintf(stderr, "query buffer max length of %d exceeded\n", - MAX_QUERY_BUFFER); - fprintf(stderr, "query line ignored\n"); - free (line); - } else { - if (query_start[0] != '\0') { - - querySent = false; - if (query[0] != '\0') { - strcat(query, "\n"); - strcat(query, query_start); - } else - strcpy(query, query_start); - } - free(line); /* PURIFY */ - } - - /* had a backslash-g? force the query to be sent */ - if (slashCmdStatus == CMD_SEND) { + /* had a backslash-g? force the query to be sent */ + if (slashCmdStatus == CMD_SEND) + { #if FALSE - if (! querySent) { - SendQuery(&success, settings, query, false, false, 0); - successResult &= success; - } + if (!querySent) + { + SendQuery(&success, settings, query, false, false, 0); + successResult &= success; + } #else - SendQuery(&success, settings, query, false, false, 0); - successResult &= success; + SendQuery(&success, settings, query, false, false, 0); + successResult &= success; #endif - querySent = true; - } - } - } /* while */ - return successResult; -} /* MainLoop() */ + querySent = true; + } + } + } /* while */ + return successResult; +} /* MainLoop() */ int main(int argc, char **argv) { - extern char *optarg; - extern int optind; - - char *dbname = NULL; - char *host = NULL; - char *port = NULL; - char *qfilename = NULL; - char errbuf[ERROR_MSG_LENGTH]; - - PsqlSettings settings; - - char *singleQuery = NULL; - - bool listDatabases = 0; - int successResult = 1; - bool singleSlashCmd = 0; - int c; - - memset(&settings, 0, sizeof settings); - settings.opt.align = 1; - settings.opt.header = 1; - settings.queryFout = stdout; - settings.opt.fieldSep = strdup(DEFAULT_FIELD_SEP); - settings.opt.pager = 1; - if (!isatty(0) || !isatty(1)) - settings.quiet = settings.notty = 1; + extern char *optarg; + extern int optind; + + char *dbname = NULL; + char *host = NULL; + char *port = NULL; + char *qfilename = NULL; + char errbuf[ERROR_MSG_LENGTH]; + + PsqlSettings settings; + + char *singleQuery = NULL; + + bool listDatabases = 0; + int successResult = 1; + bool singleSlashCmd = 0; + int c; + + memset(&settings, 0, sizeof settings); + settings.opt.align = 1; + settings.opt.header = 1; + settings.queryFout = stdout; + settings.opt.fieldSep = strdup(DEFAULT_FIELD_SEP); + settings.opt.pager = 1; + if (!isatty(0) || !isatty(1)) + settings.quiet = settings.notty = 1; #ifdef HAVE_LIBREADLINE - else - settings.useReadline = 1; + else + settings.useReadline = 1; #endif #ifdef PSQL_ALWAYS_GET_PASSWORDS - settings.getPassword = 1; + settings.getPassword = 1; #else - settings.getPassword = 0; + settings.getPassword = 0; #endif - while ((c = getopt(argc, argv, "Aa:c:d:ef:F:lh:Hnso:p:qStT:ux")) != EOF) { - switch (c) { - case 'A': - settings.opt.align = 0; - break; - case 'a': - fe_setauthsvc(optarg, errbuf); - break; - case 'c': - singleQuery = strdup(optarg); - if (singleQuery[0] == '\\') { - singleSlashCmd = 1; - } - break; - case 'd': - dbname = optarg; - break; - case 'e': - settings.echoQuery = 1; - break; - case 'f': - qfilename = optarg; - break; - case 'F': - settings.opt.fieldSep = strdup(optarg); - break; - case 'l': - listDatabases = 1; - break; - case 'h': - host = optarg; - break; - case 'H': - settings.opt.html3 = 1; - break; - case 'n': - settings.useReadline = 0; - break; - case 'o': - setFout(&settings, optarg); - break; - case 'p': - port = optarg; - break; - case 'q': - settings.quiet = 1; - break; - case 's': - settings.singleStep = 1; - break; - case 'S': - settings.singleLineMode = 1; - break; - case 't': - settings.opt.header = 0; - break; - case 'T': - settings.opt.tableOpt = strdup(optarg); - break; - case 'u': - settings.getPassword = 1; - break; - case 'x': - settings.opt.expanded = 1; - break; - default: - usage(argv[0]); - break; + while ((c = getopt(argc, argv, "Aa:c:d:ef:F:lh:Hnso:p:qStT:ux")) != EOF) + { + switch (c) + { + case 'A': + settings.opt.align = 0; + break; + case 'a': + fe_setauthsvc(optarg, errbuf); + break; + case 'c': + singleQuery = strdup(optarg); + if (singleQuery[0] == '\\') + { + singleSlashCmd = 1; + } + break; + case 'd': + dbname = optarg; + break; + case 'e': + settings.echoQuery = 1; + break; + case 'f': + qfilename = optarg; + break; + case 'F': + settings.opt.fieldSep = strdup(optarg); + break; + case 'l': + listDatabases = 1; + break; + case 'h': + host = optarg; + break; + case 'H': + settings.opt.html3 = 1; + break; + case 'n': + settings.useReadline = 0; + break; + case 'o': + setFout(&settings, optarg); + break; + case 'p': + port = optarg; + break; + case 'q': + settings.quiet = 1; + break; + case 's': + settings.singleStep = 1; + break; + case 'S': + settings.singleLineMode = 1; + break; + case 't': + settings.opt.header = 0; + break; + case 'T': + settings.opt.tableOpt = strdup(optarg); + break; + case 'u': + settings.getPassword = 1; + break; + case 'x': + settings.opt.expanded = 1; + break; + default: + usage(argv[0]); + break; + } } - } - /* if we still have an argument, use it as the database name */ - if (argc - optind == 1) - dbname = argv[optind]; - - if (listDatabases) - dbname = "template1"; - - if(settings.getPassword) { - char username[9]; - char password[9]; - char *connect_string; - - prompt_for_password(username, password); - - /* now use PQconnectdb so we can pass these options */ - connect_string = make_connect_string(host, port, dbname, username, password); - settings.db = PQconnectdb(connect_string); - free(connect_string); - } else { - settings.db = PQsetdb(host, port, NULL, NULL, dbname); - } - - dbname = PQdb(settings.db); - - if (PQstatus(settings.db) == CONNECTION_BAD) { - fprintf(stderr, "Connection to database '%s' failed.\n", dbname); - fprintf(stderr, "%s", PQerrorMessage(settings.db)); - PQfinish(settings.db); - exit(1); - } - if (listDatabases) { - exit(listAllDbs(&settings)); - } - if (!settings.quiet && !singleQuery && !qfilename) { - printf("Welcome to the POSTGRESQL interactive sql monitor:\n"); - printf(" Please read the file COPYRIGHT for copyright terms " - "of POSTGRESQL\n\n"); - printf(" type \\? for help on slash commands\n"); - printf(" type \\q to quit\n"); - printf(" type \\g or terminate with semicolon to execute query\n"); - printf(" You are currently connected to the database: %s\n\n", dbname); - } - if (qfilename || singleSlashCmd) { - /* - * read in a file full of queries instead of reading in queries - * interactively - */ - char *line; - - if (singleSlashCmd) { - /* Not really a query, but "Do what I mean, not what I say." */ - line = singleQuery; - } else { - line = malloc(strlen(qfilename) + 5); - sprintf(line, "\\i %s", qfilename); + /* if we still have an argument, use it as the database name */ + if (argc - optind == 1) + dbname = argv[optind]; + + if (listDatabases) + dbname = "template1"; + + if (settings.getPassword) + { + char username[9]; + char password[9]; + char *connect_string; + + prompt_for_password(username, password); + + /* now use PQconnectdb so we can pass these options */ + connect_string = make_connect_string(host, port, dbname, username, password); + settings.db = PQconnectdb(connect_string); + free(connect_string); } - HandleSlashCmds(&settings, line, ""); - free (line); /* PURIFY */ - } else { - if (singleQuery) { - bool success; /* The query succeeded at the backend */ - SendQuery(&success, &settings, singleQuery, false, false, 0); - successResult = success; - } else - successResult = MainLoop(&settings, stdin); - } - - PQfinish(settings.db); - free(settings.opt.fieldSep); /* PURIFY */ - if(settings.prompt) free(settings.prompt); /* PURIFY */ - - return !successResult; + else + { + settings.db = PQsetdb(host, port, NULL, NULL, dbname); + } + + dbname = PQdb(settings.db); + + if (PQstatus(settings.db) == CONNECTION_BAD) + { + fprintf(stderr, "Connection to database '%s' failed.\n", dbname); + fprintf(stderr, "%s", PQerrorMessage(settings.db)); + PQfinish(settings.db); + exit(1); + } + if (listDatabases) + { + exit(listAllDbs(&settings)); + } + if (!settings.quiet && !singleQuery && !qfilename) + { + printf("Welcome to the POSTGRESQL interactive sql monitor:\n"); + printf(" Please read the file COPYRIGHT for copyright terms " + "of POSTGRESQL\n\n"); + printf(" type \\? for help on slash commands\n"); + printf(" type \\q to quit\n"); + printf(" type \\g or terminate with semicolon to execute query\n"); + printf(" You are currently connected to the database: %s\n\n", dbname); + } + if (qfilename || singleSlashCmd) + { + + /* + * read in a file full of queries instead of reading in queries + * interactively + */ + char *line; + + if (singleSlashCmd) + { + /* Not really a query, but "Do what I mean, not what I say." */ + line = singleQuery; + } + else + { + line = malloc(strlen(qfilename) + 5); + sprintf(line, "\\i %s", qfilename); + } + HandleSlashCmds(&settings, line, ""); + free(line); /* PURIFY */ + } + else + { + if (singleQuery) + { + bool success; /* The query succeeded at the + * backend */ + + SendQuery(&success, &settings, singleQuery, false, false, 0); + successResult = success; + } + else + successResult = MainLoop(&settings, stdin); + } + + PQfinish(settings.db); + free(settings.opt.fieldSep);/* PURIFY */ + if (settings.prompt) + free(settings.prompt); /* PURIFY */ + + return !successResult; } -#define COPYBUFSIZ 8192 +#define COPYBUFSIZ 8192 static void handleCopyOut(PGresult * res, bool quiet, FILE * copystream) { - bool copydone; - char copybuf[COPYBUFSIZ]; - int ret; - - copydone = false; /* Can't be done; haven't started. */ - - while (!copydone) { - ret = PQgetline(res->conn, copybuf, COPYBUFSIZ); - - if (copybuf[0] == '\\' && - copybuf[1] == '.' && - copybuf[2] == '\0') { - copydone = true; /* don't print this... */ - } else { - fputs(copybuf, copystream); - switch (ret) { - case EOF: - copydone = true; - /* FALLTHROUGH */ - case 0: - fputc('\n', copystream); - break; - case 1: - break; - } + bool copydone; + char copybuf[COPYBUFSIZ]; + int ret; + + copydone = false; /* Can't be done; haven't started. */ + + while (!copydone) + { + ret = PQgetline(res->conn, copybuf, COPYBUFSIZ); + + if (copybuf[0] == '\\' && + copybuf[1] == '.' && + copybuf[2] == '\0') + { + copydone = true; /* don't print this... */ + } + else + { + fputs(copybuf, copystream); + switch (ret) + { + case EOF: + copydone = true; + /* FALLTHROUGH */ + case 0: + fputc('\n', copystream); + break; + case 1: + break; + } + } } - } - fflush(copystream); - PQendcopy(res->conn); + fflush(copystream); + PQendcopy(res->conn); } @@ -1925,51 +2202,59 @@ handleCopyOut(PGresult * res, bool quiet, FILE * copystream) static void handleCopyIn(PGresult * res, const bool mustprompt, FILE * copystream) { - bool copydone = false; - bool firstload; - bool linedone; - char copybuf[COPYBUFSIZ]; - char *s; - int buflen; - int c; - - if (mustprompt) { - fputs("Enter info followed by a newline\n", stdout); - fputs("End with a backslash and a " - "period on a line by itself.\n", stdout); - } - while (!copydone) { /* for each input line ... */ - if (mustprompt) { - fputs(">> ", stdout); - fflush(stdout); + bool copydone = false; + bool firstload; + bool linedone; + char copybuf[COPYBUFSIZ]; + char *s; + int buflen; + int c; + + if (mustprompt) + { + fputs("Enter info followed by a newline\n", stdout); + fputs("End with a backslash and a " + "period on a line by itself.\n", stdout); } - firstload = true; - linedone = false; - while (!linedone) { /* for each buffer ... */ - s = copybuf; - buflen = COPYBUFSIZ; - for (; buflen > 1 && - !(linedone = (c = getc(copystream)) == '\n' || c == EOF); - --buflen) { - *s++ = c; - } - if (c == EOF) { - PQputline(res->conn, "\\."); - copydone = true; - break; - } - *s = '\0'; - PQputline(res->conn, copybuf); - if (firstload) { - if (!strcmp(copybuf, "\\.")) { - copydone = true; - } - firstload = false; - } + while (!copydone) + { /* for each input line ... */ + if (mustprompt) + { + fputs(">> ", stdout); + fflush(stdout); + } + firstload = true; + linedone = false; + while (!linedone) + { /* for each buffer ... */ + s = copybuf; + buflen = COPYBUFSIZ; + for (; buflen > 1 && + !(linedone = (c = getc(copystream)) == '\n' || c == EOF); + --buflen) + { + *s++ = c; + } + if (c == EOF) + { + PQputline(res->conn, "\\."); + copydone = true; + break; + } + *s = '\0'; + PQputline(res->conn, copybuf); + if (firstload) + { + if (!strcmp(copybuf, "\\.")) + { + copydone = true; + } + firstload = false; + } + } + PQputline(res->conn, "\n"); } - PQputline(res->conn, "\n"); - } - PQendcopy(res->conn); + PQendcopy(res->conn); } @@ -1978,131 +2263,157 @@ handleCopyIn(PGresult * res, const bool mustprompt, FILE * copystream) * try to open fname and return a FILE *, if it fails, use stdout, instead */ -static FILE * +static FILE * setFout(PsqlSettings * ps, char *fname) { - if (ps->queryFout && ps->queryFout != stdout) { - if (ps->pipe) - pclose(ps->queryFout); - else - fclose(ps->queryFout); - } - if (!fname) { - ps->queryFout = stdout; - pqsignal(SIGPIPE, SIG_DFL); - } - else { - if (*fname == '|') { - pqsignal(SIGPIPE, SIG_IGN); - ps->queryFout = popen(fname + 1, "w"); - ps->pipe = 1; - } else { - ps->queryFout = fopen(fname, "w"); - pqsignal(SIGPIPE, SIG_DFL); - ps->pipe = 0; + if (ps->queryFout && ps->queryFout != stdout) + { + if (ps->pipe) + pclose(ps->queryFout); + else + fclose(ps->queryFout); } - if (!ps->queryFout) { - perror(fname); - ps->queryFout = stdout; + if (!fname) + { + ps->queryFout = stdout; + pqsignal(SIGPIPE, SIG_DFL); } - } - return ps->queryFout; + else + { + if (*fname == '|') + { + pqsignal(SIGPIPE, SIG_IGN); + ps->queryFout = popen(fname + 1, "w"); + ps->pipe = 1; + } + else + { + ps->queryFout = fopen(fname, "w"); + pqsignal(SIGPIPE, SIG_DFL); + ps->pipe = 0; + } + if (!ps->queryFout) + { + perror(fname); + ps->queryFout = stdout; + } + } + return ps->queryFout; } -static void prompt_for_password(char *username, char *password) +static void +prompt_for_password(char *username, char *password) { - int length; + int length; + #ifdef HAVE_TERMIOS_H - struct termios t_orig, t; + struct termios t_orig, + t; + #endif - printf("Username: "); - fgets(username, 9, stdin); - length = strlen(username); - /* skip rest of the line */ - if (length > 0 && username[length-1] != '\n') { - static char buf[512]; - do { - fgets(buf, 512, stdin); - } while (buf[strlen(buf)-1] != '\n'); - } - if(length > 0 && username[length-1] == '\n') username[length-1] = '\0'; - - printf("Password: "); + printf("Username: "); + fgets(username, 9, stdin); + length = strlen(username); + /* skip rest of the line */ + if (length > 0 && username[length - 1] != '\n') + { + static char buf[512]; + + do + { + fgets(buf, 512, stdin); + } while (buf[strlen(buf) - 1] != '\n'); + } + if (length > 0 && username[length - 1] == '\n') + username[length - 1] = '\0'; + + printf("Password: "); #ifdef HAVE_TERMIOS_H - tcgetattr(0, &t); - t_orig = t; - t.c_lflag &= ~ECHO; - tcsetattr(0, TCSADRAIN, &t); + tcgetattr(0, &t); + t_orig = t; + t.c_lflag &= ~ECHO; + tcsetattr(0, TCSADRAIN, &t); #endif - fgets(password, 9, stdin); + fgets(password, 9, stdin); #ifdef HAVE_TERMIOS_H - tcsetattr(0, TCSADRAIN, &t_orig); + tcsetattr(0, TCSADRAIN, &t_orig); #endif - length = strlen(password); - /* skip rest of the line */ - if (length > 0 && password[length-1] != '\n') { - static char buf[512]; - do { - fgets(buf, 512, stdin); - } while (buf[strlen(buf)-1] != '\n'); - } - if(length > 0 && password[length-1] == '\n') password[length-1] = '\0'; - - printf("\n\n"); + length = strlen(password); + /* skip rest of the line */ + if (length > 0 && password[length - 1] != '\n') + { + static char buf[512]; + + do + { + fgets(buf, 512, stdin); + } while (buf[strlen(buf) - 1] != '\n'); + } + if (length > 0 && password[length - 1] == '\n') + password[length - 1] = '\0'; + + printf("\n\n"); } -static char *make_connect_string(char *host, char *port, char *dbname, - char *username, char *password) +static char * +make_connect_string(char *host, char *port, char *dbname, + char *username, char *password) { - int connect_string_len = 0; - char *connect_string; - - if(host) - connect_string_len += 6 + strlen(host); /* 6 == "host=" + " " */ - if(username) - connect_string_len += 6 + strlen(username); /* 6 == "user=" + " " */ - if(password) - connect_string_len += 10 + strlen(password); /* 10 == "password=" + " " */ - if(port) - connect_string_len += 6 + strlen(port); /* 6 == "port=" + " " */ - if(dbname) - connect_string_len += 8 + strlen(dbname); /* 8 == "dbname=" + " " */ - connect_string_len += 18; /* "authtype=password" + null */ - - connect_string = (char *)malloc(connect_string_len); - if(!connect_string) { - return 0; - } - connect_string[0] = '\0'; - if(host) { - strcat(connect_string, "host="); - strcat(connect_string, host); - strcat(connect_string, " "); - } - if(username) { - strcat(connect_string, "user="); - strcat(connect_string, username); - strcat(connect_string, " "); - } - if(password) { - strcat(connect_string, "password="); - strcat(connect_string, password); - strcat(connect_string, " "); - } - if(port) { - strcat(connect_string, "port="); - strcat(connect_string, port); - strcat(connect_string, " "); - } - if(dbname) { - strcat(connect_string, "dbname="); - strcat(connect_string, dbname); - strcat(connect_string, " "); - } - strcat(connect_string, "authtype=password"); - - return connect_string; + int connect_string_len = 0; + char *connect_string; + + if (host) + connect_string_len += 6 + strlen(host); /* 6 == "host=" + " " */ + if (username) + connect_string_len += 6 + strlen(username); /* 6 == "user=" + " " */ + if (password) + connect_string_len += 10 + strlen(password); /* 10 == "password=" + " + * " */ + if (port) + connect_string_len += 6 + strlen(port); /* 6 == "port=" + " " */ + if (dbname) + connect_string_len += 8 + strlen(dbname); /* 8 == "dbname=" + " " */ + connect_string_len += 18; /* "authtype=password" + null */ + + connect_string = (char *) malloc(connect_string_len); + if (!connect_string) + { + return 0; + } + connect_string[0] = '\0'; + if (host) + { + strcat(connect_string, "host="); + strcat(connect_string, host); + strcat(connect_string, " "); + } + if (username) + { + strcat(connect_string, "user="); + strcat(connect_string, username); + strcat(connect_string, " "); + } + if (password) + { + strcat(connect_string, "password="); + strcat(connect_string, password); + strcat(connect_string, " "); + } + if (port) + { + strcat(connect_string, "port="); + strcat(connect_string, port); + strcat(connect_string, " "); + } + if (dbname) + { + strcat(connect_string, "dbname="); + strcat(connect_string, dbname); + strcat(connect_string, " "); + } + strcat(connect_string, "authtype=password"); + + return connect_string; } - diff --git a/src/bin/psql/psqlHelp.h b/src/bin/psql/psqlHelp.h index bff67dc665a..f9f372a8add 100644 --- a/src/bin/psql/psqlHelp.h +++ b/src/bin/psql/psqlHelp.h @@ -1,180 +1,182 @@ /*------------------------------------------------------------------------- * * psqlHelp.h-- - * Help for query language syntax + * Help for query language syntax * * Copyright (c) 1994, Regents of the University of California * - * $Id: psqlHelp.h,v 1.22 1997/09/04 15:02:56 momjian Exp $ + * $Id: psqlHelp.h,v 1.23 1997/09/07 04:55:23 momjian Exp $ * *------------------------------------------------------------------------- */ -struct _helpStruct { - char *cmd; /* the command name */ - char *help; /* the help associated with it */ - char *syntax; /* the syntax associated with it */ -} ; - +struct _helpStruct +{ + char *cmd; /* the command name */ + char *help; /* the help associated with it */ + char *syntax; /* the syntax associated with it */ +}; + static struct _helpStruct QL_HELP[] = { - { "abort", - "abort the current transaction", - "abort [transaction];"}, - { "abort transaction", - "abort the current transaction", - "abort [transaction];"}, - { "alter table", - "add/rename attributes, rename tables", - "\talter table <class_name> [*] add column <attr> <type>;\n\talter table <class_name> [*] rename [column] <attr1> to <attr2>;\n\talter table <class_name1> rename to <class_name2>"}, - { "begin", - "begin a new transaction", - "begin [transaction|work];"}, - { "begin transaction", - "begin a new transaction", - "begin [transaction|work];"}, - { "begin work", - "begin a new transaction", - "begin [transaction|work];"}, - { "cluster", - "create a clustered index (from an existing index)", - "cluster <index_name> on <relation_name>"}, - { "close", - "close an existing cursor (cursor)", - "close <cursorname>;"}, - { "commit", - "commit a transaction", - "commit [work]"}, - { "commit work", - "commit a transaction", - "commit [work]"}, - { "copy", - "copy data to and from a table", - "copy [binary] <class_name> [with oids]\n\t{to|from} {<filename>|stdin|stdout} [using delimiters <delim>];"}, - { "create", - "Please more be specific:", - "\tcreate aggregate\n\tcreate database\n\tcreate function\n\tcreate index\n\tcreate operator\n\tcreate rule\n\tcreate sequence\n\tcreate table\n\tcreate type\n\tcreate view"}, - { "create aggregate", - "define an aggregate function", - "create aggregate <agg_name> [as] (basetype = <data_type>, \n\t[sfunc1 = <sfunc_1>, stype1 = <sfunc1_return_type>]\n\t[sfunc2 = <sfunc_2>, stype2 = <sfunc2_return_type>]\n\t[,finalfunc = <final-function>]\n\t[,initcond1 = <initial-cond1>][,initcond2 = <initial-cond2>]);"}, - { "create database", - "create a database", - "create database <dbname>"}, - { "create function", - "create a user-defined function", - "create function <function_name> ([<type1>,...<typeN>]) returns <return_type>\n\tas '<object_filename>'|'<sql-queries>'\n\tlanguage 'c'|'sql'|'internal';"}, - { "create index", - "construct an index", - "create [unique] index <indexname> on <class_name> [using <access_method>]\n( <attr1> [<type_class1>] [,...] | <funcname>(<attr1>,...) [<type_class>] );"}, - { "create operator", - "create a user-defined operator", - "create operator <operator_name> (\n\t[leftarg = <type1>][,rightarg = <type2>]\n\t,procedure = <func_name>,\n\t[,commutator = <com_op>][,negator = <neg_op>]\n\t[,restrict = <res_proc>][,hashes]\n\t[,join = <join_proc>][,sort = <sort_op1>...<sort_opN>]);"}, - { "create rule", - "define a new rule", - "create rule <rule_name> as on\n\t[select|update|delete|insert]\n\tto <object> [where <qual>]\n\tdo [instead] [<action>|nothing| [<actions>]];"}, - { "create sequence", - "create a new sequence number generator", - "create sequence <sequence_name>\n\t[increment <NUMBER>]\n\t[start <NUMBER>]\n\t[minvalue <NUMBER>]\n\t[maxvalue <NUMBER>]\n\t[cache <NUMBER>]\n\t[cycle];"}, - { "create table", - "create a new table", - "create table <class_name> ( <attr1> <type1> [[not] null],... <attrN> <typeN>)\n\t[inherits (<class_name1>,...<class_nameN>)\n\tarchive=<archive_mode>\n\tstore=<smgr_name>\n\tarch_store=<smgr_name>];"}, - { "create type", - "create a new user-defined base data type", - "create type <typename> (\n\tinternallength = (<number> | variable),\n\t[externallength = (<number>|variable),]\n\tinput=<input_function>, output = <output_function>\n\t[,element = <typename>][,delimiter=<character>][,default=\'<string>\']\n\t[,send = <send_function>][,receive = <receive_function>][,passedbyvalue]);"}, - { "create view", - "create a view", - "create view <view_name> as select <expr1>[as <attr1>][,... <exprN>[as <attrN>]] [from <from_list>] [where <qual>];"}, - { "declare", - "set up a cursor", - "declare <cursorname> [binary] cursor for\n\tselect [distinct]\n\t<expr1> [as <attr1>],...<exprN> [as <attrN>]\n\t[from <from_list>] [where <qual>]\n\t[order by <attr1> [using <op1>],... <attrN> [using <opN>]];"}, - { "delete", - "delete tuples", - "delete from <class_name> [where <qual>];"}, - { "drop", - "Please more be specific:", - "\tdrop aggregate\n\tdrop database\n\tdrop function\n\tdrop index\n\tdrop operator\n\tdrop rule\n\tdrop sequence\n\tdrop table\n\tdrop type\n\tdrop view"}, - { "drop aggregate", - "remove an aggregate function", - "drop aggregate <agg_name> <agg_type>|*;"}, - { "drop database", - "remove a database", - "drop database <dbname>"}, - { "drop function", - "remove a user-defined function", - "drop function <funcname> ([<type1>,....<typeN>]);"}, - { "drop index", - "remove an existing index", - "drop index <indexname>;"}, - { "drop operator", - "remove a user-defined operator", - "drop operator <operator_name> ([<ltype>|none],[<rtype>|none]);"}, - { "drop rule", - "remove a rule", - "drop rule <rulename>;"}, - { "drop table", - "remove a table", - "drop table <class_name>[,...<class_nameN];"}, - { "drop sequence", - "remove a sequence number generator", - "drop sequence <sequence_name>[,...<sequence_nameN];"}, - { "drop type", - "remove a user-defined base type", - "drop type <typename>;"}, - { "drop view", - "remove a view", - "drop view <view_name>"}, - { "end", - "end the current transaction", - "end [transaction];"}, - { "end transaction", - "end the current transaction", - "end [transaction];"}, - { "explain", - "explain the query execution plan", - "explain [verbose] <query>"}, - { "fetch", - "retrieve tuples from a cursor", - "fetch [forward|backward] [<number>|all] [in <cursorname>];"}, - { "grant", - "grant access control to a user or group", - "grant <privilege[,privilege,...]> on <rel1>[,...<reln>] to \n[public | group <group> | <username>]\n\t privilege is {ALL | SELECT | INSERT | UPDATE | DELETE | RULE}"}, - { "insert", - "insert tuples", - "insert into <class_name> [(<attr1>...<attrN>)]\n\t[values (<expr1>...<exprN>); |\n\tselect <expr1>,...<exprN> [from <from_clause>] [where <qual>];"}, - { "listen", - "listen for notification on a relation", - "listen <class_name>"}, - { "load", - "dynamically load a module", - "load <filename>;"}, - { "notify", - "signal all frontends and backends listening on a relation", - "notify <class_name>"}, - { "purge", - "purge historical data", - "purge <class_name> [before <abstime>] [after <reltime>];"}, - { "reset", - "set run-time environment back to default", - "reset {DateStyle | GEQO | R_PLANS}"}, - { "revoke", - "revoke access control from a user or group", - "revoke <privilege[,privilege,...]> on <rel1>[,...<reln>] from \n[public | group <group> | <username>]\n\t privilege is {ALL | SELECT | INSERT | UPDATE | DELETE | RULE}"}, - { "rollback", - "abort a transaction", - "rollback [transaction|work]"}, - { "select", - "retrieve tuples", - "select [distinct on <attr>] <expr1> [as <attr1>], ... <exprN> [as <attrN>]\n\t[into table <class_name>] [from <from_list>]\n\t[where <qual>]\n\t[order by <attr1>\n\t\t[using <op1>],..<attrN> [[using <opN>] | ASC | DESC]];" }, - { "set", - "set run-time environment", - "set DateStyle to {'ISO' | 'SQL' | 'Postgres' | 'European' | 'US' | 'NonEuropean'}\nset GEQO to {'ON[=#]' | 'OFF'}\nset R_PLANS to {'ON' | 'OFF'}"}, - { "show", - "show current run-time environment", - "show {DateStyle | GEQO | R_PLANS}"}, - { "update", - "update tuples", - "update <class_name> set <attr1>=<expr1>,...<attrN>=<exprN> [from <from_clause>] [where <qual>];"}, - { "vacuum", - "vacuum the database, i.e. cleans out deleted records, updates statistics", - "vacuum [verbose] [analyze]\n\tor\nvacuum [verbose] [analyze] table [analyze [(attr1, ... attrN)] ];"}, - { NULL, NULL, NULL} /* important to keep a NULL terminator here! */ + {"abort", + "abort the current transaction", + "abort [transaction];"}, + {"abort transaction", + "abort the current transaction", + "abort [transaction];"}, + {"alter table", + "add/rename attributes, rename tables", + "\talter table <class_name> [*] add column <attr> <type>;\n\talter table <class_name> [*] rename [column] <attr1> to <attr2>;\n\talter table <class_name1> rename to <class_name2>"}, + {"begin", + "begin a new transaction", + "begin [transaction|work];"}, + {"begin transaction", + "begin a new transaction", + "begin [transaction|work];"}, + {"begin work", + "begin a new transaction", + "begin [transaction|work];"}, + {"cluster", + "create a clustered index (from an existing index)", + "cluster <index_name> on <relation_name>"}, + {"close", + "close an existing cursor (cursor)", + "close <cursorname>;"}, + {"commit", + "commit a transaction", + "commit [work]"}, + {"commit work", + "commit a transaction", + "commit [work]"}, + {"copy", + "copy data to and from a table", + "copy [binary] <class_name> [with oids]\n\t{to|from} {<filename>|stdin|stdout} [using delimiters <delim>];"}, + {"create", + "Please more be specific:", + "\tcreate aggregate\n\tcreate database\n\tcreate function\n\tcreate index\n\tcreate operator\n\tcreate rule\n\tcreate sequence\n\tcreate table\n\tcreate type\n\tcreate view"}, + {"create aggregate", + "define an aggregate function", + "create aggregate <agg_name> [as] (basetype = <data_type>, \n\t[sfunc1 = <sfunc_1>, stype1 = <sfunc1_return_type>]\n\t[sfunc2 = <sfunc_2>, stype2 = <sfunc2_return_type>]\n\t[,finalfunc = <final-function>]\n\t[,initcond1 = <initial-cond1>][,initcond2 = <initial-cond2>]);"}, + {"create database", + "create a database", + "create database <dbname>"}, + {"create function", + "create a user-defined function", + "create function <function_name> ([<type1>,...<typeN>]) returns <return_type>\n\tas '<object_filename>'|'<sql-queries>'\n\tlanguage 'c'|'sql'|'internal';"}, + {"create index", + "construct an index", + "create [unique] index <indexname> on <class_name> [using <access_method>]\n( <attr1> [<type_class1>] [,...] | <funcname>(<attr1>,...) [<type_class>] );"}, + {"create operator", + "create a user-defined operator", + "create operator <operator_name> (\n\t[leftarg = <type1>][,rightarg = <type2>]\n\t,procedure = <func_name>,\n\t[,commutator = <com_op>][,negator = <neg_op>]\n\t[,restrict = <res_proc>][,hashes]\n\t[,join = <join_proc>][,sort = <sort_op1>...<sort_opN>]);"}, + {"create rule", + "define a new rule", + "create rule <rule_name> as on\n\t[select|update|delete|insert]\n\tto <object> [where <qual>]\n\tdo [instead] [<action>|nothing| [<actions>]];"}, + {"create sequence", + "create a new sequence number generator", + "create sequence <sequence_name>\n\t[increment <NUMBER>]\n\t[start <NUMBER>]\n\t[minvalue <NUMBER>]\n\t[maxvalue <NUMBER>]\n\t[cache <NUMBER>]\n\t[cycle];"}, + {"create table", + "create a new table", + "create table <class_name> ( <attr1> <type1> [[not] null],... <attrN> <typeN>)\n\t[inherits (<class_name1>,...<class_nameN>)\n\tarchive=<archive_mode>\n\tstore=<smgr_name>\n\tarch_store=<smgr_name>];"}, + {"create type", + "create a new user-defined base data type", + "create type <typename> (\n\tinternallength = (<number> | variable),\n\t[externallength = (<number>|variable),]\n\tinput=<input_function>, output = <output_function>\n\t[,element = <typename>][,delimiter=<character>][,default=\'<string>\']\n\t[,send = <send_function>][,receive = <receive_function>][,passedbyvalue]);"}, + {"create view", + "create a view", + "create view <view_name> as select <expr1>[as <attr1>][,... <exprN>[as <attrN>]] [from <from_list>] [where <qual>];"}, + {"declare", + "set up a cursor", + "declare <cursorname> [binary] cursor for\n\tselect [distinct]\n\t<expr1> [as <attr1>],...<exprN> [as <attrN>]\n\t[from <from_list>] [where <qual>]\n\t[order by <attr1> [using <op1>],... <attrN> [using <opN>]];"}, + {"delete", + "delete tuples", + "delete from <class_name> [where <qual>];"}, + {"drop", + "Please more be specific:", + "\tdrop aggregate\n\tdrop database\n\tdrop function\n\tdrop index\n\tdrop operator\n\tdrop rule\n\tdrop sequence\n\tdrop table\n\tdrop type\n\tdrop view"}, + {"drop aggregate", + "remove an aggregate function", + "drop aggregate <agg_name> <agg_type>|*;"}, + {"drop database", + "remove a database", + "drop database <dbname>"}, + {"drop function", + "remove a user-defined function", + "drop function <funcname> ([<type1>,....<typeN>]);"}, + {"drop index", + "remove an existing index", + "drop index <indexname>;"}, + {"drop operator", + "remove a user-defined operator", + "drop operator <operator_name> ([<ltype>|none],[<rtype>|none]);"}, + {"drop rule", + "remove a rule", + "drop rule <rulename>;"}, + {"drop table", + "remove a table", + "drop table <class_name>[,...<class_nameN];"}, + {"drop sequence", + "remove a sequence number generator", + "drop sequence <sequence_name>[,...<sequence_nameN];"}, + {"drop type", + "remove a user-defined base type", + "drop type <typename>;"}, + {"drop view", + "remove a view", + "drop view <view_name>"}, + {"end", + "end the current transaction", + "end [transaction];"}, + {"end transaction", + "end the current transaction", + "end [transaction];"}, + {"explain", + "explain the query execution plan", + "explain [verbose] <query>"}, + {"fetch", + "retrieve tuples from a cursor", + "fetch [forward|backward] [<number>|all] [in <cursorname>];"}, + {"grant", + "grant access control to a user or group", + "grant <privilege[,privilege,...]> on <rel1>[,...<reln>] to \n[public | group <group> | <username>]\n\t privilege is {ALL | SELECT | INSERT | UPDATE | DELETE | RULE}"}, + {"insert", + "insert tuples", + "insert into <class_name> [(<attr1>...<attrN>)]\n\t[values (<expr1>...<exprN>); |\n\tselect <expr1>,...<exprN> [from <from_clause>] [where <qual>];"}, + {"listen", + "listen for notification on a relation", + "listen <class_name>"}, + {"load", + "dynamically load a module", + "load <filename>;"}, + {"notify", + "signal all frontends and backends listening on a relation", + "notify <class_name>"}, + {"purge", + "purge historical data", + "purge <class_name> [before <abstime>] [after <reltime>];"}, + {"reset", + "set run-time environment back to default", + "reset {DateStyle | GEQO | R_PLANS}"}, + {"revoke", + "revoke access control from a user or group", + "revoke <privilege[,privilege,...]> on <rel1>[,...<reln>] from \n[public | group <group> | <username>]\n\t privilege is {ALL | SELECT | INSERT | UPDATE | DELETE | RULE}"}, + {"rollback", + "abort a transaction", + "rollback [transaction|work]"}, + {"select", + "retrieve tuples", + "select [distinct on <attr>] <expr1> [as <attr1>], ... <exprN> [as <attrN>]\n\t[into table <class_name>] [from <from_list>]\n\t[where <qual>]\n\t[order by <attr1>\n\t\t[using <op1>],..<attrN> [[using <opN>] | ASC | DESC]];"}, + {"set", + "set run-time environment", + "set DateStyle to {'ISO' | 'SQL' | 'Postgres' | 'European' | 'US' | 'NonEuropean'}\nset GEQO to {'ON[=#]' | 'OFF'}\nset R_PLANS to {'ON' | 'OFF'}"}, + {"show", + "show current run-time environment", + "show {DateStyle | GEQO | R_PLANS}"}, + {"update", + "update tuples", + "update <class_name> set <attr1>=<expr1>,...<attrN>=<exprN> [from <from_clause>] [where <qual>];"}, + {"vacuum", + "vacuum the database, i.e. cleans out deleted records, updates statistics", + "vacuum [verbose] [analyze]\n\tor\nvacuum [verbose] [analyze] table [analyze [(attr1, ... attrN)] ];"}, + {NULL, NULL, NULL} /* important to keep a NULL terminator + * here! */ }; diff --git a/src/bin/psql/stringutils.c b/src/bin/psql/stringutils.c index cae0e7405be..cf34622209e 100644 --- a/src/bin/psql/stringutils.c +++ b/src/bin/psql/stringutils.c @@ -1,13 +1,13 @@ /*------------------------------------------------------------------------- * * stringutils.c-- - * simple string manipulation routines + * simple string manipulation routines * * Copyright (c) 1994, Regents of the University of California * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/bin/psql/stringutils.c,v 1.10 1997/08/25 19:41:52 momjian Exp $ + * $Header: /cvsroot/pgsql/src/bin/psql/stringutils.c,v 1.11 1997/09/07 04:55:27 momjian Exp $ * *------------------------------------------------------------------------- */ @@ -30,70 +30,82 @@ /* MODIFIES the string passed in and returns the head of it */ #ifdef NOT_USED -static char *leftTrim(char *s) +static char * +leftTrim(char *s) { - char *s2 = s; - int shift=0; - int j=0; - - while (isspace(*s)) - { s++; shift++;} - if (shift > 0) - { - while ( (s2[j] = s2[j+shift]) !='\0') - j++; - } - - return s2; + char *s2 = s; + int shift = 0; + int j = 0; + + while (isspace(*s)) + { + s++; + shift++; + } + if (shift > 0) + { + while ((s2[j] = s2[j + shift]) != '\0') + j++; + } + + return s2; } + #endif -char *rightTrim(char *s) +char * +rightTrim(char *s) { - char *sEnd; - sEnd = s+strlen(s)-1; - while (sEnd >= s && isspace(*sEnd)) - sEnd--; - if (sEnd < s) - s[0]='\0'; - else - s[sEnd-s+1]='\0'; - return s; + char *sEnd; + + sEnd = s + strlen(s) - 1; + while (sEnd >= s && isspace(*sEnd)) + sEnd--; + if (sEnd < s) + s[0] = '\0'; + else + s[sEnd - s + 1] = '\0'; + return s; } #ifdef NOT_USED -static char *doubleTrim(char *s) +static char * +doubleTrim(char *s) { - strcpy(s,leftTrim(rightTrim(s))); - return s; + strcpy(s, leftTrim(rightTrim(s))); + return s; } + #endif #ifdef STRINGUTILS_TEST -void testStringUtils() +void +testStringUtils() { - static char *tests[] = {" goodbye \n", /* space on both ends */ - "hello world", /* no spaces to trim */ - "", /* empty string */ - "a", /* string with one char*/ - " ", /* string with one whitespace*/ - NULL_STR}; - - int i=0; - while (tests[i]!=NULL_STR) - { - char *t; - t = strdup(tests[i]); - printf("leftTrim(%s) = ",t); - printf("%sEND\n", leftTrim(t)); - t = strdup(tests[i]); - printf("rightTrim(%s) = ",t); - printf("%sEND\n", rightTrim(t)); - t = strdup(tests[i]); - printf("doubleTrim(%s) = ",t); - printf("%sEND\n", doubleTrim(t)); - i++; - } + static char *tests[] = {" goodbye \n", /* space on both ends */ + "hello world", /* no spaces to trim */ + "", /* empty string */ + "a", /* string with one char */ + " ", /* string with one whitespace */ + NULL_STR}; + + int i = 0; + + while (tests[i] != NULL_STR) + { + char *t; + + t = strdup(tests[i]); + printf("leftTrim(%s) = ", t); + printf("%sEND\n", leftTrim(t)); + t = strdup(tests[i]); + printf("rightTrim(%s) = ", t); + printf("%sEND\n", rightTrim(t)); + t = strdup(tests[i]); + printf("doubleTrim(%s) = ", t); + printf("%sEND\n", doubleTrim(t)); + i++; + } } diff --git a/src/bin/psql/stringutils.h b/src/bin/psql/stringutils.h index c6f037ec716..2bc8795f4c4 100644 --- a/src/bin/psql/stringutils.h +++ b/src/bin/psql/stringutils.h @@ -1,11 +1,11 @@ /*------------------------------------------------------------------------- * * stringutils.h-- - * + * * * Copyright (c) 1994, Regents of the University of California * - * $Id: stringutils.h,v 1.4 1997/08/19 21:36:58 momjian Exp $ + * $Id: stringutils.h,v 1.5 1997/09/07 04:55:32 momjian Exp $ * *------------------------------------------------------------------------- */ @@ -27,10 +27,11 @@ /* removes whitespaces from the left, right and both sides of a string */ /* MODIFIES the string passed in and returns the head of it */ -extern char *rightTrim(char *s); +extern char *rightTrim(char *s); #ifdef STRINGUTILS_TEST -extern void testStringUtils(); +extern void testStringUtils(); + #endif #ifndef NULL_STR @@ -41,4 +42,4 @@ extern void testStringUtils(); #define NULL 0 #endif -#endif /* STRINGUTILS_H */ +#endif /* STRINGUTILS_H */ |