#include "btree_gist.h"
PG_FUNCTION_INFO_V1(btree_decompress);
-Datum btree_decompress(PG_FUNCTION_ARGS);
+Datum btree_decompress(PG_FUNCTION_ARGS);
/*
** GiST DeCompress methods
extern GIST_SPLITVEC *btree_picksplit(bytea *entryvec, GIST_SPLITVEC *v,
BINARY_UNION bu, CMPFUNC cmp);
-
NDBOX *cube_in(char *str);
NDBOX *cube(text *str);
char *cube_out(NDBOX * cube);
-NDBOX *cube_f8(double *);
-NDBOX *cube_f8_f8(double *, double *);
-NDBOX *cube_c_f8(NDBOX *, double *);
-NDBOX *cube_c_f8_f8(NDBOX *, double *, double *);
-int4 cube_dim(NDBOX * a);
+NDBOX *cube_f8(double *);
+NDBOX *cube_f8_f8(double *, double *);
+NDBOX *cube_c_f8(NDBOX *, double *);
+NDBOX *cube_c_f8_f8(NDBOX *, double *, double *);
+int4 cube_dim(NDBOX * a);
double *cube_ll_coord(NDBOX * a, int4 n);
double *cube_ur_coord(NDBOX * a, int4 n);
bool equal = true;
int dim = cube->dim;
int i;
- int ndig;
+ int ndig;
initStringInfo(&buf);
* Get the number of digits to display.
*/
ndig = DBL_DIG + extra_float_digits;
- if (ndig < 1) ndig = 1;
+ if (ndig < 1)
+ ndig = 1;
/*
* while printing the first (LL) corner, check if it is equal to the
j,
k;
- if (n > CUBE_MAX_DIM) n = CUBE_MAX_DIM;
+ if (n > CUBE_MAX_DIM)
+ n = CUBE_MAX_DIM;
if (*r > 0 && n > 0)
dim = n;
if (a->dim > dim)
cube_f8(double *x1)
{
NDBOX *result;
- int size;
+ int size;
+
size = offsetof(NDBOX, x[0]) + sizeof(double) * 2;
result = (NDBOX *) palloc(size);
memset(result, 0, size);
result->size = size;
result->dim = 1;
- result->x[0] = *x1;
- result->x[1] = *x1;
+ result->x[0] = *x1;
+ result->x[1] = *x1;
return result;
}
cube_f8_f8(double *x1, double *x2)
{
NDBOX *result;
- int size;
+ int size;
+
size = offsetof(NDBOX, x[0]) + sizeof(double) * 2;
result = (NDBOX *) palloc(size);
memset(result, 0, size);
result->size = size;
result->dim = 1;
- result->x[0] = *x1;
- result->x[1] = *x2;
+ result->x[0] = *x1;
+ result->x[1] = *x2;
return result;
}
/* Add a dimension to an existing cube with the same values for the new
coordinate */
NDBOX *
-cube_c_f8(NDBOX *c, double *x1)
+cube_c_f8(NDBOX * c, double *x1)
{
NDBOX *result;
- int size;
- int i;
- size = offsetof(NDBOX, x[0]) + sizeof(double) * (c->dim + 1) * 2;
+ int size;
+ int i;
+
+ size = offsetof(NDBOX, x[0]) + sizeof(double) * (c->dim + 1) *2;
result = (NDBOX *) palloc(size);
memset(result, 0, size);
result->size = size;
result->dim = c->dim + 1;
- for (i = 0; i < c->dim; i++) {
- result->x[i] = c->x[i];
- result->x[result->dim + i] = c->x[c->dim + i];
- }
- result->x[result->dim - 1] = *x1;
- result->x[2 * result->dim - 1] = *x1;
+ for (i = 0; i < c->dim; i++)
+ {
+ result->x[i] = c->x[i];
+ result->x[result->dim + i] = c->x[c->dim + i];
+ }
+ result->x[result->dim - 1] = *x1;
+ result->x[2 * result->dim - 1] = *x1;
return result;
}
/* Add a dimension to an existing cube */
NDBOX *
-cube_c_f8_f8(NDBOX *c, double *x1, double *x2)
+cube_c_f8_f8(NDBOX * c, double *x1, double *x2)
{
NDBOX *result;
- int size;
- int i;
- size = offsetof(NDBOX, x[0]) + sizeof(double) * (c->dim + 1) * 2;
+ int size;
+ int i;
+
+ size = offsetof(NDBOX, x[0]) + sizeof(double) * (c->dim + 1) *2;
result = (NDBOX *) palloc(size);
memset(result, 0, size);
result->size = size;
result->dim = c->dim + 1;
- for (i = 0; i < c->dim; i++) {
- result->x[i] = c->x[i];
- result->x[result->dim + i] = c->x[c->dim + i];
- }
- result->x[result->dim - 1] = *x1;
- result->x[2 * result->dim - 1] = *x2;
+ for (i = 0; i < c->dim; i++)
+ {
+ result->x[i] = c->x[i];
+ result->x[result->dim + i] = c->x[c->dim + i];
+ }
+ result->x[result->dim - 1] = *x1;
+ result->x[2 * result->dim - 1] = *x2;
return result;
}
if (result == DBF_VALID)
{
query[0] = '\0';
- j = 0; /* counter for fields in the output */
+ j = 0; /* counter for fields in the output */
for (h = 0; h < dbh->db_nfields; h++)
{
- if (!strlen(fields[h].db_name)) /* When the new fieldname is empty, the field is skipped */
- {
+ if (!strlen(fields[h].db_name)) /* When the new fieldname
+ * is empty, the field is
+ * skipped */
continue;
- }
else
- {
j++;
- }
if (j > 1) /* not for the first field! */
strcat(query, "\t"); /* COPY statement field
typedef struct remoteConn
{
- PGconn *con; /* Hold the remote connection */
- bool remoteTrFlag; /* Indicates whether or not a transaction
- * on remote database is in progress*/
-} remoteConn;
+ PGconn *con; /* Hold the remote connection */
+ bool remoteTrFlag; /* Indicates whether or not a transaction
+ * on remote database is in progress */
+} remoteConn;
/*
* Internal declarations
*/
static remoteConn *getConnectionByName(const char *name);
static HTAB *createConnHash(void);
-static void createNewConnection(const char *name,remoteConn *con);
+static void createNewConnection(const char *name, remoteConn * con);
static void deleteConnection(const char *name);
static char **get_pkey_attnames(Oid relid, int16 *numatts);
static char *get_sql_insert(Oid relid, int16 *pkattnums, int16 pknumatts, char **src_pkattvals, char **tgt_pkattvals);
static char *generate_relation_name(Oid relid);
/* Global */
-List *res_id = NIL;
-int res_id_index = 0;
-PGconn *persistent_conn = NULL;
-static HTAB *remoteConnHash=NULL;
+List *res_id = NIL;
+int res_id_index = 0;
+PGconn *persistent_conn = NULL;
+static HTAB *remoteConnHash = NULL;
-/*
+/*
Following is list that holds multiple remote connections.
Calling convention of each dblink function changes to accept
-connection name as the first parameter. The connection list is
+connection name as the first parameter. The connection list is
much like ecpg e.g. a mapping between a name and a PGconn object.
*/
{
char name[NAMEDATALEN];
remoteConn *rcon;
-} remoteConnHashEnt;
+} remoteConnHashEnt;
/* initial number of connection hashes */
#define NUMCONN 16
PGconn *conn = NULL;
remoteConn *rcon = NULL;
- if(PG_NARGS()==2)
+ if (PG_NARGS() == 2)
{
connstr = GET_STR(PG_GETARG_TEXT_P(1));
connname = GET_STR(PG_GETARG_TEXT_P(0));
}
- else if(PG_NARGS()==1)
+ else if (PG_NARGS() == 1)
connstr = GET_STR(PG_GETARG_TEXT_P(0));
oldcontext = MemoryContextSwitchTo(TopMemoryContext);
- if(connname)
- rcon=(remoteConn *) palloc(sizeof(remoteConn));
+ if (connname)
+ rcon = (remoteConn *) palloc(sizeof(remoteConn));
conn = PQconnectdb(connstr);
MemoryContextSwitchTo(oldcontext);
{
msg = pstrdup(PQerrorMessage(conn));
PQfinish(conn);
- if(rcon)
+ if (rcon)
pfree(rcon);
ereport(ERROR,
- (errcode(ERRCODE_SQLCLIENT_UNABLE_TO_ESTABLISH_SQLCONNECTION),
- errmsg("could not establish connection"),
- errdetail("%s", msg)));
+ (errcode(ERRCODE_SQLCLIENT_UNABLE_TO_ESTABLISH_SQLCONNECTION),
+ errmsg("could not establish connection"),
+ errdetail("%s", msg)));
}
- if(connname)
+ if (connname)
{
rcon->con = conn;
createNewConnection(connname, rcon);
remoteConn *rcon = NULL;
PGconn *conn = NULL;
- if (PG_NARGS() ==1 )
+ if (PG_NARGS() == 1)
{
conname = GET_STR(PG_GETARG_TEXT_P(0));
rcon = getConnectionByName(conname);
StringInfo str = makeStringInfo();
remoteConn *rcon = NULL;
- if(PG_NARGS() == 2)
+ if (PG_NARGS() == 2)
{
curname = GET_STR(PG_GETARG_TEXT_P(0));
sql = GET_STR(PG_GETARG_TEXT_P(1));
conn = persistent_conn;
}
- else if(PG_NARGS() == 3)
+ else if (PG_NARGS() == 3)
{
conname = GET_STR(PG_GETARG_TEXT_P(0));
curname = GET_STR(PG_GETARG_TEXT_P(1));
curname = GET_STR(PG_GETARG_TEXT_P(0));
conn = persistent_conn;
}
- else if (PG_NARGS()==2)
+ else if (PG_NARGS() == 2)
{
conname = GET_STR(PG_GETARG_TEXT_P(0));
curname = GET_STR(PG_GETARG_TEXT_P(1));
rcon = getConnectionByName(conname);
- if(rcon)
+ if (rcon)
conn = rcon->con;
}
PGresult *res = NULL;
MemoryContext oldcontext;
char *conname = NULL;
- remoteConn *rcon=NULL;
+ remoteConn *rcon = NULL;
/* stuff done only on the first call of the function */
if (SRF_IS_FIRSTCALL())
howmany = PG_GETARG_INT32(2);
rcon = getConnectionByName(conname);
- if(rcon)
+ if (rcon)
conn = rcon->con;
}
else if (PG_NARGS() == 2)
conn = persistent_conn;
}
- if(!conn)
+ if (!conn)
DBLINK_CONN_NOT_AVAIL;
/* create a function context for cross-call persistence */
if (!res ||
(PQresultStatus(res) != PGRES_COMMAND_OK &&
PQresultStatus(res) != PGRES_TUPLES_OK))
- {
DBLINK_RES_ERROR("sql error");
- }
else if (PQresultStatus(res) == PGRES_COMMAND_OK)
{
/* cursor does not exist - closed already or bad name */
char *connstr = NULL;
char *sql = NULL;
char *conname = NULL;
- remoteConn *rcon=NULL;
+ remoteConn *rcon = NULL;
/* create a function context for cross-call persistence */
funcctx = SRF_FIRSTCALL_INIT();
/* shouldn't happen */
elog(ERROR, "wrong number of arguments");
- if(!conn)
+ if (!conn)
DBLINK_CONN_NOT_AVAIL;
res = PQexec(conn, sql);
TEXTOID, -1, 0, false);
/*
- * and save a copy of the command status string to return
- * as our result tuple
+ * and save a copy of the command status string to return as
+ * our result tuple
*/
sql_cmd_status = PQcmdStatus(res);
funcctx->max_calls = 1;
char *connstr = NULL;
char *sql = NULL;
char *conname = NULL;
- remoteConn *rcon=NULL;
+ remoteConn *rcon = NULL;
bool freeconn = true;
if (PG_NARGS() == 2)
/* shouldn't happen */
elog(ERROR, "wrong number of arguments");
- if(!conn)
+ if (!conn)
DBLINK_CONN_NOT_AVAIL;
res = PQexec(conn, sql);
TEXTOID, -1, 0, false);
/*
- * and save a copy of the command status string to return as
- * our result tuple
+ * and save a copy of the command status string to return as our
+ * result tuple
*/
sql_cmd_status = GET_TEXT(PQcmdStatus(res));
}
else
ereport(ERROR,
- (errcode(ERRCODE_S_R_E_PROHIBITED_SQL_STATEMENT_ATTEMPTED),
- errmsg("statement returning results not allowed")));
+ (errcode(ERRCODE_S_R_E_PROHIBITED_SQL_STATEMENT_ATTEMPTED),
+ errmsg("statement returning results not allowed")));
PQclear(res);
(errcode(ERRCODE_UNDEFINED_TABLE),
errmsg("relation \"%s\" does not exist",
GET_STR(PG_GETARG_TEXT_P(0)))));
+
/*
* need a tuple descriptor representing one INT and one TEXT
* column
if (src_nitems != pknumatts)
ereport(ERROR,
(errcode(ERRCODE_ARRAY_SUBSCRIPT_ERROR),
- errmsg("source key array length must match number of key " \
- "attributes")));
+ errmsg("source key array length must match number of key " \
+ "attributes")));
/*
* get array of pointers to c-strings from the input source array
if (tgt_nitems != pknumatts)
ereport(ERROR,
(errcode(ERRCODE_ARRAY_SUBSCRIPT_ERROR),
- errmsg("target key array length must match number of key " \
- "attributes")));
+ errmsg("target key array length must match number of key " \
+ "attributes")));
/*
* get array of pointers to c-strings from the input target array
if (tgt_nitems != pknumatts)
ereport(ERROR,
(errcode(ERRCODE_ARRAY_SUBSCRIPT_ERROR),
- errmsg("target key array length must match number of key " \
- "attributes")));
+ errmsg("target key array length must match number of key " \
+ "attributes")));
/*
* get array of pointers to c-strings from the input target array
if (src_nitems != pknumatts)
ereport(ERROR,
(errcode(ERRCODE_ARRAY_SUBSCRIPT_ERROR),
- errmsg("source key array length must match number of key " \
- "attributes")));
+ errmsg("source key array length must match number of key " \
+ "attributes")));
/*
* get array of pointers to c-strings from the input source array
if (tgt_nitems != pknumatts)
ereport(ERROR,
(errcode(ERRCODE_ARRAY_SUBSCRIPT_ERROR),
- errmsg("target key array length must match number of key " \
- "attributes")));
+ errmsg("target key array length must match number of key " \
+ "attributes")));
/*
* get array of pointers to c-strings from the input target array
ereport(ERROR,
(errcode(ERRCODE_MOST_SPECIFIC_TYPE_MISMATCH),
errmsg("field size mismatch"),
- errdetail("Size of remote field \"%s\" does not match " \
- "size of local type \"%s\".", attname,
- format_type_with_typemod(atttypid,
- atttypmod))));
+ errdetail("Size of remote field \"%s\" does not match " \
+ "size of local type \"%s\".", attname,
+ format_type_with_typemod(atttypid,
+ atttypmod))));
attdim = 0;
attisset = false;
static remoteConn *
getConnectionByName(const char *name)
{
- remoteConnHashEnt *hentry;
- char key[NAMEDATALEN];
+ remoteConnHashEnt *hentry;
+ char key[NAMEDATALEN];
- if(!remoteConnHash)
- remoteConnHash=createConnHash();
+ if (!remoteConnHash)
+ remoteConnHash = createConnHash();
MemSet(key, 0, NAMEDATALEN);
snprintf(key, NAMEDATALEN - 1, "%s", name);
- hentry = (remoteConnHashEnt*) hash_search(remoteConnHash,
- key, HASH_FIND, NULL);
+ hentry = (remoteConnHashEnt *) hash_search(remoteConnHash,
+ key, HASH_FIND, NULL);
- if(hentry)
- return(hentry->rcon);
+ if (hentry)
+ return (hentry->rcon);
- return(NULL);
+ return (NULL);
}
static HTAB *
createConnHash(void)
{
- HASHCTL ctl;
- HTAB *ptr;
+ HASHCTL ctl;
+ HTAB *ptr;
ctl.keysize = NAMEDATALEN;
ctl.entrysize = sizeof(remoteConnHashEnt);
- ptr=hash_create("Remote Con hash", NUMCONN, &ctl, HASH_ELEM);
+ ptr = hash_create("Remote Con hash", NUMCONN, &ctl, HASH_ELEM);
- if(!ptr)
+ if (!ptr)
ereport(ERROR,
(errcode(ERRCODE_OUT_OF_MEMORY),
errmsg("out of memory")));
- return(ptr);
+ return (ptr);
}
static void
-createNewConnection(const char *name, remoteConn *con)
+createNewConnection(const char *name, remoteConn * con)
{
- remoteConnHashEnt *hentry;
- bool found;
- char key[NAMEDATALEN];
+ remoteConnHashEnt *hentry;
+ bool found;
+ char key[NAMEDATALEN];
- if(!remoteConnHash)
+ if (!remoteConnHash)
remoteConnHash = createConnHash();
MemSet(key, 0, NAMEDATALEN);
hentry = (remoteConnHashEnt *) hash_search(remoteConnHash, key,
HASH_ENTER, &found);
- if(!hentry)
+ if (!hentry)
ereport(ERROR,
(errcode(ERRCODE_OUT_OF_MEMORY),
errmsg("out of memory")));
- if(found)
+ if (found)
ereport(ERROR,
(errcode(ERRCODE_DUPLICATE_OBJECT),
errmsg("duplicate connection name")));
static void
deleteConnection(const char *name)
{
- remoteConnHashEnt *hentry;
- bool found;
- char key[NAMEDATALEN];
+ remoteConnHashEnt *hentry;
+ bool found;
+ char key[NAMEDATALEN];
- if(!remoteConnHash)
- remoteConnHash=createConnHash();
+ if (!remoteConnHash)
+ remoteConnHash = createConnHash();
MemSet(key, 0, NAMEDATALEN);
snprintf(key, NAMEDATALEN - 1, "%s", name);
hentry = (remoteConnHashEnt *) hash_search(remoteConnHash,
key, HASH_REMOVE, &found);
- if(!hentry)
+ if (!hentry)
ereport(ERROR,
(errcode(ERRCODE_UNDEFINED_OBJECT),
errmsg("undefined connection name")));
/****************************************************************************
* pending.c
- * $Id: pending.c,v 1.12 2003/07/24 17:52:20 tgl Exp $
+ * $Id: pending.c,v 1.13 2003/08/04 00:43:10 momjian Exp $
*
* This file contains a trigger for Postgresql-7.x to record changes to tables
* to a pending table for mirroring.
*
* (c) 2001-2002 Navtech Systems Support Inc.
- * ALL RIGHTS RESERVED
+ * ALL RIGHTS RESERVED
*
* Permission to use, copy, modify, and distribute this software and its
* documentation for any purpose, without fee, and without a written agreement
HeapTuple retTuple = NULL;
char *tblname;
char op = 0;
- char *schemaname;
+ char *schemaname;
char *fullyqualtblname;
+
if (fcinfo->context != NULL)
{
tblname = SPI_getrelname(trigdata->tg_relation);
#ifndef NOSCHEMAS
schemaname = get_namespace_name(RelationGetNamespace(trigdata->tg_relation));
- fullyqualtblname = SPI_palloc(strlen(tblname) +
- strlen(schemaname) + 6);
- sprintf(fullyqualtblname,"\"%s\".\"%s\"",
- schemaname,tblname);
+ fullyqualtblname = SPI_palloc(strlen(tblname) +
+ strlen(schemaname) + 6);
+ sprintf(fullyqualtblname, "\"%s\".\"%s\"",
+ schemaname, tblname);
#else
fullyqualtblname = SPI_palloc(strlen(tblname) + 3);
- sprintf(fullyqualtblname,"\"%s\"",tblname);
+ sprintf(fullyqualtblname, "\"%s\"", tblname);
#endif
tupdesc = trigdata->tg_relation->rd_att;
if (TRIGGER_FIRED_BY_UPDATE(trigdata->tg_event))
int iResult = 0;
HeapTuple tCurTuple;
- //Points the current tuple(before or after)
- Datum saPlanData[4];
+ /* Points the current tuple(before or after) */
+ Datum saPlanData[4];
Oid taPlanArgTypes[3] = {NAMEOID, CHAROID, INT4OID};
void *vpPlan;
if (cpKeyData == NULL)
ereport(ERROR,
(errcode(ERRCODE_UNDEFINED_OBJECT),
- /* cpTableName already contains quotes... */
+ /* cpTableName already contains quotes... */
errmsg("there is no PRIMARY KEY for table %s",
cpTableName)));
}
else
{
- sprintf(cpFormatedPtr," ");
+ sprintf(cpFormatedPtr, " ");
iUsedDataBlock++;
cpFormatedPtr++;
continue;
if (tpPKeys != NULL)
SPI_pfree(tpPKeys);
#if defined DEBUG_OUTPUT
- elog(NOTICE, "returning DataBlockSize:%d iUsedDataBlock:%d",iDataBlockSize,
- iUsedDataBlock);
+ elog(NOTICE, "returning DataBlockSize:%d iUsedDataBlock:%d", iDataBlockSize,
+ iUsedDataBlock);
#endif
memset(cpDataBlock + iUsedDataBlock, 0, iDataBlockSize - iUsedDataBlock);
if (!OidIsValid(dbid))
ereport(ERROR,
(errcode(ERRCODE_UNDEFINED_DATABASE),
- errmsg("database \"%s\" does not exist", NameStr(*dbname))));
+ errmsg("database \"%s\" does not exist", NameStr(*dbname))));
dbpath = GetDatabasePath(dbid);
/* Earth's radius is in statute miles. */
-const double EARTH_RADIUS = 3958.747716;
-const double TWO_PI = 2.0 * M_PI;
+const double EARTH_RADIUS = 3958.747716;
+const double TWO_PI = 2.0 * M_PI;
double *geo_distance(Point *pt1, Point *pt2);
if (longdiff > M_PI)
longdiff = TWO_PI - longdiff;
- sino = sqrt(sin(fabs(lat1-lat2)/2.)*sin(fabs(lat1-lat2)/2.) +
- cos(lat1) * cos(lat2) * sin(longdiff/2.)*sin(longdiff/2.));
- if (sino > 1.) sino = 1.;
- *resultp = 2. * EARTH_RADIUS * asin(sino);
+ sino = sqrt(sin(fabs(lat1 - lat2) / 2.) * sin(fabs(lat1 - lat2) / 2.) +
+ cos(lat1) * cos(lat2) * sin(longdiff / 2.) * sin(longdiff / 2.));
+ if (sino > 1.)
+ sino = 1.;
+ *resultp = 2. * EARTH_RADIUS * asin(sino);
return resultp;
}
*
* Copyright 2002 by PostgreSQL Global Development Group
*
- * $Header: /cvsroot/pgsql/contrib/findoidjoins/Attic/findoidjoins.c,v 1.20 2003/05/14 03:25:56 tgl Exp $
+ * $Header: /cvsroot/pgsql/contrib/findoidjoins/Attic/findoidjoins.c,v 1.21 2003/08/04 00:43:10 momjian Exp $
*/
#include "postgres_fe.h"
int
main(int argc, char **argv)
{
- PGconn *conn;
- PQExpBufferData sql;
- PGresult *res;
- PGresult *pkrel_res;
- PGresult *fkrel_res;
- char *fk_relname;
- char *fk_nspname;
- char *fk_attname;
- char *pk_relname;
- char *pk_nspname;
- int fk, pk; /* loop counters */
+ PGconn *conn;
+ PQExpBufferData sql;
+ PGresult *res;
+ PGresult *pkrel_res;
+ PGresult *fkrel_res;
+ char *fk_relname;
+ char *fk_nspname;
+ char *fk_attname;
+ char *pk_relname;
+ char *pk_nspname;
+ int fk,
+ pk; /* loop counters */
if (argc != 2)
{
fprintf(stderr, "Usage: %s database\n", argv[0]);
exit(EXIT_FAILURE);
- }
+ }
initPQExpBuffer(&sql);
resetPQExpBuffer(&sql);
appendPQExpBuffer(&sql, "%s",
- "SET search_path = public;"
- "SELECT c.relname, (SELECT nspname FROM "
- "pg_catalog.pg_namespace n WHERE n.oid = c.relnamespace) AS nspname "
- "FROM pg_catalog.pg_class c "
- "WHERE c.relkind = 'r' "
- "AND c.relhasoids "
- "ORDER BY nspname, c.relname"
+ "SET search_path = public;"
+ "SELECT c.relname, (SELECT nspname FROM "
+ "pg_catalog.pg_namespace n WHERE n.oid = c.relnamespace) AS nspname "
+ "FROM pg_catalog.pg_class c "
+ "WHERE c.relkind = 'r' "
+ "AND c.relhasoids "
+ "ORDER BY nspname, c.relname"
);
res = PQexec(conn, sql.data);
resetPQExpBuffer(&sql);
appendPQExpBuffer(&sql, "%s",
- "SELECT c.relname, "
- "(SELECT nspname FROM pg_catalog.pg_namespace n WHERE n.oid = c.relnamespace) AS nspname, "
- "a.attname "
- "FROM pg_catalog.pg_class c, pg_catalog.pg_attribute a "
- "WHERE a.attnum > 0 AND c.relkind = 'r' "
- "AND a.attrelid = c.oid "
- "AND a.atttypid IN ('pg_catalog.oid'::regtype, "
- " 'pg_catalog.regclass'::regtype, "
- " 'pg_catalog.regoper'::regtype, "
- " 'pg_catalog.regoperator'::regtype, "
- " 'pg_catalog.regproc'::regtype, "
- " 'pg_catalog.regprocedure'::regtype, "
- " 'pg_catalog.regtype'::regtype) "
- "ORDER BY nspname, c.relname, a.attnum"
+ "SELECT c.relname, "
+ "(SELECT nspname FROM pg_catalog.pg_namespace n WHERE n.oid = c.relnamespace) AS nspname, "
+ "a.attname "
+ "FROM pg_catalog.pg_class c, pg_catalog.pg_attribute a "
+ "WHERE a.attnum > 0 AND c.relkind = 'r' "
+ "AND a.attrelid = c.oid "
+ "AND a.atttypid IN ('pg_catalog.oid'::regtype, "
+ " 'pg_catalog.regclass'::regtype, "
+ " 'pg_catalog.regoper'::regtype, "
+ " 'pg_catalog.regoperator'::regtype, "
+ " 'pg_catalog.regproc'::regtype, "
+ " 'pg_catalog.regprocedure'::regtype, "
+ " 'pg_catalog.regtype'::regtype) "
+ "ORDER BY nspname, c.relname, a.attnum"
);
res = PQexec(conn, sql.data);
fkrel_res = res;
/*
- * For each column and each relation-having-OIDs, look to see if
- * the column contains any values matching entries in the relation.
+ * For each column and each relation-having-OIDs, look to see if the
+ * column contains any values matching entries in the relation.
*/
for (fk = 0; fk < PQntuples(fkrel_res); fk++)
resetPQExpBuffer(&sql);
appendPQExpBuffer(&sql,
- "SELECT 1 "
- "FROM \"%s\".\"%s\" t1, "
- "\"%s\".\"%s\" t2 "
- "WHERE t1.\"%s\"::pg_catalog.oid = t2.oid "
- "LIMIT 1",
- fk_nspname, fk_relname, pk_nspname, pk_relname, fk_attname);
+ "SELECT 1 "
+ "FROM \"%s\".\"%s\" t1, "
+ "\"%s\".\"%s\" t2 "
+ "WHERE t1.\"%s\"::pg_catalog.oid = t2.oid "
+ "LIMIT 1",
+ fk_nspname, fk_relname, pk_nspname, pk_relname, fk_attname);
res = PQexec(conn, sql.data);
if (!res || PQresultStatus(res) != PGRES_TUPLES_OK)
ereport(ERROR,
(errcode(ERRCODE_UNDEFINED_COLUMN),
errmsg("column \"%s\" of \"%s\" does not exist",
- args[i + 1], indexname)));
+ args[i + 1], indexname)));
/* Get the char* representation of the column */
column = SPI_getvalue(rettuple, tupdesc, colnum);
ret = SPI_execp(*(plan->splan), values, NULL, 0);
if (ret != SPI_OK_INSERT)
ereport(ERROR,
- (errcode(ERRCODE_TRIGGERED_ACTION_EXCEPTION),
- errmsg("error executing insert")));
+ (errcode(ERRCODE_TRIGGERED_ACTION_EXCEPTION),
+ errmsg("error executing insert")));
}
pfree(buff);
pfree(data);
ereport(ERROR,
(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
errmsg("argument exceeds max length: %d",
- MAX_LEVENSHTEIN_STRLEN)));
+ MAX_LEVENSHTEIN_STRLEN)));
/*
* If either rows or cols is 0, the answer is the other value. This
ereport(ERROR,
(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
errmsg("argument exceeds max length: %d",
- MAX_METAPHONE_STRLEN)));
+ MAX_METAPHONE_STRLEN)));
if (!(str_i_len > 0))
ereport(ERROR,
ereport(ERROR,
(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
errmsg("output length exceeds max length: %d",
- MAX_METAPHONE_STRLEN)));
+ MAX_METAPHONE_STRLEN)));
if (!(reqlen > 0))
ereport(ERROR,
/* use current transaction context */
pnew = palloc(cb);
+
/*
- * Fix up the fields in the new structure, so Postgres
- * understands
+ * Fix up the fields in the new structure, so Postgres understands
*/
memcpy(pnew, p, cb);
pnew->a.size = cb;
if (!rsi || !IsA(rsi, ReturnSetInfo))
ereport(ERROR,
(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
- errmsg("int_enum called in context that cannot accept a set")));
+ errmsg("int_enum called in context that cannot accept a set")));
if (!p)
{
*/
typedef struct
{
- int4 len;
- int4 flag;
- char data[1];
-} GISTTYPE;
+ int4 len;
+ int4 flag;
+ char data[1];
+} GISTTYPE;
-#define ALLISTRUE 0x04
+#define ALLISTRUE 0x04
-#define ISALLTRUE(x) ( ((GISTTYPE*)x)->flag & ALLISTRUE )
+#define ISALLTRUE(x) ( ((GISTTYPE*)x)->flag & ALLISTRUE )
-#define GTHDRSIZE ( sizeof(int4)*2 )
+#define GTHDRSIZE ( sizeof(int4)*2 )
#define CALCGTSIZE(flag) ( GTHDRSIZE+(((flag) & ALLISTRUE) ? 0 : SIGLEN) )
-#define GETSIGN(x) ( (BITVECP)( (char*)x+GTHDRSIZE ) )
+#define GETSIGN(x) ( (BITVECP)( (char*)x+GTHDRSIZE ) )
/*
** types for functions
/*
** useful function
*/
-bool isort(int4 *a, const int len);
-ArrayType *new_intArrayType(int num);
-ArrayType *copy_intArrayType(ArrayType *a);
-ArrayType *resize_intArrayType(ArrayType *a, int num);
-int internal_size(int *a, int len);
-ArrayType *_int_unique(ArrayType *a);
-int32 intarray_match_first(ArrayType *a, int32 elem);
-ArrayType *intarray_add_elem(ArrayType *a, int32 elem);
-ArrayType *intarray_concat_arrays(ArrayType *a, ArrayType *b);
-ArrayType *int_to_intset(int32 elem);
-bool inner_int_overlap(ArrayType *a, ArrayType *b);
-bool inner_int_contains(ArrayType *a, ArrayType *b);
-ArrayType * inner_int_union(ArrayType *a, ArrayType *b);
-ArrayType * inner_int_inter(ArrayType *a, ArrayType *b);
-void rt__int_size(ArrayType *a, float *size);
-void gensign(BITVEC sign, int *a, int len);
+bool isort(int4 *a, const int len);
+ArrayType *new_intArrayType(int num);
+ArrayType *copy_intArrayType(ArrayType *a);
+ArrayType *resize_intArrayType(ArrayType *a, int num);
+int internal_size(int *a, int len);
+ArrayType *_int_unique(ArrayType *a);
+int32 intarray_match_first(ArrayType *a, int32 elem);
+ArrayType *intarray_add_elem(ArrayType *a, int32 elem);
+ArrayType *intarray_concat_arrays(ArrayType *a, ArrayType *b);
+ArrayType *int_to_intset(int32 elem);
+bool inner_int_overlap(ArrayType *a, ArrayType *b);
+bool inner_int_contains(ArrayType *a, ArrayType *b);
+ArrayType *inner_int_union(ArrayType *a, ArrayType *b);
+ArrayType *inner_int_inter(ArrayType *a, ArrayType *b);
+void rt__int_size(ArrayType *a, float *size);
+void gensign(BITVEC sign, int *a, int len);
/*****************************************************************************
#define COMPUTESIZE(size) ( HDRSIZEQT + size * sizeof(ITEM) )
#define GETQUERY(x) (ITEM*)( (char*)(x)+HDRSIZEQT )
-bool signconsistent(QUERYTYPE * query, BITVEC sign, bool calcnot);
-bool execconsistent(QUERYTYPE * query, ArrayType *array, bool calcnot);
-
-
+bool signconsistent(QUERYTYPE * query, BITVEC sign, bool calcnot);
+bool execconsistent(QUERYTYPE * query, ArrayType *array, bool calcnot);
-int compASC(const void *a, const void *b);
-int compDESC(const void *a, const void *b);
-#define QSORT(a, direction) \
-if (ARRNELEMS(a) > 1) \
- qsort((void*)ARRPTR(a), ARRNELEMS(a),sizeof(int4), \
- (direction) ? compASC : compDESC )
+int compASC(const void *a, const void *b);
+int compDESC(const void *a, const void *b);
+#define QSORT(a, direction) \
+if (ARRNELEMS(a) > 1) \
+ qsort((void*)ARRPTR(a), ARRNELEMS(a),sizeof(int4), \
+ (direction) ? compASC : compDESC )
GETQUERY(query) + query->size - 1,
(void *) sign, calcnot,
checkcondition_bit
- );
+ );
}
bool
boolop,
PG_GETARG_DATUM(1),
PG_GETARG_DATUM(0)
- );
+ );
}
Datum
PG_RETURN_POINTER(res);
}
-
}
Datum
-g_int_union(PG_FUNCTION_ARGS) {
- bytea *entryvec = (bytea *) PG_GETARG_POINTER(0);
- int *size = (int *) PG_GETARG_POINTER(1);
- int4 i,len = (VARSIZE(entryvec) - VARHDRSZ) / sizeof(GISTENTRY);
- ArrayType *res;
- int totlen=0,*ptr;
+g_int_union(PG_FUNCTION_ARGS)
+{
+ bytea *entryvec = (bytea *) PG_GETARG_POINTER(0);
+ int *size = (int *) PG_GETARG_POINTER(1);
+ int4 i,
+ len = (VARSIZE(entryvec) - VARHDRSZ) / sizeof(GISTENTRY);
+ ArrayType *res;
+ int totlen = 0,
+ *ptr;
for (i = 0; i < len; i++)
- totlen+=ARRNELEMS( GETENTRY(entryvec,i) );
+ totlen += ARRNELEMS(GETENTRY(entryvec, i));
- res=new_intArrayType(totlen);
- ptr=ARRPTR(res);
+ res = new_intArrayType(totlen);
+ ptr = ARRPTR(res);
- for (i = 0; i < len; i++) {
- memcpy(ptr, ARRPTR( GETENTRY(entryvec,i) ), ARRNELEMS( GETENTRY(entryvec,i) )*sizeof(int4) );
- ptr+=ARRNELEMS( GETENTRY(entryvec,i) );
+ for (i = 0; i < len; i++)
+ {
+ memcpy(ptr, ARRPTR(GETENTRY(entryvec, i)), ARRNELEMS(GETENTRY(entryvec, i)) * sizeof(int4));
+ ptr += ARRNELEMS(GETENTRY(entryvec, i));
}
- QSORT(res,1);
- res=_int_unique(res);
- *size = VARSIZE(res);
+ QSORT(res, 1);
+ res = _int_unique(res);
+ *size = VARSIZE(res);
PG_RETURN_POINTER(res);
}
** The GiST Penalty method for _intments
*/
Datum
-g_int_penalty(PG_FUNCTION_ARGS) {
- GISTENTRY *origentry = (GISTENTRY *) PG_GETARG_POINTER(0);
- GISTENTRY *newentry = (GISTENTRY *) PG_GETARG_POINTER(1);
- float *result = (float *) PG_GETARG_POINTER(2);
+g_int_penalty(PG_FUNCTION_ARGS)
+{
+ GISTENTRY *origentry = (GISTENTRY *) PG_GETARG_POINTER(0);
+ GISTENTRY *newentry = (GISTENTRY *) PG_GETARG_POINTER(1);
+ float *result = (float *) PG_GETARG_POINTER(2);
ArrayType *ud;
float tmp1,
tmp2;
ud = inner_int_union((ArrayType *) DatumGetPointer(origentry->key),
- (ArrayType *) DatumGetPointer(newentry->key));
+ (ArrayType *) DatumGetPointer(newentry->key));
rt__int_size(ud, &tmp1);
rt__int_size((ArrayType *) DatumGetPointer(origentry->key), &tmp2);
*result = tmp1 - tmp2;
pfree(ud);
- PG_RETURN_POINTER (result);
+ PG_RETURN_POINTER(result);
}
** We use Guttman's poly time split algorithm
*/
Datum
-g_int_picksplit(PG_FUNCTION_ARGS) {
- bytea *entryvec = (bytea *) PG_GETARG_POINTER(0);
+g_int_picksplit(PG_FUNCTION_ARGS)
+{
+ bytea *entryvec = (bytea *) PG_GETARG_POINTER(0);
GIST_SPLITVEC *v = (GIST_SPLITVEC *) PG_GETARG_POINTER(1);
OffsetNumber i,
j;
PG_RETURN_POINTER(v);
}
-
*data;
int num = ARRNELEMS(r);
- if ( num<2 )
+ if (num < 2)
return r;
data = tmp = dr = ARRPTR(r);
return 0;
return (*(int4 *) a < *(int4 *) b) ? 1 : -1;
}
-
if (ARR_NDIM(la) != 1)
ereport(ERROR,
- (errcode(ERRCODE_ARRAY_SUBSCRIPT_ERROR),
- errmsg("array must be one-dimensional")));
+ (errcode(ERRCODE_ARRAY_SUBSCRIPT_ERROR),
+ errmsg("array must be one-dimensional")));
if (found)
*found = NULL;
Datum
_lt_q_regex(PG_FUNCTION_ARGS)
{
- ArrayType *_tree = PG_GETARG_ARRAYTYPE_P(0);
- ArrayType *_query = PG_GETARG_ARRAYTYPE_P(1);
- lquery *query = (lquery *) ARR_DATA_PTR(_query);
- bool res = false;
- int num = ArrayGetNItems(ARR_NDIM(_query), ARR_DIMS(_query));
-
- if (ARR_NDIM(_query) != 1)
- ereport(ERROR,
+ ArrayType *_tree = PG_GETARG_ARRAYTYPE_P(0);
+ ArrayType *_query = PG_GETARG_ARRAYTYPE_P(1);
+ lquery *query = (lquery *) ARR_DATA_PTR(_query);
+ bool res = false;
+ int num = ArrayGetNItems(ARR_NDIM(_query), ARR_DIMS(_query));
+
+ if (ARR_NDIM(_query) != 1)
+ ereport(ERROR,
(errcode(ERRCODE_ARRAY_SUBSCRIPT_ERROR),
errmsg("array must be one-dimensional")));
- while (num > 0) {
- if ( array_iterator(_tree, ltq_regex, (void*)query, NULL) ) {
- res = true;
- break;
- }
- num--;
- query = (lquery*)NEXTVAL(query);
- }
-
- PG_FREE_IF_COPY(_tree, 0);
- PG_FREE_IF_COPY(_query, 1);
- PG_RETURN_BOOL(res);
+ while (num > 0)
+ {
+ if (array_iterator(_tree, ltq_regex, (void *) query, NULL))
+ {
+ res = true;
+ break;
+ }
+ num--;
+ query = (lquery *) NEXTVAL(query);
+ }
+
+ PG_FREE_IF_COPY(_tree, 0);
+ PG_FREE_IF_COPY(_query, 1);
+ PG_RETURN_BOOL(res);
}
Datum
_lt_q_rregex(PG_FUNCTION_ARGS)
{
- PG_RETURN_DATUM(DirectFunctionCall2(_lt_q_regex,
- PG_GETARG_DATUM(1),
- PG_GETARG_DATUM(0)
- ));
+ PG_RETURN_DATUM(DirectFunctionCall2(_lt_q_regex,
+ PG_GETARG_DATUM(1),
+ PG_GETARG_DATUM(0)
+ ));
}
}
bool
-compare_subnode(ltree_level * t, char *qn, int len, int (*cmpptr) (const char *, const char *, size_t), bool anyend)
+ compare_subnode(ltree_level * t, char *qn, int len, int (*cmpptr) (const char *, const char *, size_t), bool anyend)
{
char *endt = t->name + t->len;
char *endq = qn + len;
}
*/
-static struct {
- bool muse;
- uint32 high_pos;
-} SomeStack = {false,0,};
+static struct
+{
+ bool muse;
+ uint32 high_pos;
+} SomeStack =
+
+{
+ false, 0,
+};
static bool
checkCond(lquery_level * curq, int query_numlevel, ltree_level * curt, int tree_numlevel, FieldNot * ptr)
lquery_level *prevq = NULL;
ltree_level *prevt = NULL;
- if ( SomeStack.muse ) {
+ if (SomeStack.muse)
+ {
high_pos = SomeStack.high_pos;
qlen--;
prevq = curq;
curt = LEVEL_NEXT(curt);
tlen--;
cur_tpos++;
- if ( isok && prevq && prevq->numvar==0 && tlen>0 && cur_tpos <= high_pos ) {
- FieldNot tmpptr;
- if ( ptr )
- memcpy(&tmpptr,ptr,sizeof(FieldNot));
- SomeStack.high_pos = high_pos-cur_tpos;
+ if (isok && prevq && prevq->numvar == 0 && tlen > 0 && cur_tpos <= high_pos)
+ {
+ FieldNot tmpptr;
+
+ if (ptr)
+ memcpy(&tmpptr, ptr, sizeof(FieldNot));
+ SomeStack.high_pos = high_pos - cur_tpos;
SomeStack.muse = true;
- if ( checkCond(prevq, qlen+1, curt, tlen, (ptr) ? &tmpptr : NULL) )
+ if (checkCond(prevq, qlen + 1, curt, tlen, (ptr) ? &tmpptr : NULL))
return true;
}
if (!isok && ptr)
lt_q_regex(PG_FUNCTION_ARGS)
{
ltree *tree = PG_GETARG_LTREE(0);
- ArrayType *_query = PG_GETARG_ARRAYTYPE_P(1);
- lquery *query = (lquery *) ARR_DATA_PTR(_query);
- bool res = false;
- int num = ArrayGetNItems(ARR_NDIM(_query), ARR_DIMS(_query));
+ ArrayType *_query = PG_GETARG_ARRAYTYPE_P(1);
+ lquery *query = (lquery *) ARR_DATA_PTR(_query);
+ bool res = false;
+ int num = ArrayGetNItems(ARR_NDIM(_query), ARR_DIMS(_query));
- if (ARR_NDIM(_query) != 1)
- ereport(ERROR,
+ if (ARR_NDIM(_query) != 1)
+ ereport(ERROR,
(errcode(ERRCODE_ARRAY_SUBSCRIPT_ERROR),
errmsg("array must be one-dimensional")));
- while (num > 0) {
+ while (num > 0)
+ {
if (DatumGetBool(DirectFunctionCall2(ltq_regex,
- PointerGetDatum(tree), PointerGetDatum(query)))) {
+ PointerGetDatum(tree), PointerGetDatum(query))))
+ {
res = true;
break;
PG_GETARG_DATUM(0)
));
}
-
-
#define UNCHAR ereport(ERROR, \
(errcode(ERRCODE_SYNTAX_ERROR), \
- errmsg("syntax error at position %d near \"%c\"", \
+ errmsg("syntax error at position %d near \"%c\"", \
(int)(ptr-buf), *ptr)));
(errcode(ERRCODE_NAME_TOO_LONG),
errmsg("name of level is too long"),
errdetail("name length is %d, must " \
- "be < 256, in position %d",
- lptr->len, (int) (lptr->start - buf))));
+ "be < 256, in position %d",
+ lptr->len, (int) (lptr->start - buf))));
totallen += MAXALIGN(lptr->len + LEVEL_HDRSIZE);
lptr++;
(errcode(ERRCODE_NAME_TOO_LONG),
errmsg("name of level is too long"),
errdetail("name length is %d, must " \
- "be < 256, in position %d",
- lptr->len, (int) (lptr->start - buf))));
+ "be < 256, in position %d",
+ lptr->len, (int) (lptr->start - buf))));
totallen += MAXALIGN(lptr->len + LEVEL_HDRSIZE);
lptr++;
(errcode(ERRCODE_NAME_TOO_LONG),
errmsg("name of level is too long"),
errdetail("name length is %d, must " \
- "be < 256, in position %d",
- lptr->len, (int) (lptr->start - buf))));
+ "be < 256, in position %d",
+ lptr->len, (int) (lptr->start - buf))));
state = LQPRS_WAITVAR;
}
(errcode(ERRCODE_NAME_TOO_LONG),
errmsg("name of level is too long"),
errdetail("name length is %d, must " \
- "be < 256, in position %d",
- lptr->len, (int) (lptr->start - buf))));
+ "be < 256, in position %d",
+ lptr->len, (int) (lptr->start - buf))));
state = LQPRS_WAITLEVEL;
curqlevel = NEXTLEV(curqlevel);
(errcode(ERRCODE_NAME_TOO_LONG),
errmsg("name of level is too long"),
errdetail("name length is %d, must " \
- "be < 256, in position %d",
- lptr->len, (int) (lptr->start - buf))));
+ "be < 256, in position %d",
+ lptr->len, (int) (lptr->start - buf))));
}
else if (state == LQPRS_WAITOPEN)
curqlevel->high = 0xffff;
(errcode(ERRCODE_SYNTAX_ERROR),
errmsg("syntax error"),
errdetail("Low limit(%d) is greater than upper(%d).",
- curqlevel->low, curqlevel->high)));
+ curqlevel->low, curqlevel->high)));
curqlevel = NEXTLEV(curqlevel);
}
ltree_cmp(PG_FUNCTION_ARGS)
{
RUNCMP
- PG_RETURN_INT32(res);
+ PG_RETURN_INT32(res);
}
Datum
ltree_lt(PG_FUNCTION_ARGS)
{
RUNCMP
- PG_RETURN_BOOL((res < 0) ? true : false);
+ PG_RETURN_BOOL((res < 0) ? true : false);
}
Datum
ltree_le(PG_FUNCTION_ARGS)
{
RUNCMP
- PG_RETURN_BOOL((res <= 0) ? true : false);
+ PG_RETURN_BOOL((res <= 0) ? true : false);
}
Datum
ltree_eq(PG_FUNCTION_ARGS)
{
RUNCMP
- PG_RETURN_BOOL((res == 0) ? true : false);
+ PG_RETURN_BOOL((res == 0) ? true : false);
}
Datum
ltree_ge(PG_FUNCTION_ARGS)
{
RUNCMP
- PG_RETURN_BOOL((res >= 0) ? true : false);
+ PG_RETURN_BOOL((res >= 0) ? true : false);
}
Datum
ltree_gt(PG_FUNCTION_ARGS)
{
RUNCMP
- PG_RETURN_BOOL((res > 0) ? true : false);
+ PG_RETURN_BOOL((res > 0) ? true : false);
}
Datum
ltree_ne(PG_FUNCTION_ARGS)
{
RUNCMP
- PG_RETURN_BOOL((res != 0) ? true : false);
+ PG_RETURN_BOOL((res != 0) ? true : false);
}
Datum
{
ltree *a = PG_GETARG_LTREE(0);
ltree *b = PG_GETARG_LTREE(1);
- int start=(fcinfo->nargs == 3) ? PG_GETARG_INT32(2) : 0;
- int i,j;
- ltree_level *startptr, *aptr, *bptr;
- bool found=false;
-
- if ( start < 0 ) {
- if ( -start >= a->numlevel )
- start=0;
- else
- start = (int)(a->numlevel)+start;
+ int start = (fcinfo->nargs == 3) ? PG_GETARG_INT32(2) : 0;
+ int i,
+ j;
+ ltree_level *startptr,
+ *aptr,
+ *bptr;
+ bool found = false;
+
+ if (start < 0)
+ {
+ if (-start >= a->numlevel)
+ start = 0;
+ else
+ start = (int) (a->numlevel) + start;
}
- if ( a->numlevel - start < b->numlevel || a->numlevel==0 || b->numlevel==0 ) {
+ if (a->numlevel - start < b->numlevel || a->numlevel == 0 || b->numlevel == 0)
+ {
PG_FREE_IF_COPY(a, 0);
PG_FREE_IF_COPY(b, 1);
PG_RETURN_INT32(-1);
}
- startptr=LTREE_FIRST(a);
- for(i=0; i<=a->numlevel-b->numlevel; i++) {
- if ( i>=start ) {
- aptr=startptr;
- bptr=LTREE_FIRST(b);
- for(j=0;j<b->numlevel;j++) {
- if ( !(aptr->len==bptr->len && strncmp(aptr->name,bptr->name, aptr->len)==0) )
- break;
- aptr=LEVEL_NEXT(aptr);
- bptr=LEVEL_NEXT(bptr);
+ startptr = LTREE_FIRST(a);
+ for (i = 0; i <= a->numlevel - b->numlevel; i++)
+ {
+ if (i >= start)
+ {
+ aptr = startptr;
+ bptr = LTREE_FIRST(b);
+ for (j = 0; j < b->numlevel; j++)
+ {
+ if (!(aptr->len == bptr->len && strncmp(aptr->name, bptr->name, aptr->len) == 0))
+ break;
+ aptr = LEVEL_NEXT(aptr);
+ bptr = LEVEL_NEXT(bptr);
}
-
- if ( j==b->numlevel ) {
- found=true;
+
+ if (j == b->numlevel)
+ {
+ found = true;
break;
}
}
- startptr=LEVEL_NEXT(startptr);
+ startptr = LEVEL_NEXT(startptr);
}
-
- if ( !found )
- i=-1;
+
+ if (!found)
+ i = -1;
PG_FREE_IF_COPY(a, 0);
PG_FREE_IF_COPY(b, 1);
text2ltree(PG_FUNCTION_ARGS)
{
text *in = PG_GETARG_TEXT_P(0);
- char *s = (char *) palloc(VARSIZE(in) - VARHDRSZ + 1);
- ltree *out;
+ char *s = (char *) palloc(VARSIZE(in) - VARHDRSZ + 1);
+ ltree *out;
memcpy(s, VARDATA(in), VARSIZE(in) - VARHDRSZ);
s[VARSIZE(in) - VARHDRSZ] = '\0';
out = (ltree *) DatumGetPointer(DirectFunctionCall1(
- ltree_in,
- PointerGetDatum(s)
- ));
+ ltree_in,
+ PointerGetDatum(s)
+ ));
pfree(s);
- PG_FREE_IF_COPY(in,0);
+ PG_FREE_IF_COPY(in, 0);
PG_RETURN_POINTER(out);
}
ltree2text(PG_FUNCTION_ARGS)
{
ltree *in = PG_GETARG_LTREE(0);
- char *ptr;
- int i;
+ char *ptr;
+ int i;
ltree_level *curlevel;
- text *out;
-
- out=(text*)palloc(in->len+VARHDRSZ);
- ptr = VARDATA(out);
+ text *out;
+
+ out = (text *) palloc(in->len + VARHDRSZ);
+ ptr = VARDATA(out);
curlevel = LTREE_FIRST(in);
- for (i = 0; i < in->numlevel; i++) {
- if (i != 0) {
+ for (i = 0; i < in->numlevel; i++)
+ {
+ if (i != 0)
+ {
*ptr = '.';
ptr++;
}
ptr += curlevel->len;
curlevel = LEVEL_NEXT(curlevel);
}
-
- VARATT_SIZEP(out) = VARHDRSZ + (ptr-VARDATA(out));
+
+ VARATT_SIZEP(out) = VARHDRSZ + (ptr - VARDATA(out));
PG_FREE_IF_COPY(in, 0);
-
+
PG_RETURN_POINTER(out);
}
-
-
-
-
snprintf(todo, 1024, "select relfilenode,relname from pg_class order by relname");
else
snprintf(todo, 1024, "select relfilenode,relname from pg_class "
- "where relkind not in ('v','s', 'c') and "
- "relname not like 'pg_%%' order by relname");
+ "where relkind not in ('v','s', 'c') and "
+ "relname not like 'pg_%%' order by relname");
sql_exec(conn, todo, 0);
}
#include "pg_autovacuum.h"
#define TIMEBUFF 256
-FILE *LOGOUTPUT;
-char timebuffer[TIMEBUFF];
-char logbuffer[4096];
+FILE *LOGOUTPUT;
+char timebuffer[TIMEBUFF];
+char logbuffer[4096];
void
-log_entry (const char *logentry)
+log_entry(const char *logentry)
{
- time_t curtime;
- struct tm *loctime;
- curtime = time (NULL);
- loctime = localtime (&curtime);
- strftime (timebuffer, TIMEBUFF, "%Y-%m-%d %r", loctime); /* cbb - %F is not always available */
- fprintf (LOGOUTPUT, "[%s] %s\n", timebuffer, logentry);
+ time_t curtime;
+ struct tm *loctime;
+
+ curtime = time(NULL);
+ loctime = localtime(&curtime);
+ strftime(timebuffer, TIMEBUFF, "%Y-%m-%d %r", loctime); /* cbb - %F is not
+ * always available */
+ fprintf(LOGOUTPUT, "[%s] %s\n", timebuffer, logentry);
}
/* Function used to detatch the pg_autovacuum daemon from the tty and go into the background *
-* This code is mostly ripped directly from pm_dameonize in postmaster.c *
-* with unneeded code removed. */
-void daemonize ()
+* This code is mostly ripped directly from pm_dameonize in postmaster.c *
+* with unneeded code removed. */
+void
+daemonize()
{
- pid_t pid;
-
- pid = fork();
- if (pid == (pid_t) -1)
- {
- log_entry("Error: cannot disassociate from controlling TTY");
- fflush(LOGOUTPUT);
- _exit(1);
- }
- else if (pid)
- { /* parent */
- /* Parent should just exit, without doing any atexit cleanup */
- _exit(0);
- }
+ pid_t pid;
+
+ pid = fork();
+ if (pid == (pid_t) -1)
+ {
+ log_entry("Error: cannot disassociate from controlling TTY");
+ fflush(LOGOUTPUT);
+ _exit(1);
+ }
+ else if (pid)
+ { /* parent */
+ /* Parent should just exit, without doing any atexit cleanup */
+ _exit(0);
+ }
/* GH: If there's no setsid(), we hopefully don't need silent mode.
* Until there's a better solution. */
#ifdef HAVE_SETSID
- if (setsid() < 0)
- {
- log_entry("Error: cannot disassociate from controlling TTY");
- fflush(LOGOUTPUT);
- _exit(1);
- }
+ if (setsid() < 0)
+ {
+ log_entry("Error: cannot disassociate from controlling TTY");
+ fflush(LOGOUTPUT);
+ _exit(1);
+ }
#endif
}
/* Create and return tbl_info struct with initialized to values from row or res */
tbl_info *
-init_table_info (PGresult * res, int row, db_info *dbi)
+init_table_info(PGresult *res, int row, db_info * dbi)
{
- tbl_info *new_tbl = (tbl_info *) malloc (sizeof (tbl_info));
-
- if (!new_tbl) {
- log_entry ("init_table_info: Cannot get memory");
- fflush (LOGOUTPUT);
- return NULL;
- }
-
- if (NULL == res)
- return NULL;
-
- new_tbl->dbi = dbi; /* set pointer to db */
-
- new_tbl->schema_name = (char *)
- malloc (strlen (PQgetvalue (res, row, PQfnumber (res, "schemaname"))) + 1);
- if (!new_tbl->schema_name) {
- log_entry ("init_table_info: malloc failed on new_tbl->schema_name");
- fflush (LOGOUTPUT);
- return NULL;
- }
- strcpy (new_tbl->schema_name,
- PQgetvalue (res, row, PQfnumber (res, "schemaname")));
-
- new_tbl->table_name = (char *)
- malloc (strlen (PQgetvalue (res, row, PQfnumber (res, "relname"))) +
- strlen (new_tbl->schema_name) + 2);
- if (!new_tbl->table_name) {
- log_entry ("init_table_info: malloc failed on new_tbl->table_name");
- fflush (LOGOUTPUT);
- return NULL;
- }
- strcpy (new_tbl->table_name, new_tbl->schema_name);
- strcat (new_tbl->table_name, ".");
- strcat (new_tbl->table_name, PQgetvalue (res, row, PQfnumber (res, "relname")));
-
- new_tbl->CountAtLastAnalyze =
- (atol (PQgetvalue (res, row, PQfnumber (res, "n_tup_ins"))) +
- atol (PQgetvalue (res, row, PQfnumber (res, "n_tup_upd"))));
- new_tbl->curr_analyze_count = new_tbl->CountAtLastAnalyze;
-
- new_tbl->CountAtLastVacuum =
- (atol (PQgetvalue (res, row, PQfnumber (res, "n_tup_del"))) +
- atol (PQgetvalue (res, row, PQfnumber (res, "n_tup_upd"))));
- new_tbl->curr_vacuum_count = new_tbl->CountAtLastVacuum;
-
- new_tbl->relfilenode = atoi (PQgetvalue (res, row, PQfnumber (res, "relfilenode")));
- new_tbl->reltuples = atoi (PQgetvalue (res, row, PQfnumber (res, "reltuples")));
- new_tbl->relpages = atoi (PQgetvalue (res, row, PQfnumber (res, "relpages")));
-
- new_tbl->analyze_threshold =
- args->analyze_base_threshold + args->analyze_scaling_factor * new_tbl->reltuples;
- new_tbl->vacuum_threshold =
- args->vacuum_base_threshold + args->vacuum_scaling_factor * new_tbl->reltuples;
-
- if (args->debug >= 2) {
- print_table_info (new_tbl);
- }
-
- return new_tbl;
+ tbl_info *new_tbl = (tbl_info *) malloc(sizeof(tbl_info));
+
+ if (!new_tbl)
+ {
+ log_entry("init_table_info: Cannot get memory");
+ fflush(LOGOUTPUT);
+ return NULL;
+ }
+
+ if (NULL == res)
+ return NULL;
+
+ new_tbl->dbi = dbi; /* set pointer to db */
+
+ new_tbl->schema_name = (char *)
+ malloc(strlen(PQgetvalue(res, row, PQfnumber(res, "schemaname"))) + 1);
+ if (!new_tbl->schema_name)
+ {
+ log_entry("init_table_info: malloc failed on new_tbl->schema_name");
+ fflush(LOGOUTPUT);
+ return NULL;
+ }
+ strcpy(new_tbl->schema_name,
+ PQgetvalue(res, row, PQfnumber(res, "schemaname")));
+
+ new_tbl->table_name = (char *)
+ malloc(strlen(PQgetvalue(res, row, PQfnumber(res, "relname"))) +
+ strlen(new_tbl->schema_name) + 2);
+ if (!new_tbl->table_name)
+ {
+ log_entry("init_table_info: malloc failed on new_tbl->table_name");
+ fflush(LOGOUTPUT);
+ return NULL;
+ }
+ strcpy(new_tbl->table_name, new_tbl->schema_name);
+ strcat(new_tbl->table_name, ".");
+ strcat(new_tbl->table_name, PQgetvalue(res, row, PQfnumber(res, "relname")));
+
+ new_tbl->CountAtLastAnalyze =
+ (atol(PQgetvalue(res, row, PQfnumber(res, "n_tup_ins"))) +
+ atol(PQgetvalue(res, row, PQfnumber(res, "n_tup_upd"))));
+ new_tbl->curr_analyze_count = new_tbl->CountAtLastAnalyze;
+
+ new_tbl->CountAtLastVacuum =
+ (atol(PQgetvalue(res, row, PQfnumber(res, "n_tup_del"))) +
+ atol(PQgetvalue(res, row, PQfnumber(res, "n_tup_upd"))));
+ new_tbl->curr_vacuum_count = new_tbl->CountAtLastVacuum;
+
+ new_tbl->relfilenode = atoi(PQgetvalue(res, row, PQfnumber(res, "relfilenode")));
+ new_tbl->reltuples = atoi(PQgetvalue(res, row, PQfnumber(res, "reltuples")));
+ new_tbl->relpages = atoi(PQgetvalue(res, row, PQfnumber(res, "relpages")));
+
+ new_tbl->analyze_threshold =
+ args->analyze_base_threshold + args->analyze_scaling_factor * new_tbl->reltuples;
+ new_tbl->vacuum_threshold =
+ args->vacuum_base_threshold + args->vacuum_scaling_factor * new_tbl->reltuples;
+
+ if (args->debug >= 2)
+ print_table_info(new_tbl);
+
+ return new_tbl;
}
/* Set thresholds = base_value + scaling_factor * reltuples
Should be called after a vacuum since vacuum updates values in pg_class */
void
-update_table_thresholds (db_info * dbi, tbl_info * tbl,int vacuum_type)
+update_table_thresholds(db_info * dbi, tbl_info * tbl, int vacuum_type)
{
- PGresult *res = NULL;
- int disconnect = 0;
- char query[128];
-
- if (NULL == dbi->conn) {
- dbi->conn = db_connect (dbi);
- disconnect = 1;
- }
-
- if (NULL != dbi->conn) {
- snprintf (query, sizeof (query), PAGES_QUERY, tbl->relfilenode);
- res = send_query (query, dbi);
- if (NULL != res) {
- tbl->reltuples =
- atoi (PQgetvalue (res, 0, PQfnumber (res, "reltuples")));
- tbl->relpages = atoi (PQgetvalue (res, 0, PQfnumber (res, "relpages")));
-
- /* update vacuum thresholds only of we just did a vacuum analyze */
- if(VACUUM_ANALYZE == vacuum_type)
- {
- tbl->vacuum_threshold =
- (args->vacuum_base_threshold + args->vacuum_scaling_factor * tbl->reltuples);
- tbl->CountAtLastVacuum = tbl->curr_vacuum_count;
- }
-
- /* update analyze thresholds */
- tbl->analyze_threshold =
- (args->analyze_base_threshold + args->analyze_scaling_factor * tbl->reltuples);
- tbl->CountAtLastAnalyze = tbl->curr_analyze_count;
-
- PQclear (res);
-
- /* If the stats collector is reporting fewer updates then we have on record
- then the stats were probably reset, so we need to reset also */
- if ((tbl->curr_analyze_count < tbl->CountAtLastAnalyze) ||
- (tbl->curr_vacuum_count < tbl->CountAtLastVacuum))
- {
- tbl->CountAtLastAnalyze = tbl->curr_analyze_count;
- tbl->CountAtLastVacuum = tbl->curr_vacuum_count;
- }
- }
- }
- if (disconnect)
- db_disconnect (dbi);
+ PGresult *res = NULL;
+ int disconnect = 0;
+ char query[128];
+
+ if (NULL == dbi->conn)
+ {
+ dbi->conn = db_connect(dbi);
+ disconnect = 1;
+ }
+
+ if (NULL != dbi->conn)
+ {
+ snprintf(query, sizeof(query), PAGES_QUERY, tbl->relfilenode);
+ res = send_query(query, dbi);
+ if (NULL != res)
+ {
+ tbl->reltuples =
+ atoi(PQgetvalue(res, 0, PQfnumber(res, "reltuples")));
+ tbl->relpages = atoi(PQgetvalue(res, 0, PQfnumber(res, "relpages")));
+
+ /*
+ * update vacuum thresholds only of we just did a vacuum
+ * analyze
+ */
+ if (VACUUM_ANALYZE == vacuum_type)
+ {
+ tbl->vacuum_threshold =
+ (args->vacuum_base_threshold + args->vacuum_scaling_factor * tbl->reltuples);
+ tbl->CountAtLastVacuum = tbl->curr_vacuum_count;
+ }
+
+ /* update analyze thresholds */
+ tbl->analyze_threshold =
+ (args->analyze_base_threshold + args->analyze_scaling_factor * tbl->reltuples);
+ tbl->CountAtLastAnalyze = tbl->curr_analyze_count;
+
+ PQclear(res);
+
+ /*
+ * If the stats collector is reporting fewer updates then we
+ * have on record then the stats were probably reset, so we
+ * need to reset also
+ */
+ if ((tbl->curr_analyze_count < tbl->CountAtLastAnalyze) ||
+ (tbl->curr_vacuum_count < tbl->CountAtLastVacuum))
+ {
+ tbl->CountAtLastAnalyze = tbl->curr_analyze_count;
+ tbl->CountAtLastVacuum = tbl->curr_vacuum_count;
+ }
+ }
+ }
+ if (disconnect)
+ db_disconnect(dbi);
}
void
-update_table_list (db_info * dbi)
+update_table_list(db_info * dbi)
{
- int disconnect = 0;
- PGresult *res = NULL;
- tbl_info *tbl = NULL;
- Dlelem *tbl_elem = DLGetHead (dbi->table_list);
- int i = 0, t = 0, found_match = 0;
-
- if (NULL == dbi->conn) {
- dbi->conn = db_connect (dbi);
- disconnect = 1;
- }
-
- if (NULL != dbi->conn) {
- /* Get a result set that has all the information
- we will need to both remove tables from the list
- that no longer exist and add tables to the list
- that are new */
- res = send_query (query_table_stats (dbi), dbi);
- t = PQntuples (res);
-
- /* First: use the tbl_list as the outer loop and
- the result set as the inner loop, this will
- determine what tables should be removed */
- while (NULL != tbl_elem) {
- tbl = ((tbl_info *) DLE_VAL (tbl_elem));
- found_match = 0;
-
- for (i = 0; i < t; i++) { /* loop through result set looking for a match */
- if (tbl->relfilenode == atoi (PQgetvalue (res, i, PQfnumber (res, "relfilenode")))) {
- found_match = 1;
- break;
- }
- }
- if (0 == found_match) { /* then we didn't find this tbl_elem in the result set */
- Dlelem *elem_to_remove = tbl_elem;
- tbl_elem = DLGetSucc (tbl_elem);
- remove_table_from_list (elem_to_remove);
- }
- else
- tbl_elem = DLGetSucc (tbl_elem);
- } /* Done removing dropped tables from the table_list */
-
- /* Then loop use result set as outer loop and
- tbl_list as the inner loop to determine
- what tables are new */
- for (i = 0; i < t; i++)
- {
- tbl_elem = DLGetHead (dbi->table_list);
- found_match = 0;
- while (NULL != tbl_elem)
- {
- tbl = ((tbl_info *) DLE_VAL (tbl_elem));
- if (tbl->relfilenode == atoi (PQgetvalue (res, i, PQfnumber (res, "relfilenode"))))
- {
- found_match = 1;
- break;
- }
- tbl_elem = DLGetSucc (tbl_elem);
- }
- if (0 == found_match) /*then we didn't find this result now in the tbl_list */
- {
- DLAddTail (dbi->table_list, DLNewElem (init_table_info (res, i, dbi)));
- if (args->debug >= 1)
- {
- sprintf (logbuffer, "added table: %s.%s", dbi->dbname,
- ((tbl_info *) DLE_VAL (DLGetTail (dbi->table_list)))->table_name);
- log_entry (logbuffer);
- }
- }
- } /* end of for loop that adds tables */
- fflush (LOGOUTPUT);
- PQclear (res);
- res = NULL;
- if (args->debug >= 3) {
- print_table_list (dbi->table_list);
- }
- if (disconnect)
- db_disconnect (dbi);
- }
+ int disconnect = 0;
+ PGresult *res = NULL;
+ tbl_info *tbl = NULL;
+ Dlelem *tbl_elem = DLGetHead(dbi->table_list);
+ int i = 0,
+ t = 0,
+ found_match = 0;
+
+ if (NULL == dbi->conn)
+ {
+ dbi->conn = db_connect(dbi);
+ disconnect = 1;
+ }
+
+ if (NULL != dbi->conn)
+ {
+ /*
+ * Get a result set that has all the information we will need to
+ * both remove tables from the list that no longer exist and add
+ * tables to the list that are new
+ */
+ res = send_query(query_table_stats(dbi), dbi);
+ t = PQntuples(res);
+
+ /*
+ * First: use the tbl_list as the outer loop and the result set as
+ * the inner loop, this will determine what tables should be
+ * removed
+ */
+ while (NULL != tbl_elem)
+ {
+ tbl = ((tbl_info *) DLE_VAL(tbl_elem));
+ found_match = 0;
+
+ for (i = 0; i < t; i++)
+ { /* loop through result set looking for a
+ * match */
+ if (tbl->relfilenode == atoi(PQgetvalue(res, i, PQfnumber(res, "relfilenode"))))
+ {
+ found_match = 1;
+ break;
+ }
+ }
+ if (0 == found_match)
+ { /* then we didn't find this tbl_elem in
+ * the result set */
+ Dlelem *elem_to_remove = tbl_elem;
+
+ tbl_elem = DLGetSucc(tbl_elem);
+ remove_table_from_list(elem_to_remove);
+ }
+ else
+ tbl_elem = DLGetSucc(tbl_elem);
+ } /* Done removing dropped tables from the
+ * table_list */
+
+ /*
+ * Then loop use result set as outer loop and tbl_list as the
+ * inner loop to determine what tables are new
+ */
+ for (i = 0; i < t; i++)
+ {
+ tbl_elem = DLGetHead(dbi->table_list);
+ found_match = 0;
+ while (NULL != tbl_elem)
+ {
+ tbl = ((tbl_info *) DLE_VAL(tbl_elem));
+ if (tbl->relfilenode == atoi(PQgetvalue(res, i, PQfnumber(res, "relfilenode"))))
+ {
+ found_match = 1;
+ break;
+ }
+ tbl_elem = DLGetSucc(tbl_elem);
+ }
+ if (0 == found_match) /* then we didn't find this result
+ * now in the tbl_list */
+ {
+ DLAddTail(dbi->table_list, DLNewElem(init_table_info(res, i, dbi)));
+ if (args->debug >= 1)
+ {
+ sprintf(logbuffer, "added table: %s.%s", dbi->dbname,
+ ((tbl_info *) DLE_VAL(DLGetTail(dbi->table_list)))->table_name);
+ log_entry(logbuffer);
+ }
+ }
+ } /* end of for loop that adds tables */
+ fflush(LOGOUTPUT);
+ PQclear(res);
+ res = NULL;
+ if (args->debug >= 3)
+ print_table_list(dbi->table_list);
+ if (disconnect)
+ db_disconnect(dbi);
+ }
}
/* Free memory, and remove the node from the list */
void
-remove_table_from_list (Dlelem * tbl_to_remove)
+remove_table_from_list(Dlelem *tbl_to_remove)
{
- tbl_info *tbl = ((tbl_info *) DLE_VAL (tbl_to_remove));
-
- if (args->debug >= 1) {
- sprintf (logbuffer, "Removing table: %s from list.", tbl->table_name);
- log_entry (logbuffer);
- fflush (LOGOUTPUT);
- }
- DLRemove (tbl_to_remove);
-
- if (tbl->schema_name) {
- free (tbl->schema_name);
- tbl->schema_name = NULL;
- }
- if (tbl->table_name) {
- free (tbl->table_name);
- tbl->table_name = NULL;
- }
- if (tbl) {
- free (tbl);
- tbl = NULL;
- }
- DLFreeElem (tbl_to_remove);
+ tbl_info *tbl = ((tbl_info *) DLE_VAL(tbl_to_remove));
+
+ if (args->debug >= 1)
+ {
+ sprintf(logbuffer, "Removing table: %s from list.", tbl->table_name);
+ log_entry(logbuffer);
+ fflush(LOGOUTPUT);
+ }
+ DLRemove(tbl_to_remove);
+
+ if (tbl->schema_name)
+ {
+ free(tbl->schema_name);
+ tbl->schema_name = NULL;
+ }
+ if (tbl->table_name)
+ {
+ free(tbl->table_name);
+ tbl->table_name = NULL;
+ }
+ if (tbl)
+ {
+ free(tbl);
+ tbl = NULL;
+ }
+ DLFreeElem(tbl_to_remove);
}
/* Free the entire table list */
void
-free_tbl_list (Dllist * tbl_list)
+free_tbl_list(Dllist *tbl_list)
{
- Dlelem *tbl_elem = DLGetHead (tbl_list);
- Dlelem *tbl_elem_to_remove = NULL;
- while (NULL != tbl_elem) {
- tbl_elem_to_remove = tbl_elem;
- tbl_elem = DLGetSucc (tbl_elem);
- remove_table_from_list (tbl_elem_to_remove);
- }
- DLFreeList (tbl_list);
+ Dlelem *tbl_elem = DLGetHead(tbl_list);
+ Dlelem *tbl_elem_to_remove = NULL;
+
+ while (NULL != tbl_elem)
+ {
+ tbl_elem_to_remove = tbl_elem;
+ tbl_elem = DLGetSucc(tbl_elem);
+ remove_table_from_list(tbl_elem_to_remove);
+ }
+ DLFreeList(tbl_list);
}
void
-print_table_list (Dllist * table_list)
+print_table_list(Dllist *table_list)
{
- Dlelem *table_elem = DLGetHead (table_list);
- while (NULL != table_elem) {
- print_table_info (((tbl_info *) DLE_VAL (table_elem)));
- table_elem = DLGetSucc (table_elem);
- }
+ Dlelem *table_elem = DLGetHead(table_list);
+
+ while (NULL != table_elem)
+ {
+ print_table_info(((tbl_info *) DLE_VAL(table_elem)));
+ table_elem = DLGetSucc(table_elem);
+ }
}
void
-print_table_info (tbl_info * tbl)
+print_table_info(tbl_info * tbl)
{
- sprintf (logbuffer, " table name: %s.%s", tbl->dbi->dbname, tbl->table_name);
- log_entry (logbuffer);
- sprintf (logbuffer, " relfilenode: %i",tbl->relfilenode);
- log_entry (logbuffer);
- sprintf (logbuffer, " reltuples: %i; relpages: %i", tbl->reltuples, tbl->relpages);
- log_entry (logbuffer);
- sprintf (logbuffer, " curr_analyze_count: %li; cur_delete_count: %li",
- tbl->curr_analyze_count, tbl->curr_vacuum_count);
- log_entry (logbuffer);
- sprintf (logbuffer, " ins_at_last_analyze: %li; del_at_last_vacuum: %li",
- tbl->CountAtLastAnalyze, tbl->CountAtLastVacuum);
- log_entry (logbuffer);
- sprintf (logbuffer, " insert_threshold: %li; delete_threshold %li",
- tbl->analyze_threshold, tbl->vacuum_threshold);
- log_entry (logbuffer);
- fflush (LOGOUTPUT);
+ sprintf(logbuffer, " table name: %s.%s", tbl->dbi->dbname, tbl->table_name);
+ log_entry(logbuffer);
+ sprintf(logbuffer, " relfilenode: %i", tbl->relfilenode);
+ log_entry(logbuffer);
+ sprintf(logbuffer, " reltuples: %i; relpages: %i", tbl->reltuples, tbl->relpages);
+ log_entry(logbuffer);
+ sprintf(logbuffer, " curr_analyze_count: %li; cur_delete_count: %li",
+ tbl->curr_analyze_count, tbl->curr_vacuum_count);
+ log_entry(logbuffer);
+ sprintf(logbuffer, " ins_at_last_analyze: %li; del_at_last_vacuum: %li",
+ tbl->CountAtLastAnalyze, tbl->CountAtLastVacuum);
+ log_entry(logbuffer);
+ sprintf(logbuffer, " insert_threshold: %li; delete_threshold %li",
+ tbl->analyze_threshold, tbl->vacuum_threshold);
+ log_entry(logbuffer);
+ fflush(LOGOUTPUT);
}
/* End of table Management Functions */
/* init_db_list() creates the db_list and initalizes template1 */
Dllist *
-init_db_list ()
+init_db_list()
{
- Dllist *db_list = DLNewList ();
- db_info *dbs = NULL;
- PGresult *res = NULL;
-
- DLAddHead (db_list, DLNewElem (init_dbinfo ((char *) "template1", 0, 0)));
- if (NULL == DLGetHead (db_list)) { /* Make sure init_dbinfo was successful */
- log_entry ("init_db_list(): Error creating db_list for db: template1.");
- fflush (LOGOUTPUT);
- return NULL;
- }
-
- /* We do this just so we can set the proper oid for the template1 database */
- dbs = ((db_info *) DLE_VAL (DLGetHead (db_list)));
- dbs->conn = db_connect (dbs);
-
- if (NULL != dbs->conn) {
- res = send_query (FROZENOID_QUERY, dbs);
- dbs->oid = atoi (PQgetvalue (res, 0, PQfnumber (res, "oid")));
- dbs->age = atoi (PQgetvalue (res, 0, PQfnumber (res, "age")));
- if (res)
- PQclear (res);
-
- if (args->debug >= 2) {
- print_db_list (db_list, 0);
- }
- }
- return db_list;
+ Dllist *db_list = DLNewList();
+ db_info *dbs = NULL;
+ PGresult *res = NULL;
+
+ DLAddHead(db_list, DLNewElem(init_dbinfo((char *) "template1", 0, 0)));
+ if (NULL == DLGetHead(db_list))
+ { /* Make sure init_dbinfo was successful */
+ log_entry("init_db_list(): Error creating db_list for db: template1.");
+ fflush(LOGOUTPUT);
+ return NULL;
+ }
+
+ /*
+ * We do this just so we can set the proper oid for the template1
+ * database
+ */
+ dbs = ((db_info *) DLE_VAL(DLGetHead(db_list)));
+ dbs->conn = db_connect(dbs);
+
+ if (NULL != dbs->conn)
+ {
+ res = send_query(FROZENOID_QUERY, dbs);
+ dbs->oid = atoi(PQgetvalue(res, 0, PQfnumber(res, "oid")));
+ dbs->age = atoi(PQgetvalue(res, 0, PQfnumber(res, "age")));
+ if (res)
+ PQclear(res);
+
+ if (args->debug >= 2)
+ print_db_list(db_list, 0);
+ }
+ return db_list;
}
/* Simple function to create an instance of the dbinfo struct
- Initalizes all the pointers and connects to the database */
+ Initalizes all the pointers and connects to the database */
db_info *
-init_dbinfo (char *dbname, int oid, int age)
+init_dbinfo(char *dbname, int oid, int age)
{
- db_info *newdbinfo = (db_info *) malloc (sizeof (db_info));
- newdbinfo->analyze_threshold = args->vacuum_base_threshold;
- newdbinfo->vacuum_threshold = args->analyze_base_threshold;
- newdbinfo->dbname = (char *) malloc (strlen (dbname) + 1);
- strcpy (newdbinfo->dbname, dbname);
- newdbinfo->username = NULL;
- if (NULL != args->user) {
- newdbinfo->username = (char *) malloc (strlen (args->user) + 1);
- strcpy (newdbinfo->username, args->user);
- }
- newdbinfo->password = NULL;
- if (NULL != args->password) {
- newdbinfo->password = (char *) malloc (strlen (args->password) + 1);
- strcpy (newdbinfo->password, args->password);
- }
- newdbinfo->oid = oid;
- newdbinfo->age = age;
- newdbinfo->table_list = DLNewList ();
- newdbinfo->conn = NULL;
-
- if (args->debug >= 2) {
- print_table_list (newdbinfo->table_list);
- }
-
- return newdbinfo;
+ db_info *newdbinfo = (db_info *) malloc(sizeof(db_info));
+
+ newdbinfo->analyze_threshold = args->vacuum_base_threshold;
+ newdbinfo->vacuum_threshold = args->analyze_base_threshold;
+ newdbinfo->dbname = (char *) malloc(strlen(dbname) + 1);
+ strcpy(newdbinfo->dbname, dbname);
+ newdbinfo->username = NULL;
+ if (NULL != args->user)
+ {
+ newdbinfo->username = (char *) malloc(strlen(args->user) + 1);
+ strcpy(newdbinfo->username, args->user);
+ }
+ newdbinfo->password = NULL;
+ if (NULL != args->password)
+ {
+ newdbinfo->password = (char *) malloc(strlen(args->password) + 1);
+ strcpy(newdbinfo->password, args->password);
+ }
+ newdbinfo->oid = oid;
+ newdbinfo->age = age;
+ newdbinfo->table_list = DLNewList();
+ newdbinfo->conn = NULL;
+
+ if (args->debug >= 2)
+ print_table_list(newdbinfo->table_list);
+
+ return newdbinfo;
}
/* Function adds and removes databases from the db_list as appropriate */
void
-update_db_list (Dllist * db_list)
+update_db_list(Dllist *db_list)
{
- int disconnect = 0;
- PGresult *res = NULL;
- Dlelem *db_elem = DLGetHead (db_list);
- db_info *dbi = NULL;
- db_info *dbi_template1 = DLE_VAL (db_elem);
- int i = 0, t = 0, found_match = 0;
-
- if (args->debug >= 2) {
- log_entry ("updating the database list");
- fflush (LOGOUTPUT);
- }
-
- if (NULL == dbi_template1->conn) {
- dbi_template1->conn = db_connect (dbi_template1);
- disconnect = 1;
- }
-
- if (NULL != dbi_template1->conn) {
- /* Get a result set that has all the information
- we will need to both remove databasews from the list
- that no longer exist and add databases to the list
- that are new */
- res = send_query (FROZENOID_QUERY2, dbi_template1);
- t = PQntuples (res);
-
- /* First: use the db_list as the outer loop and
- the result set as the inner loop, this will
- determine what databases should be removed */
- while (NULL != db_elem) {
- dbi = ((db_info *) DLE_VAL (db_elem));
- found_match = 0;
-
- for (i = 0; i < t; i++) { /* loop through result set looking for a match */
- if (dbi->oid == atoi (PQgetvalue (res, i, PQfnumber (res, "oid")))) {
- found_match = 1;
- /* update the dbi->age so that we ensure xid_wraparound won't happen */
- dbi->age = atoi (PQgetvalue (res, i, PQfnumber (res, "age")));
- break;
- }
- }
- if (0 == found_match) { /*then we didn't find this db_elem in the result set */
- Dlelem *elem_to_remove = db_elem;
- db_elem = DLGetSucc (db_elem);
- remove_db_from_list (elem_to_remove);
- }
- else
- db_elem = DLGetSucc (db_elem);
- } /* Done removing dropped databases from the table_list */
-
- /* Then loop use result set as outer loop and
- db_list as the inner loop to determine
- what databases are new */
- for (i = 0; i < t; i++)
- {
- db_elem = DLGetHead (db_list);
- found_match = 0;
- while (NULL != db_elem)
- {
- dbi = ((db_info *) DLE_VAL (db_elem));
- if (dbi->oid == atoi (PQgetvalue (res, i, PQfnumber (res, "oid"))))
- {
- found_match = 1;
- break;
- }
- db_elem = DLGetSucc (db_elem);
- }
- if (0 == found_match) /*then we didn't find this result now in the tbl_list */
- {
- DLAddTail (db_list, DLNewElem (init_dbinfo
- (PQgetvalue(res, i, PQfnumber (res, "datname")),
- atoi (PQgetvalue(res, i, PQfnumber (res, "oid"))),
- atoi (PQgetvalue(res, i, PQfnumber (res, "age"))))));
- if (args->debug >= 1)
- {
- sprintf (logbuffer, "added database: %s",((db_info *) DLE_VAL (DLGetTail (db_list)))->dbname);
- log_entry (logbuffer);
- }
- }
- } /* end of for loop that adds tables */
- fflush (LOGOUTPUT);
- PQclear (res);
- res = NULL;
- if (args->debug >= 3) {
- print_db_list (db_list, 0);
- }
- if (disconnect)
- db_disconnect (dbi_template1);
- }
+ int disconnect = 0;
+ PGresult *res = NULL;
+ Dlelem *db_elem = DLGetHead(db_list);
+ db_info *dbi = NULL;
+ db_info *dbi_template1 = DLE_VAL(db_elem);
+ int i = 0,
+ t = 0,
+ found_match = 0;
+
+ if (args->debug >= 2)
+ {
+ log_entry("updating the database list");
+ fflush(LOGOUTPUT);
+ }
+
+ if (NULL == dbi_template1->conn)
+ {
+ dbi_template1->conn = db_connect(dbi_template1);
+ disconnect = 1;
+ }
+
+ if (NULL != dbi_template1->conn)
+ {
+ /*
+ * Get a result set that has all the information we will need to
+ * both remove databasews from the list that no longer exist and
+ * add databases to the list that are new
+ */
+ res = send_query(FROZENOID_QUERY2, dbi_template1);
+ t = PQntuples(res);
+
+ /*
+ * First: use the db_list as the outer loop and the result set as
+ * the inner loop, this will determine what databases should be
+ * removed
+ */
+ while (NULL != db_elem)
+ {
+ dbi = ((db_info *) DLE_VAL(db_elem));
+ found_match = 0;
+
+ for (i = 0; i < t; i++)
+ { /* loop through result set looking for a
+ * match */
+ if (dbi->oid == atoi(PQgetvalue(res, i, PQfnumber(res, "oid"))))
+ {
+ found_match = 1;
+
+ /*
+ * update the dbi->age so that we ensure
+ * xid_wraparound won't happen
+ */
+ dbi->age = atoi(PQgetvalue(res, i, PQfnumber(res, "age")));
+ break;
+ }
+ }
+ if (0 == found_match)
+ { /* then we didn't find this db_elem in the
+ * result set */
+ Dlelem *elem_to_remove = db_elem;
+
+ db_elem = DLGetSucc(db_elem);
+ remove_db_from_list(elem_to_remove);
+ }
+ else
+ db_elem = DLGetSucc(db_elem);
+ } /* Done removing dropped databases from
+ * the table_list */
+
+ /*
+ * Then loop use result set as outer loop and db_list as the inner
+ * loop to determine what databases are new
+ */
+ for (i = 0; i < t; i++)
+ {
+ db_elem = DLGetHead(db_list);
+ found_match = 0;
+ while (NULL != db_elem)
+ {
+ dbi = ((db_info *) DLE_VAL(db_elem));
+ if (dbi->oid == atoi(PQgetvalue(res, i, PQfnumber(res, "oid"))))
+ {
+ found_match = 1;
+ break;
+ }
+ db_elem = DLGetSucc(db_elem);
+ }
+ if (0 == found_match) /* then we didn't find this result
+ * now in the tbl_list */
+ {
+ DLAddTail(db_list, DLNewElem(init_dbinfo
+ (PQgetvalue(res, i, PQfnumber(res, "datname")),
+ atoi(PQgetvalue(res, i, PQfnumber(res, "oid"))),
+ atoi(PQgetvalue(res, i, PQfnumber(res, "age"))))));
+ if (args->debug >= 1)
+ {
+ sprintf(logbuffer, "added database: %s", ((db_info *) DLE_VAL(DLGetTail(db_list)))->dbname);
+ log_entry(logbuffer);
+ }
+ }
+ } /* end of for loop that adds tables */
+ fflush(LOGOUTPUT);
+ PQclear(res);
+ res = NULL;
+ if (args->debug >= 3)
+ print_db_list(db_list, 0);
+ if (disconnect)
+ db_disconnect(dbi_template1);
+ }
}
/* xid_wraparound_check
return 1 if the database needed a database wide vacuum
*/
int
-xid_wraparound_check (db_info * dbi)
+xid_wraparound_check(db_info * dbi)
{
- /* FIXME: should probably do something better here so that we don't vacuum all the
- databases on the server at the same time. We have 500million xacts to work with so
- we should be able to spread the load of full database vacuums a bit */
- if (1500000000 < dbi->age) {
- PGresult *res = NULL;
- res = send_query ("vacuum", dbi);
- /* FIXME: Perhaps should add a check for PQ_COMMAND_OK */
- PQclear (res);
- return 1;
- }
- return 0;
+ /*
+ * FIXME: should probably do something better here so that we don't
+ * vacuum all the databases on the server at the same time. We have
+ * 500million xacts to work with so we should be able to spread the
+ * load of full database vacuums a bit
+ */
+ if (1500000000 < dbi->age)
+ {
+ PGresult *res = NULL;
+
+ res = send_query("vacuum", dbi);
+ /* FIXME: Perhaps should add a check for PQ_COMMAND_OK */
+ PQclear(res);
+ return 1;
+ }
+ return 0;
}
/* Close DB connection, free memory, and remove the node from the list */
void
-remove_db_from_list (Dlelem * db_to_remove)
+remove_db_from_list(Dlelem *db_to_remove)
{
- db_info *dbi = ((db_info *) DLE_VAL (db_to_remove));
-
- if (args->debug >= 1) {
- sprintf (logbuffer, "Removing db: %s from list.", dbi->dbname);
- log_entry (logbuffer);
- fflush (LOGOUTPUT);
- }
- DLRemove (db_to_remove);
- if (dbi->conn)
- db_disconnect (dbi);
- if (dbi->dbname) {
- free (dbi->dbname);
- dbi->dbname = NULL;
- }
- if (dbi->username) {
- free (dbi->username);
- dbi->username = NULL;
- }
- if (dbi->password) {
- free (dbi->password);
- dbi->password = NULL;
- }
- if (dbi->table_list) {
- free_tbl_list (dbi->table_list);
- dbi->table_list = NULL;
- }
- if (dbi) {
- free (dbi);
- dbi = NULL;
- }
- DLFreeElem (db_to_remove);
+ db_info *dbi = ((db_info *) DLE_VAL(db_to_remove));
+
+ if (args->debug >= 1)
+ {
+ sprintf(logbuffer, "Removing db: %s from list.", dbi->dbname);
+ log_entry(logbuffer);
+ fflush(LOGOUTPUT);
+ }
+ DLRemove(db_to_remove);
+ if (dbi->conn)
+ db_disconnect(dbi);
+ if (dbi->dbname)
+ {
+ free(dbi->dbname);
+ dbi->dbname = NULL;
+ }
+ if (dbi->username)
+ {
+ free(dbi->username);
+ dbi->username = NULL;
+ }
+ if (dbi->password)
+ {
+ free(dbi->password);
+ dbi->password = NULL;
+ }
+ if (dbi->table_list)
+ {
+ free_tbl_list(dbi->table_list);
+ dbi->table_list = NULL;
+ }
+ if (dbi)
+ {
+ free(dbi);
+ dbi = NULL;
+ }
+ DLFreeElem(db_to_remove);
}
/* Function is called before program exit to free all memory
mostly it's just to keep valgrind happy */
void
-free_db_list (Dllist * db_list)
+free_db_list(Dllist *db_list)
{
- Dlelem *db_elem = DLGetHead (db_list);
- Dlelem *db_elem_to_remove = NULL;
- while (NULL != db_elem) {
- db_elem_to_remove = db_elem;
- db_elem = DLGetSucc (db_elem);
- remove_db_from_list (db_elem_to_remove);
- db_elem_to_remove = NULL;
- }
- DLFreeList (db_list);
+ Dlelem *db_elem = DLGetHead(db_list);
+ Dlelem *db_elem_to_remove = NULL;
+
+ while (NULL != db_elem)
+ {
+ db_elem_to_remove = db_elem;
+ db_elem = DLGetSucc(db_elem);
+ remove_db_from_list(db_elem_to_remove);
+ db_elem_to_remove = NULL;
+ }
+ DLFreeList(db_list);
}
void
-print_db_list (Dllist * db_list, int print_table_lists)
+print_db_list(Dllist *db_list, int print_table_lists)
{
- Dlelem *db_elem = DLGetHead (db_list);
- while (NULL != db_elem) {
- print_db_info (((db_info *) DLE_VAL (db_elem)), print_table_lists);
- db_elem = DLGetSucc (db_elem);
- }
+ Dlelem *db_elem = DLGetHead(db_list);
+
+ while (NULL != db_elem)
+ {
+ print_db_info(((db_info *) DLE_VAL(db_elem)), print_table_lists);
+ db_elem = DLGetSucc(db_elem);
+ }
}
void
-print_db_info (db_info * dbi, int print_tbl_list)
+print_db_info(db_info * dbi, int print_tbl_list)
{
- sprintf (logbuffer, "dbname: %s Username %s Passwd %s", dbi->dbname,
- dbi->username, dbi->password);
- log_entry (logbuffer);
- sprintf (logbuffer, " oid %i InsertThresh: %i DeleteThresh: %i", dbi->oid,
- dbi->analyze_threshold, dbi->vacuum_threshold);
- log_entry (logbuffer);
- if (NULL != dbi->conn)
- log_entry (" conn is valid, we are connected");
- else
- log_entry (" conn is null, we are not connected.");
-
- fflush (LOGOUTPUT);
- if (0 < print_tbl_list)
- print_table_list (dbi->table_list);
+ sprintf(logbuffer, "dbname: %s Username %s Passwd %s", dbi->dbname,
+ dbi->username, dbi->password);
+ log_entry(logbuffer);
+ sprintf(logbuffer, " oid %i InsertThresh: %i DeleteThresh: %i", dbi->oid,
+ dbi->analyze_threshold, dbi->vacuum_threshold);
+ log_entry(logbuffer);
+ if (NULL != dbi->conn)
+ log_entry(" conn is valid, we are connected");
+ else
+ log_entry(" conn is null, we are not connected.");
+
+ fflush(LOGOUTPUT);
+ if (0 < print_tbl_list)
+ print_table_list(dbi->table_list);
}
/* End of DB List Management Function */
char *
-query_table_stats (db_info * dbi)
+query_table_stats(db_info * dbi)
{
- if (!strcmp (dbi->dbname, "template1")) /* Use template1 to monitor the system tables */
- return (char *) TABLE_STATS_ALL;
- else
- return (char *) TABLE_STATS_USER;
+ if (!strcmp(dbi->dbname, "template1")) /* Use template1 to
+ * monitor the system
+ * tables */
+ return (char *) TABLE_STATS_ALL;
+ else
+ return (char *) TABLE_STATS_USER;
}
/* Perhaps add some test to this function to make sure that the stats we need are available */
PGconn *
-db_connect (db_info * dbi)
+db_connect(db_info * dbi)
{
- PGconn *db_conn =
- PQsetdbLogin (args->host, args->port, NULL, NULL, dbi->dbname,
- dbi->username, dbi->password);
-
- if (CONNECTION_OK != PQstatus (db_conn)) {
- sprintf (logbuffer, "Failed connection to database %s with error: %s.",
- dbi->dbname, PQerrorMessage (db_conn));
- log_entry (logbuffer);
- fflush (LOGOUTPUT);
- PQfinish (db_conn);
- db_conn = NULL;
- }
- return db_conn;
-} /* end of db_connect() */
+ PGconn *db_conn =
+ PQsetdbLogin(args->host, args->port, NULL, NULL, dbi->dbname,
+ dbi->username, dbi->password);
+
+ if (CONNECTION_OK != PQstatus(db_conn))
+ {
+ sprintf(logbuffer, "Failed connection to database %s with error: %s.",
+ dbi->dbname, PQerrorMessage(db_conn));
+ log_entry(logbuffer);
+ fflush(LOGOUTPUT);
+ PQfinish(db_conn);
+ db_conn = NULL;
+ }
+ return db_conn;
+} /* end of db_connect() */
void
-db_disconnect (db_info * dbi)
+db_disconnect(db_info * dbi)
{
- if (NULL != dbi->conn) {
- PQfinish (dbi->conn);
- dbi->conn = NULL;
- }
+ if (NULL != dbi->conn)
+ {
+ PQfinish(dbi->conn);
+ dbi->conn = NULL;
+ }
}
int
-check_stats_enabled (db_info * dbi)
+check_stats_enabled(db_info * dbi)
{
- PGresult *res = NULL;
- int ret = 0;
- res = send_query ("show stats_row_level", dbi);
- ret =
- strcmp ("on", PQgetvalue (res, 0, PQfnumber (res, "stats_row_level")));
- PQclear (res);
- return ret;
+ PGresult *res = NULL;
+ int ret = 0;
+
+ res = send_query("show stats_row_level", dbi);
+ ret =
+ strcmp("on", PQgetvalue(res, 0, PQfnumber(res, "stats_row_level")));
+ PQclear(res);
+ return ret;
}
PGresult *
-send_query (const char *query, db_info * dbi)
+send_query(const char *query, db_info * dbi)
{
- PGresult *res;
-
- if (NULL == dbi->conn)
- return NULL;
-
- res = PQexec (dbi->conn, query);
-
- if (!res) {
- sprintf (logbuffer,
- "Fatal error occured while sending query (%s) to database %s",
- query, dbi->dbname);
- log_entry (logbuffer);
- sprintf (logbuffer, "The error is [%s]", PQresultErrorMessage (res));
- log_entry (logbuffer);
- fflush (LOGOUTPUT);
- return NULL;
- }
- if (PQresultStatus (res) != PGRES_TUPLES_OK
- && PQresultStatus (res) != PGRES_COMMAND_OK) {
- sprintf (logbuffer,
- "Can not refresh statistics information from the database %s.",
- dbi->dbname);
- log_entry (logbuffer);
- sprintf (logbuffer, "The error is [%s]", PQresultErrorMessage (res));
- log_entry (logbuffer);
- fflush (LOGOUTPUT);
- PQclear (res);
- return NULL;
- }
- return res;
-} /* End of send_query() */
+ PGresult *res;
+
+ if (NULL == dbi->conn)
+ return NULL;
+
+ res = PQexec(dbi->conn, query);
+
+ if (!res)
+ {
+ sprintf(logbuffer,
+ "Fatal error occured while sending query (%s) to database %s",
+ query, dbi->dbname);
+ log_entry(logbuffer);
+ sprintf(logbuffer, "The error is [%s]", PQresultErrorMessage(res));
+ log_entry(logbuffer);
+ fflush(LOGOUTPUT);
+ return NULL;
+ }
+ if (PQresultStatus(res) != PGRES_TUPLES_OK
+ && PQresultStatus(res) != PGRES_COMMAND_OK)
+ {
+ sprintf(logbuffer,
+ "Can not refresh statistics information from the database %s.",
+ dbi->dbname);
+ log_entry(logbuffer);
+ sprintf(logbuffer, "The error is [%s]", PQresultErrorMessage(res));
+ log_entry(logbuffer);
+ fflush(LOGOUTPUT);
+ PQclear(res);
+ return NULL;
+ }
+ return res;
+} /* End of send_query() */
void
-free_cmd_args ()
+free_cmd_args()
{
- if (NULL != args) {
- if (NULL != args->user)
- free (args->user);
- if (NULL != args->user)
- free (args->password);
- free (args);
- }
+ if (NULL != args)
+ {
+ if (NULL != args->user)
+ free(args->user);
+ if (NULL != args->user)
+ free(args->password);
+ free(args);
+ }
}
cmd_args *
-get_cmd_args (int argc, char *argv[])
+get_cmd_args(int argc, char *argv[])
{
- int c;
- args = (cmd_args *) malloc (sizeof (cmd_args));
- args->sleep_base_value = SLEEPBASEVALUE;
- args->sleep_scaling_factor = SLEEPSCALINGFACTOR;
- args->vacuum_base_threshold = VACBASETHRESHOLD;
- args->vacuum_scaling_factor = VACSCALINGFACTOR;
- args->analyze_base_threshold = -1;
- args->analyze_scaling_factor = -1;
- args->debug = AUTOVACUUM_DEBUG;
- args->daemonize = 0;
-
- /* Fixme: Should add some sanity checking such as positive integer values etc */
- while (-1 != (c = getopt (argc, argv, "s:S:v:V:a:A:d:U:P:H:L:p:hD"))) {
- switch (c) {
- case 's':
- args->sleep_base_value = atoi (optarg);
- break;
- case 'S':
- args->sleep_scaling_factor = atof (optarg);
- break;
- case 'v':
- args->vacuum_base_threshold = atoi (optarg);
- break;
- case 'V':
- args->vacuum_scaling_factor = atof (optarg);
- break;
- case 'a':
- args->analyze_base_threshold = atoi (optarg);
- break;
- case 'A':
- args->analyze_scaling_factor = atof (optarg);
- break;
- case 'D':
- args->daemonize++;
- break;
- case 'd':
- args->debug = atoi (optarg);
- break;
- case 'U':
- args->user = optarg;
- break;
- case 'P':
- args->password = optarg;
- break;
- case 'H':
- args->host = optarg;
- break;
- case 'L':
- args->logfile = optarg;
- break;
- case 'p':
- args->port = optarg;
- break;
- case 'h':
- usage();
- exit (0);
- default:
- /* It's here that we know that things are invalid...
- It is not forcibly an error to call usage */
- fprintf (stderr, "Error: Invalid Command Line Options.\n");
- usage();
- exit (1);
- break;
- }
- /* if values for insert thresholds are not specified,
- then they default to 1/2 of the delete values */
- if(-1 == args->analyze_base_threshold)
- args->analyze_base_threshold = args->vacuum_base_threshold / 2;
- if(-1 == args->analyze_scaling_factor)
- args->analyze_scaling_factor = args->vacuum_scaling_factor / 2;
- }
- return args;
+ int c;
+
+ args = (cmd_args *) malloc(sizeof(cmd_args));
+ args->sleep_base_value = SLEEPBASEVALUE;
+ args->sleep_scaling_factor = SLEEPSCALINGFACTOR;
+ args->vacuum_base_threshold = VACBASETHRESHOLD;
+ args->vacuum_scaling_factor = VACSCALINGFACTOR;
+ args->analyze_base_threshold = -1;
+ args->analyze_scaling_factor = -1;
+ args->debug = AUTOVACUUM_DEBUG;
+ args->daemonize = 0;
+
+ /*
+ * Fixme: Should add some sanity checking such as positive integer
+ * values etc
+ */
+ while (-1 != (c = getopt(argc, argv, "s:S:v:V:a:A:d:U:P:H:L:p:hD")))
+ {
+ switch (c)
+ {
+ case 's':
+ args->sleep_base_value = atoi(optarg);
+ break;
+ case 'S':
+ args->sleep_scaling_factor = atof(optarg);
+ break;
+ case 'v':
+ args->vacuum_base_threshold = atoi(optarg);
+ break;
+ case 'V':
+ args->vacuum_scaling_factor = atof(optarg);
+ break;
+ case 'a':
+ args->analyze_base_threshold = atoi(optarg);
+ break;
+ case 'A':
+ args->analyze_scaling_factor = atof(optarg);
+ break;
+ case 'D':
+ args->daemonize++;
+ break;
+ case 'd':
+ args->debug = atoi(optarg);
+ break;
+ case 'U':
+ args->user = optarg;
+ break;
+ case 'P':
+ args->password = optarg;
+ break;
+ case 'H':
+ args->host = optarg;
+ break;
+ case 'L':
+ args->logfile = optarg;
+ break;
+ case 'p':
+ args->port = optarg;
+ break;
+ case 'h':
+ usage();
+ exit(0);
+ default:
+
+ /*
+ * It's here that we know that things are invalid... It is
+ * not forcibly an error to call usage
+ */
+ fprintf(stderr, "Error: Invalid Command Line Options.\n");
+ usage();
+ exit(1);
+ break;
+ }
+
+ /*
+ * if values for insert thresholds are not specified, then they
+ * default to 1/2 of the delete values
+ */
+ if (-1 == args->analyze_base_threshold)
+ args->analyze_base_threshold = args->vacuum_base_threshold / 2;
+ if (-1 == args->analyze_scaling_factor)
+ args->analyze_scaling_factor = args->vacuum_scaling_factor / 2;
+ }
+ return args;
}
-void usage()
+void
+usage()
{
- int i=0;
- float f=0;
- fprintf (stderr, "usage: pg_autovacuum \n");
- fprintf (stderr, " [-D] Daemonize (Detach from tty and run in the background)\n");
- i=AUTOVACUUM_DEBUG;
- fprintf (stderr, " [-d] debug (debug level=0,1,2,3; default=%i)\n",i);
-
- i=SLEEPBASEVALUE;
- fprintf (stderr, " [-s] sleep base value (default=%i)\n",i);
- f=SLEEPSCALINGFACTOR;
- fprintf (stderr, " [-S] sleep scaling factor (default=%f)\n",f);
-
- i=VACBASETHRESHOLD;
- fprintf (stderr, " [-v] vacuum base threshold (default=%i)\n",i);
- f=VACSCALINGFACTOR;
- fprintf (stderr, " [-V] vacuum scaling factor (default=%f)\n",f);
- i=i/2;
- fprintf (stderr, " [-a] analyze base threshold (default=%i)\n",i);
- f=f/2;
- fprintf (stderr, " [-A] analyze scaling factor (default=%f)\n",f);
-
- fprintf (stderr, " [-L] logfile (default=none)\n");
-
- fprintf (stderr, " [-U] username (libpq default)\n");
- fprintf (stderr, " [-P] password (libpq default)\n");
- fprintf (stderr, " [-H] host (libpq default)\n");
- fprintf (stderr, " [-p] port (libpq default)\n");
-
- fprintf (stderr, " [-h] help (Show this output)\n");
+ int i = 0;
+ float f = 0;
+
+ fprintf(stderr, "usage: pg_autovacuum \n");
+ fprintf(stderr, " [-D] Daemonize (Detach from tty and run in the background)\n");
+ i = AUTOVACUUM_DEBUG;
+ fprintf(stderr, " [-d] debug (debug level=0,1,2,3; default=%i)\n", i);
+
+ i = SLEEPBASEVALUE;
+ fprintf(stderr, " [-s] sleep base value (default=%i)\n", i);
+ f = SLEEPSCALINGFACTOR;
+ fprintf(stderr, " [-S] sleep scaling factor (default=%f)\n", f);
+
+ i = VACBASETHRESHOLD;
+ fprintf(stderr, " [-v] vacuum base threshold (default=%i)\n", i);
+ f = VACSCALINGFACTOR;
+ fprintf(stderr, " [-V] vacuum scaling factor (default=%f)\n", f);
+ i = i / 2;
+ fprintf(stderr, " [-a] analyze base threshold (default=%i)\n", i);
+ f = f / 2;
+ fprintf(stderr, " [-A] analyze scaling factor (default=%f)\n", f);
+
+ fprintf(stderr, " [-L] logfile (default=none)\n");
+
+ fprintf(stderr, " [-U] username (libpq default)\n");
+ fprintf(stderr, " [-P] password (libpq default)\n");
+ fprintf(stderr, " [-H] host (libpq default)\n");
+ fprintf(stderr, " [-p] port (libpq default)\n");
+
+ fprintf(stderr, " [-h] help (Show this output)\n");
}
void
-print_cmd_args ()
+print_cmd_args()
{
- sprintf (logbuffer, "Printing command_args");
- log_entry (logbuffer);
- sprintf (logbuffer, " args->host=%s", (args->host) ? args->host : "(null)");
- log_entry (logbuffer);
- sprintf (logbuffer, " args->port=%s", (args->port) ? args->port : "(null)");
- log_entry (logbuffer);
- sprintf (logbuffer, " args->user=%s", (args->user) ? args->user : "(null)");
- log_entry (logbuffer);
- sprintf (logbuffer, " args->password=%s",(args->password) ? args->password : "(null)");
- log_entry (logbuffer);
- sprintf (logbuffer, " args->logfile=%s",(args->logfile) ? args->logfile : "(null)");
- log_entry (logbuffer);
- sprintf (logbuffer, " args->daemonize=%i",args->daemonize);
- log_entry (logbuffer);
-
- sprintf (logbuffer, " args->sleep_base_value=%i", args->sleep_base_value);
- log_entry (logbuffer);
- sprintf (logbuffer, " args->sleep_scaling_factor=%f",args->sleep_scaling_factor);
- log_entry (logbuffer);
- sprintf (logbuffer, " args->vacuum_base_threshold=%i",args->vacuum_base_threshold);
- log_entry (logbuffer);
- sprintf (logbuffer, " args->vacuum_scaling_factor=%f",args->vacuum_scaling_factor);
- log_entry (logbuffer);
- sprintf (logbuffer, " args->analyze_base_threshold=%i",args->analyze_base_threshold);
- log_entry (logbuffer);
- sprintf (logbuffer, " args->analyze_scaling_factor=%f",args->analyze_scaling_factor);
- log_entry (logbuffer);
- sprintf (logbuffer, " args->debug=%i", args->debug);
- log_entry (logbuffer);
-
- fflush (LOGOUTPUT);
+ sprintf(logbuffer, "Printing command_args");
+ log_entry(logbuffer);
+ sprintf(logbuffer, " args->host=%s", (args->host) ? args->host : "(null)");
+ log_entry(logbuffer);
+ sprintf(logbuffer, " args->port=%s", (args->port) ? args->port : "(null)");
+ log_entry(logbuffer);
+ sprintf(logbuffer, " args->user=%s", (args->user) ? args->user : "(null)");
+ log_entry(logbuffer);
+ sprintf(logbuffer, " args->password=%s", (args->password) ? args->password : "(null)");
+ log_entry(logbuffer);
+ sprintf(logbuffer, " args->logfile=%s", (args->logfile) ? args->logfile : "(null)");
+ log_entry(logbuffer);
+ sprintf(logbuffer, " args->daemonize=%i", args->daemonize);
+ log_entry(logbuffer);
+
+ sprintf(logbuffer, " args->sleep_base_value=%i", args->sleep_base_value);
+ log_entry(logbuffer);
+ sprintf(logbuffer, " args->sleep_scaling_factor=%f", args->sleep_scaling_factor);
+ log_entry(logbuffer);
+ sprintf(logbuffer, " args->vacuum_base_threshold=%i", args->vacuum_base_threshold);
+ log_entry(logbuffer);
+ sprintf(logbuffer, " args->vacuum_scaling_factor=%f", args->vacuum_scaling_factor);
+ log_entry(logbuffer);
+ sprintf(logbuffer, " args->analyze_base_threshold=%i", args->analyze_base_threshold);
+ log_entry(logbuffer);
+ sprintf(logbuffer, " args->analyze_scaling_factor=%f", args->analyze_scaling_factor);
+ log_entry(logbuffer);
+ sprintf(logbuffer, " args->debug=%i", args->debug);
+ log_entry(logbuffer);
+
+ fflush(LOGOUTPUT);
}
/* Beginning of AutoVacuum Main Program */
int
-main (int argc, char *argv[])
+main(int argc, char *argv[])
{
- char buf[256];
- int j = 0, loops = 0;
-/* int numInserts, numDeletes, */
- int sleep_secs;
- Dllist *db_list;
- Dlelem *db_elem, *tbl_elem;
- db_info *dbs;
- tbl_info *tbl;
- PGresult *res=NULL;
- long long diff = 0;
- struct timeval now, then;
-
- args = get_cmd_args (argc, argv); /* Get Command Line Args and put them in the args struct */
-
- /* Dameonize if requested */
- if (1 == args->daemonize){ daemonize(); }
-
- if (args->logfile) {
- LOGOUTPUT = fopen (args->logfile, "a");
- if (!LOGOUTPUT) {
- fprintf (stderr, "Could not open log file - [%s]\n", args->logfile);
- exit(-1);
- }
- }
- else {
- LOGOUTPUT = stderr;
- }
- if (args->debug >= 2) {
- print_cmd_args ();
- }
-
- /* Init the db list with template1 */
- db_list = init_db_list ();
- if (NULL == db_list)
- return 1;
-
- if (0 != check_stats_enabled (((db_info *) DLE_VAL (DLGetHead (db_list))))) {
- log_entry ("Error: GUC variable stats_row_level must be enabled.");
- log_entry (" Please fix the problems and try again.");
- fflush (LOGOUTPUT);
-
- exit (1);
- }
-
- gettimeofday (&then, 0); /* for use later to caluculate sleep time */
-
- while (1) { /* Main Loop */
- db_elem = DLGetHead (db_list); /* Reset cur_db_node to the beginning of the db_list */
-
- dbs = ((db_info *) DLE_VAL (db_elem)); /* get pointer to cur_db's db_info struct */
- if (NULL == dbs->conn) {
- dbs->conn = db_connect (dbs);
- if (NULL == dbs->conn) { /* Serious problem: We can't connect to template1 */
- log_entry ("Error: Cannot connect to template1, exiting.");
- fflush (LOGOUTPUT);
- fclose (LOGOUTPUT);
- exit (1);
- }
- }
-
- if (0 == (loops % UPDATE_INTERVAL)) /* Update the list if it's time */
- update_db_list (db_list); /* Add and remove databases from the list */
-
- while (NULL != db_elem) { /* Loop through databases in list */
- dbs = ((db_info *) DLE_VAL (db_elem)); /* get pointer to cur_db's db_info struct */
- if (NULL == dbs->conn)
- dbs->conn = db_connect (dbs);
-
- if (NULL != dbs->conn) {
- if (0 == (loops % UPDATE_INTERVAL)) /* Update the list if it's time */
- update_table_list (dbs); /* Add and remove tables from the list */
-
- if (0 == xid_wraparound_check (dbs));
- {
- res = send_query (query_table_stats (dbs), dbs); /* Get an updated snapshot of this dbs table stats */
- for (j = 0; j < PQntuples (res); j++) { /* loop through result set */
- tbl_elem = DLGetHead (dbs->table_list); /* Reset tbl_elem to top of dbs->table_list */
- while (NULL != tbl_elem) { /* Loop through tables in list */
- tbl = ((tbl_info *) DLE_VAL (tbl_elem)); /* set tbl_info = current_table */
- if (tbl->relfilenode == atoi (PQgetvalue(res, j, PQfnumber (res, "relfilenode")))) {
- tbl->curr_analyze_count =
- (atol (PQgetvalue (res, j, PQfnumber (res, "n_tup_ins"))) +
- atol (PQgetvalue (res, j, PQfnumber (res, "n_tup_upd"))) +
- atol (PQgetvalue (res, j, PQfnumber (res, "n_tup_del"))));
- tbl->curr_vacuum_count =
- (atol (PQgetvalue (res, j, PQfnumber (res, "n_tup_del"))) +
- atol (PQgetvalue (res, j, PQfnumber (res, "n_tup_upd"))));
-
- /* Check numDeletes to see if we need to vacuum, if so:
- Run vacuum analyze (adding analyze is small so we might as well)
- Update table thresholds and related information
- if numDeletes is not big enough for vacuum then check numInserts for analyze */
- if ((tbl->curr_vacuum_count - tbl->CountAtLastVacuum) >= tbl->vacuum_threshold)
- {
- snprintf (buf, sizeof (buf), "vacuum analyze %s", tbl->table_name);
- if (args->debug >= 1) {
- sprintf (logbuffer, "Performing: %s", buf);
- log_entry (logbuffer);
- fflush (LOGOUTPUT);
- }
- send_query (buf, dbs);
- update_table_thresholds (dbs, tbl, VACUUM_ANALYZE);
- if (args->debug >= 2) {print_table_info (tbl);}
- }
- else if ((tbl->curr_analyze_count - tbl->CountAtLastAnalyze) >= tbl->analyze_threshold)
- {
- snprintf (buf, sizeof (buf), "analyze %s", tbl->table_name);
- if (args->debug >= 1) {
- sprintf (logbuffer, "Performing: %s", buf);
- log_entry (logbuffer);
- fflush (LOGOUTPUT);
- }
- send_query (buf, dbs);
- update_table_thresholds (dbs, tbl, ANALYZE_ONLY);
- if (args->debug >= 2) { print_table_info (tbl); }
- }
-
- break; /* once we have found a match, no need to keep checking. */
- }
- /* Advance the table pointers for the next loop */
- tbl_elem = DLGetSucc (tbl_elem);
-
- } /* end for table while loop */
- } /* end for j loop (tuples in PGresult) */
- } /* close of if(xid_wraparound_check()) */
- /* Done working on this db, Clean up, then advance cur_db */
- PQclear (res);
- res = NULL;
- db_disconnect (dbs);
- }
- db_elem = DLGetSucc (db_elem); /* move on to next DB regardless */
- } /* end of db_list while loop */
-
- /* Figure out how long to sleep etc ... */
- gettimeofday (&now, 0);
- diff = (now.tv_sec - then.tv_sec) * 1000000 + (now.tv_usec - then.tv_usec);
-
- sleep_secs = args->sleep_base_value + args->sleep_scaling_factor * diff / 1000000;
- loops++;
- if (args->debug >= 2) {
- sprintf (logbuffer,
- "%i All DBs checked in: %lld usec, will sleep for %i secs.",
- loops, diff, sleep_secs);
- log_entry (logbuffer);
- }
-
- sleep (sleep_secs); /* Larger Pause between outer loops */
-
- gettimeofday (&then, 0); /* Reset time counter */
-
- } /* end of while loop */
-
- /* program is exiting, this should never run, but is here to make compiler / valgrind happy */
- free_db_list (db_list);
- free_cmd_args ();
- return EXIT_SUCCESS;
+ char buf[256];
+ int j = 0,
+ loops = 0;
+
+/* int numInserts, numDeletes, */
+ int sleep_secs;
+ Dllist *db_list;
+ Dlelem *db_elem,
+ *tbl_elem;
+ db_info *dbs;
+ tbl_info *tbl;
+ PGresult *res = NULL;
+ long long diff = 0;
+ struct timeval now,
+ then;
+
+ args = get_cmd_args(argc, argv); /* Get Command Line Args and put
+ * them in the args struct */
+
+ /* Dameonize if requested */
+ if (1 == args->daemonize)
+ daemonize();
+
+ if (args->logfile)
+ {
+ LOGOUTPUT = fopen(args->logfile, "a");
+ if (!LOGOUTPUT)
+ {
+ fprintf(stderr, "Could not open log file - [%s]\n", args->logfile);
+ exit(-1);
+ }
+ }
+ else
+ LOGOUTPUT = stderr;
+ if (args->debug >= 2)
+ print_cmd_args();
+
+ /* Init the db list with template1 */
+ db_list = init_db_list();
+ if (NULL == db_list)
+ return 1;
+
+ if (0 != check_stats_enabled(((db_info *) DLE_VAL(DLGetHead(db_list)))))
+ {
+ log_entry("Error: GUC variable stats_row_level must be enabled.");
+ log_entry(" Please fix the problems and try again.");
+ fflush(LOGOUTPUT);
+
+ exit(1);
+ }
+
+ gettimeofday(&then, 0); /* for use later to caluculate sleep time */
+
+ while (1)
+ { /* Main Loop */
+ db_elem = DLGetHead(db_list); /* Reset cur_db_node to the
+ * beginning of the db_list */
+
+ dbs = ((db_info *) DLE_VAL(db_elem)); /* get pointer to cur_db's
+ * db_info struct */
+ if (NULL == dbs->conn)
+ {
+ dbs->conn = db_connect(dbs);
+ if (NULL == dbs->conn)
+ { /* Serious problem: We can't connect to
+ * template1 */
+ log_entry("Error: Cannot connect to template1, exiting.");
+ fflush(LOGOUTPUT);
+ fclose(LOGOUTPUT);
+ exit(1);
+ }
+ }
+
+ if (0 == (loops % UPDATE_INTERVAL)) /* Update the list if it's
+ * time */
+ update_db_list(db_list); /* Add and remove databases from
+ * the list */
+
+ while (NULL != db_elem)
+ { /* Loop through databases in list */
+ dbs = ((db_info *) DLE_VAL(db_elem)); /* get pointer to
+ * cur_db's db_info
+ * struct */
+ if (NULL == dbs->conn)
+ dbs->conn = db_connect(dbs);
+
+ if (NULL != dbs->conn)
+ {
+ if (0 == (loops % UPDATE_INTERVAL)) /* Update the list if
+ * it's time */
+ update_table_list(dbs); /* Add and remove tables
+ * from the list */
+
+ if (0 == xid_wraparound_check(dbs));
+ {
+ res = send_query(query_table_stats(dbs), dbs); /* Get an updated
+ * snapshot of this dbs
+ * table stats */
+ for (j = 0; j < PQntuples(res); j++)
+ { /* loop through result set */
+ tbl_elem = DLGetHead(dbs->table_list); /* Reset tbl_elem to top
+ * of dbs->table_list */
+ while (NULL != tbl_elem)
+ { /* Loop through tables in list */
+ tbl = ((tbl_info *) DLE_VAL(tbl_elem)); /* set tbl_info =
+ * current_table */
+ if (tbl->relfilenode == atoi(PQgetvalue(res, j, PQfnumber(res, "relfilenode"))))
+ {
+ tbl->curr_analyze_count =
+ (atol(PQgetvalue(res, j, PQfnumber(res, "n_tup_ins"))) +
+ atol(PQgetvalue(res, j, PQfnumber(res, "n_tup_upd"))) +
+ atol(PQgetvalue(res, j, PQfnumber(res, "n_tup_del"))));
+ tbl->curr_vacuum_count =
+ (atol(PQgetvalue(res, j, PQfnumber(res, "n_tup_del"))) +
+ atol(PQgetvalue(res, j, PQfnumber(res, "n_tup_upd"))));
+
+ /*
+ * Check numDeletes to see if we need to
+ * vacuum, if so: Run vacuum analyze
+ * (adding analyze is small so we might as
+ * well) Update table thresholds and
+ * related information if numDeletes is
+ * not big enough for vacuum then check
+ * numInserts for analyze
+ */
+ if ((tbl->curr_vacuum_count - tbl->CountAtLastVacuum) >= tbl->vacuum_threshold)
+ {
+ snprintf(buf, sizeof(buf), "vacuum analyze %s", tbl->table_name);
+ if (args->debug >= 1)
+ {
+ sprintf(logbuffer, "Performing: %s", buf);
+ log_entry(logbuffer);
+ fflush(LOGOUTPUT);
+ }
+ send_query(buf, dbs);
+ update_table_thresholds(dbs, tbl, VACUUM_ANALYZE);
+ if (args->debug >= 2)
+ print_table_info(tbl);
+ }
+ else if ((tbl->curr_analyze_count - tbl->CountAtLastAnalyze) >= tbl->analyze_threshold)
+ {
+ snprintf(buf, sizeof(buf), "analyze %s", tbl->table_name);
+ if (args->debug >= 1)
+ {
+ sprintf(logbuffer, "Performing: %s", buf);
+ log_entry(logbuffer);
+ fflush(LOGOUTPUT);
+ }
+ send_query(buf, dbs);
+ update_table_thresholds(dbs, tbl, ANALYZE_ONLY);
+ if (args->debug >= 2)
+ print_table_info(tbl);
+ }
+
+ break; /* once we have found a match, no
+ * need to keep checking. */
+ }
+
+ /*
+ * Advance the table pointers for the next
+ * loop
+ */
+ tbl_elem = DLGetSucc(tbl_elem);
+
+ } /* end for table while loop */
+ } /* end for j loop (tuples in PGresult) */
+ } /* close of if(xid_wraparound_check()) */
+ /* Done working on this db, Clean up, then advance cur_db */
+ PQclear(res);
+ res = NULL;
+ db_disconnect(dbs);
+ }
+ db_elem = DLGetSucc(db_elem); /* move on to next DB
+ * regardless */
+ } /* end of db_list while loop */
+
+ /* Figure out how long to sleep etc ... */
+ gettimeofday(&now, 0);
+ diff = (now.tv_sec - then.tv_sec) * 1000000 + (now.tv_usec - then.tv_usec);
+
+ sleep_secs = args->sleep_base_value + args->sleep_scaling_factor * diff / 1000000;
+ loops++;
+ if (args->debug >= 2)
+ {
+ sprintf(logbuffer,
+ "%i All DBs checked in: %lld usec, will sleep for %i secs.",
+ loops, diff, sleep_secs);
+ log_entry(logbuffer);
+ }
+
+ sleep(sleep_secs); /* Larger Pause between outer loops */
+
+ gettimeofday(&then, 0); /* Reset time counter */
+
+ } /* end of while loop */
+
+ /*
+ * program is exiting, this should never run, but is here to make
+ * compiler / valgrind happy
+ */
+ free_db_list(db_list);
+ free_cmd_args();
+ return EXIT_SUCCESS;
}
#include "/usr/include/pgsql/server/lib/dllist.h"
*/
-#define AUTOVACUUM_DEBUG 1
-#define VACBASETHRESHOLD 1000
-#define VACSCALINGFACTOR 2
-#define SLEEPBASEVALUE 300
-#define SLEEPSCALINGFACTOR 2
-#define UPDATE_INTERVAL 2
+#define AUTOVACUUM_DEBUG 1
+#define VACBASETHRESHOLD 1000
+#define VACSCALINGFACTOR 2
+#define SLEEPBASEVALUE 300
+#define SLEEPSCALINGFACTOR 2
+#define UPDATE_INTERVAL 2
/* these two constants are used to tell update_table_stats what operation we just perfomred */
-#define VACUUM_ANALYZE 0
-#define ANALYZE_ONLY 1
+#define VACUUM_ANALYZE 0
+#define ANALYZE_ONLY 1
-#define TABLE_STATS_ALL "select a.relfilenode,a.relname,a.relnamespace,a.relpages,a.reltuples,b.schemaname,b.n_tup_ins,b.n_tup_upd,b.n_tup_del from pg_class a, pg_stat_all_tables b where a.relfilenode=b.relid"
-#define TABLE_STATS_USER "select a.relfilenode,a.relname,a.relnamespace,a.relpages,a.reltuples,b.schemaname,b.n_tup_ins,b.n_tup_upd,b.n_tup_del from pg_class a, pg_stat_user_tables b where a.relfilenode=b.relid"
+#define TABLE_STATS_ALL "select a.relfilenode,a.relname,a.relnamespace,a.relpages,a.reltuples,b.schemaname,b.n_tup_ins,b.n_tup_upd,b.n_tup_del from pg_class a, pg_stat_all_tables b where a.relfilenode=b.relid"
+#define TABLE_STATS_USER "select a.relfilenode,a.relname,a.relnamespace,a.relpages,a.reltuples,b.schemaname,b.n_tup_ins,b.n_tup_upd,b.n_tup_del from pg_class a, pg_stat_user_tables b where a.relfilenode=b.relid"
#define FRONTEND
#define PAGES_QUERY "select relfilenode,reltuples,relpages from pg_class where relfilenode=%i"
#define FROZENOID_QUERY "select oid,age(datfrozenxid) from pg_database where datname = 'template1'"
/* define cmd_args stucture */
struct cmdargs
{
- int vacuum_base_threshold, analyze_base_threshold, sleep_base_value, debug, daemonize;
- float vacuum_scaling_factor, analyze_scaling_factor, sleep_scaling_factor;
- char *user, *password, *host, *logfile, *port;
+ int vacuum_base_threshold,
+ analyze_base_threshold,
+ sleep_base_value,
+ debug,
+ daemonize;
+ float vacuum_scaling_factor,
+ analyze_scaling_factor,
+ sleep_scaling_factor;
+ char *user,
+ *password,
+ *host,
+ *logfile,
+ *port;
};
typedef struct cmdargs cmd_args;
/* define cmd_args as global so we can get to them everywhere */
-cmd_args *args;
+cmd_args *args;
/* Might need to add a time value for last time the whold database was vacuumed.
- I think we need to guarantee this happens approx every 1Million TX's */
+ I think we need to guarantee this happens approx every 1Million TX's */
struct dbinfo
{
- int oid, age;
- int analyze_threshold, vacuum_threshold; /* Use these as defaults for table thresholds */
- PGconn *conn;
- char *dbname, *username, *password;
- Dllist *table_list;
+ int oid,
+ age;
+ int analyze_threshold,
+ vacuum_threshold; /* Use these as defaults for table
+ * thresholds */
+ PGconn *conn;
+ char *dbname,
+ *username,
+ *password;
+ Dllist *table_list;
};
typedef struct dbinfo db_info;
struct tableinfo
{
- char *schema_name, *table_name;
- int relfilenode, reltuples, relpages;
- long analyze_threshold, vacuum_threshold;
- long CountAtLastAnalyze; /* equal to: inserts + updates as of the last analyze or initial values at startup */
- long CountAtLastVacuum; /* equal to: deletes + updates as of the last vacuum or initial values at startup */
- long curr_analyze_count, curr_vacuum_count; /* Latest values from stats system */
- db_info *dbi; /* pointer to the database that this table belongs to */
+ char *schema_name,
+ *table_name;
+ int relfilenode,
+ reltuples,
+ relpages;
+ long analyze_threshold,
+ vacuum_threshold;
+ long CountAtLastAnalyze; /* equal to: inserts + updates as
+ * of the last analyze or initial
+ * values at startup */
+ long CountAtLastVacuum; /* equal to: deletes + updates as
+ * of the last vacuum or initial
+ * values at startup */
+ long curr_analyze_count,
+ curr_vacuum_count; /* Latest values from stats system */
+ db_info *dbi; /* pointer to the database that this table
+ * belongs to */
};
typedef struct tableinfo tbl_info;
/* Functions for dealing with command line arguements */
-static cmd_args *get_cmd_args (int argc, char *argv[]);
-static void print_cmd_args (void);
-static void free_cmd_args (void);
-static void usage (void);
+static cmd_args *get_cmd_args(int argc, char *argv[]);
+static void print_cmd_args(void);
+static void free_cmd_args(void);
+static void usage(void);
/* Functions for managing database lists */
-static Dllist *init_db_list (void);
-static db_info *init_dbinfo (char *dbname, int oid, int age);
-static void update_db_list (Dllist * db_list);
-static void remove_db_from_list (Dlelem * db_to_remove);
-static void print_db_info (db_info * dbi, int print_table_list);
-static void print_db_list (Dllist * db_list, int print_table_lists);
-static int xid_wraparound_check (db_info * dbi);
-static void free_db_list (Dllist * db_list);
+static Dllist *init_db_list(void);
+static db_info *init_dbinfo(char *dbname, int oid, int age);
+static void update_db_list(Dllist *db_list);
+static void remove_db_from_list(Dlelem *db_to_remove);
+static void print_db_info(db_info * dbi, int print_table_list);
+static void print_db_list(Dllist *db_list, int print_table_lists);
+static int xid_wraparound_check(db_info * dbi);
+static void free_db_list(Dllist *db_list);
/* Functions for managing table lists */
-static tbl_info *init_table_info (PGresult * conn, int row, db_info *dbi);
-static void update_table_list (db_info * dbi);
-static void remove_table_from_list (Dlelem * tbl_to_remove);
-static void print_table_list (Dllist * tbl_node);
-static void print_table_info (tbl_info * tbl);
-static void update_table_thresholds (db_info * dbi, tbl_info * tbl, int vacuum_type);
-static void free_tbl_list (Dllist * tbl_list);
+static tbl_info *init_table_info(PGresult *conn, int row, db_info * dbi);
+static void update_table_list(db_info * dbi);
+static void remove_table_from_list(Dlelem *tbl_to_remove);
+static void print_table_list(Dllist *tbl_node);
+static void print_table_info(tbl_info * tbl);
+static void update_table_thresholds(db_info * dbi, tbl_info * tbl, int vacuum_type);
+static void free_tbl_list(Dllist *tbl_list);
/* A few database helper functions */
-static int check_stats_enabled (db_info * dbi);
-static PGconn *db_connect (db_info * dbi);
-static void db_disconnect (db_info * dbi);
-static PGresult *send_query (const char *query, db_info * dbi);
-static char *query_table_stats (db_info * dbi);
+static int check_stats_enabled(db_info * dbi);
+static PGconn *db_connect(db_info * dbi);
+static void db_disconnect(db_info * dbi);
+static PGresult *send_query(const char *query, db_info * dbi);
+static char *query_table_stats(db_info * dbi);
/* Other Generally needed Functions */
static void daemonize(void);
-static void log_entry (const char *logentry);
+static void log_entry(const char *logentry);
/* -------------------------------------------------------------------------
* pg_dumplo
*
- * $Header: /cvsroot/pgsql/contrib/pg_dumplo/Attic/main.c,v 1.16 2003/05/14 03:25:56 tgl Exp $
+ * $Header: /cvsroot/pgsql/contrib/pg_dumplo/Attic/main.c,v 1.17 2003/08/04 00:43:11 momjian Exp $
*
* Karel Zak 1999-2000
* -------------------------------------------------------------------------
#ifndef HAVE_GETOPT_LONG
#include "getopt_long.h"
-int optreset;
+int optreset;
#endif
char *progname = NULL;
/*
- * $Header: /cvsroot/pgsql/contrib/pgbench/pgbench.c,v 1.25 2003/08/01 02:21:17 tgl Exp $
+ * $Header: /cvsroot/pgsql/contrib/pgbench/pgbench.c,v 1.26 2003/08/04 00:43:11 momjian Exp $
*
* pgbench: a simple TPC-B like benchmark program for PostgreSQL
* written by Tatsuo Ishii
{
PGconn *con;
PGresult *res;
-
+
con = PQsetdbLogin(pghost, pgport, pgoptions, pgtty, dbName,
login, pwd);
if (con == NULL)
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
- * $Id: openssl.c,v 1.11 2002/11/15 02:54:44 momjian Exp $
+ * $Id: openssl.c,v 1.12 2003/08/04 00:43:11 momjian Exp $
*/
#include <postgres.h>
* of functions does not allow enough flexibility
* and forces some of the parameters (keylen,
* padding) to SSL defaults.
- *
+ *
* So need to manage ciphers ourselves.
*/
-struct ossl_cipher {
- int (*init) (PX_Cipher * c, const uint8 *key, unsigned klen, const uint8 *iv);
- int (*encrypt) (PX_Cipher * c, const uint8 *data, unsigned dlen, uint8 *res);
- int (*decrypt) (PX_Cipher * c, const uint8 *data, unsigned dlen, uint8 *res);
+struct ossl_cipher
+{
+ int (*init) (PX_Cipher * c, const uint8 *key, unsigned klen, const uint8 *iv);
+ int (*encrypt) (PX_Cipher * c, const uint8 *data, unsigned dlen, uint8 *res);
+ int (*decrypt) (PX_Cipher * c, const uint8 *data, unsigned dlen, uint8 *res);
- int block_size;
- int max_key_size;
- int stream_cipher;
+ int block_size;
+ int max_key_size;
+ int stream_cipher;
};
typedef struct
bf_ecb_encrypt(PX_Cipher * c, const uint8 *data, unsigned dlen, uint8 *res)
{
unsigned bs = gen_ossl_block_size(c);
- unsigned i;
+ unsigned i;
ossldata *od = c->ptr;
for (i = 0; i < dlen / bs; i++)
ossl_des_init(PX_Cipher * c, const uint8 *key, unsigned klen, const uint8 *iv)
{
ossldata *od = c->ptr;
- des_cblock xkey;
+ des_cblock xkey;
memset(&xkey, 0, sizeof(xkey));
memcpy(&xkey, key, klen > 8 ? 8 : klen);
des_set_key(&xkey, od->u.des.key_schedule);
memset(&xkey, 0, sizeof(xkey));
-
+
if (iv)
memcpy(od->iv, iv, 8);
else
static int
ossl_des_ecb_encrypt(PX_Cipher * c, const uint8 *data, unsigned dlen,
- uint8 *res)
+ uint8 *res)
{
unsigned bs = gen_ossl_block_size(c);
- unsigned i;
+ unsigned i;
ossldata *od = c->ptr;
for (i = 0; i < dlen / bs; i++)
- des_ecb_encrypt((des_cblock*)(data + i * bs),
- (des_cblock*)(res + i * bs),
- od->u.des.key_schedule, 1);
+ des_ecb_encrypt((des_cblock *) (data + i * bs),
+ (des_cblock *) (res + i * bs),
+ od->u.des.key_schedule, 1);
return 0;
}
static int
ossl_des_ecb_decrypt(PX_Cipher * c, const uint8 *data, unsigned dlen,
- uint8 *res)
+ uint8 *res)
{
unsigned bs = gen_ossl_block_size(c);
- unsigned i;
+ unsigned i;
ossldata *od = c->ptr;
for (i = 0; i < dlen / bs; i++)
- des_ecb_encrypt((des_cblock*)(data + i * bs),
- (des_cblock*)(res + i * bs),
- od->u.des.key_schedule, 0);
+ des_ecb_encrypt((des_cblock *) (data + i * bs),
+ (des_cblock *) (res + i * bs),
+ od->u.des.key_schedule, 0);
return 0;
}
static int
ossl_des_cbc_encrypt(PX_Cipher * c, const uint8 *data, unsigned dlen,
- uint8 *res)
+ uint8 *res)
{
ossldata *od = c->ptr;
des_ncbc_encrypt(data, res, dlen, od->u.des.key_schedule,
- (des_cblock*)od->iv, 1);
+ (des_cblock *) od->iv, 1);
return 0;
}
static int
ossl_des_cbc_decrypt(PX_Cipher * c, const uint8 *data, unsigned dlen,
- uint8 *res)
+ uint8 *res)
{
ossldata *od = c->ptr;
des_ncbc_encrypt(data, res, dlen, od->u.des.key_schedule,
- (des_cblock*)od->iv, 0);
+ (des_cblock *) od->iv, 0);
return 0;
}
{
unsigned bs = gen_ossl_block_size(c);
ossldata *od = c->ptr;
- const uint8 *end = data + dlen - bs;
+ const uint8 *end = data + dlen - bs;
for (; data <= end; data += bs, res += bs)
CAST_ecb_encrypt(data, res, &od->u.cast_key, CAST_ENCRYPT);
{
unsigned bs = gen_ossl_block_size(c);
ossldata *od = c->ptr;
- const uint8 *end = data + dlen - bs;
+ const uint8 *end = data + dlen - bs;
for (; data <= end; data += bs, res += bs)
CAST_ecb_encrypt(data, res, &od->u.cast_key, CAST_DECRYPT);
static const struct ossl_cipher ossl_bf_cbc = {
bf_init, bf_cbc_encrypt, bf_cbc_decrypt,
- 64/8, 448/8, 0
+ 64 / 8, 448 / 8, 0
};
static const struct ossl_cipher ossl_bf_ecb = {
bf_init, bf_ecb_encrypt, bf_ecb_decrypt,
- 64/8, 448/8, 0
+ 64 / 8, 448 / 8, 0
};
static const struct ossl_cipher ossl_bf_cfb = {
bf_init, bf_cfb64_encrypt, bf_cfb64_decrypt,
- 64/8, 448/8, 1
+ 64 / 8, 448 / 8, 1
};
static const struct ossl_cipher ossl_des_ecb = {
ossl_des_init, ossl_des_ecb_encrypt, ossl_des_ecb_decrypt,
- 64/8, 64/8, 0
+ 64 / 8, 64 / 8, 0
};
static const struct ossl_cipher ossl_des_cbc = {
ossl_des_init, ossl_des_cbc_encrypt, ossl_des_cbc_decrypt,
- 64/8, 64/8, 0
+ 64 / 8, 64 / 8, 0
};
static const struct ossl_cipher ossl_cast_ecb = {
ossl_cast_init, ossl_cast_ecb_encrypt, ossl_cast_ecb_decrypt,
- 64/8, 128/8, 0
+ 64 / 8, 128 / 8, 0
};
static const struct ossl_cipher ossl_cast_cbc = {
ossl_cast_init, ossl_cast_cbc_encrypt, ossl_cast_cbc_decrypt,
- 64/8, 128/8, 0
+ 64 / 8, 128 / 8, 0
};
/*
*/
static const struct
{
- const char *name;
+ const char *name;
const struct ossl_cipher *ciph;
} ossl_cipher_types[] =
const struct ossl_cipher *ossl_ciph = NULL;
name = px_resolve_alias(ossl_aliases, name);
- for (i = 0; ossl_cipher_types[i].name; i++) {
- if (!strcmp(ossl_cipher_types[i].name, name)) {
+ for (i = 0; ossl_cipher_types[i].name; i++)
+ {
+ if (!strcmp(ossl_cipher_types[i].name, name))
+ {
ossl_ciph = ossl_cipher_types[i].ciph;
break;
}
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
- * $Id: pgcrypto.c,v 1.13 2003/07/24 17:52:33 tgl Exp $
+ * $Id: pgcrypto.c,v 1.14 2003/08/04 00:43:11 momjian Exp $
*/
#include <postgres.h>
if (len == 0)
ereport(ERROR,
(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
- errmsg("no such crypt algorithm or bad number of rounds")));
+ errmsg("no such crypt algorithm or bad number of rounds")));
res = (text *) palloc(len + VARHDRSZ);
VARATT_SIZEP(res) = len + VARHDRSZ;
/*
- * $Header: /cvsroot/pgsql/contrib/pgstattuple/pgstattuple.c,v 1.11 2003/08/01 02:21:17 tgl Exp $
+ * $Header: /cvsroot/pgsql/contrib/pgstattuple/pgstattuple.c,v 1.12 2003/08/04 00:43:11 momjian Exp $
*
* Copyright (c) 2001,2002 Tatsuo Ishii
*
pfree(values[i]);
pfree(values);
- return(result);
+ return (result);
}
if (SPI_gettypeid(tupdesc, attnum) != INT4OID)
ereport(ERROR,
(errcode(ERRCODE_TRIGGERED_ACTION_EXCEPTION),
- errmsg("attribute \"%s\" of \"%s\" must be type INT4",
- args[i], relname)));
+ errmsg("attribute \"%s\" of \"%s\" must be type INT4",
+ args[i], relname)));
val = DatumGetInt32(SPI_getbinval(rettuple, tupdesc, attnum, &isnull));
if (attnum < 0)
ereport(ERROR,
(errcode(ERRCODE_TRIGGERED_ACTION_EXCEPTION),
- errmsg("\"%s\" has no attribute \"%s\"", relname, args[0])));
+ errmsg("\"%s\" has no attribute \"%s\"", relname, args[0])));
if (SPI_gettypeid(tupdesc, attnum) != TEXTOID)
ereport(ERROR,
(errcode(ERRCODE_TRIGGERED_ACTION_EXCEPTION),
errmsg("attribute \"%s\" of \"%s\" must be type TEXT",
- args[0], relname)));
+ args[0], relname)));
/* create fields containing name */
newval = DirectFunctionCall1(textin,
- CStringGetDatum(GetUserNameFromId(GetUserId())));
+ CStringGetDatum(GetUserNameFromId(GetUserId())));
/* construct new tuple */
rettuple = SPI_modifytuple(rel, rettuple, 1, &attnum, &newval, NULL);
if (SPI_gettypeid(tupdesc, attnum) != TIMESTAMPOID)
ereport(ERROR,
(errcode(ERRCODE_TRIGGERED_ACTION_EXCEPTION),
- errmsg("attribute \"%s\" of \"%s\" must be type TIMESTAMP",
- args[0], relname)));
+ errmsg("attribute \"%s\" of \"%s\" must be type TIMESTAMP",
+ args[0], relname)));
/* 1 is the number of items in the arrays attnum and newdt.
attnum is the positional number of the field to be updated.
if (fnumber < 0)
ereport(ERROR,
(errcode(ERRCODE_UNDEFINED_COLUMN),
- errmsg("there is no attribute \"%s\" in relation \"%s\"",
- args[i], SPI_getrelname(rel))));
+ errmsg("there is no attribute \"%s\" in relation \"%s\"",
+ args[i], SPI_getrelname(rel))));
/* Well, get binary (in internal format) value of column */
kvals[i] = SPI_getbinval(tuple, tupdesc, fnumber, &isnull);
if (fnumber < 0)
ereport(ERROR,
(errcode(ERRCODE_UNDEFINED_COLUMN),
- errmsg("there is no attribute \"%s\" in relation \"%s\"",
- args[i], SPI_getrelname(rel))));
+ errmsg("there is no attribute \"%s\" in relation \"%s\"",
+ args[i], SPI_getrelname(rel))));
/* Well, get binary (in internal format) value of column */
kvals[i] = SPI_getbinval(trigtuple, tupdesc, fnumber, &isnull);
ereport(ERROR,
(errcode(ERRCODE_TRIGGERED_ACTION_EXCEPTION),
errmsg("\"%s\": tuple is referenced in \"%s\"",
- trigger->tgname, relname)));
+ trigger->tgname, relname)));
}
else
{
#include "executor/spi.h" /* this is what you need to work with SPI */
-#include "commands/trigger.h" /* -"- and triggers */
+#include "commands/trigger.h" /* -"- and triggers */
#include "miscadmin.h" /* for GetPgUserName() */
-#include <ctype.h> /* tolower () */
+#include <ctype.h> /* tolower () */
-#define ABSTIMEOID 702 /* it should be in pg_type.h */
+#define ABSTIMEOID 702 /* it should be in pg_type.h */
/* AbsoluteTime currabstime(void); */
Datum timetravel(PG_FUNCTION_ARGS);
typedef struct _TTOffList
{
- struct _TTOffList *next;
- char name[1];
-} TTOffList;
+ struct _TTOffList *next;
+ char name[1];
+} TTOffList;
-static TTOffList TTOff = {NULL,{0}};
+static TTOffList TTOff = {NULL, {0}};
-static int findTTStatus(char *name);
+static int findTTStatus(char *name);
static EPlan *find_plan(char *ident, EPlan ** eplan, int *nplans);
/*
PG_FUNCTION_INFO_V1(timetravel);
-Datum /* have to return HeapTuple to Executor */
+Datum /* have to return HeapTuple to Executor */
timetravel(PG_FUNCTION_ARGS)
{
- TriggerData *trigdata = (TriggerData *) fcinfo->context;
- Trigger *trigger; /* to get trigger name */
- int argc;
- char **args; /* arguments */
- int attnum[MaxAttrNum]; /* fnumbers of start/stop columns */
+ TriggerData *trigdata = (TriggerData *) fcinfo->context;
+ Trigger *trigger; /* to get trigger name */
+ int argc;
+ char **args; /* arguments */
+ int attnum[MaxAttrNum]; /* fnumbers of start/stop columns */
Datum oldtimeon,
- oldtimeoff;
+ oldtimeoff;
Datum newtimeon,
- newtimeoff,
- newuser,
- nulltext;
- Datum *cvals; /* column values */
- char *cnulls; /* column nulls */
- char *relname; /* triggered relation name */
+ newtimeoff,
+ newuser,
+ nulltext;
+ Datum *cvals; /* column values */
+ char *cnulls; /* column nulls */
+ char *relname; /* triggered relation name */
Relation rel; /* triggered relation */
HeapTuple trigtuple;
HeapTuple newtuple = NULL;
HeapTuple rettuple;
TupleDesc tupdesc; /* tuple description */
- int natts; /* # of attributes */
- EPlan *plan; /* prepared plan */
+ int natts; /* # of attributes */
+ EPlan *plan; /* prepared plan */
char ident[2 * NAMEDATALEN];
bool isnull; /* to know is some column NULL or not */
bool isinsert = false;
- int ret;
- int i;
+ int ret;
+ int i;
/*
* Some checks first...
*/
/* Called by trigger manager ? */
- if(!CALLED_AS_TRIGGER(fcinfo))
+ if (!CALLED_AS_TRIGGER(fcinfo))
elog(ERROR, "timetravel: not fired by trigger manager");
/* Should be called for ROW trigger */
- if(TRIGGER_FIRED_FOR_STATEMENT(trigdata->tg_event))
+ if (TRIGGER_FIRED_FOR_STATEMENT(trigdata->tg_event))
elog(ERROR, "timetravel: can't process STATEMENT events");
/* Should be called BEFORE */
- if(TRIGGER_FIRED_AFTER(trigdata->tg_event))
+ if (TRIGGER_FIRED_AFTER(trigdata->tg_event))
elog(ERROR, "timetravel: must be fired before event");
/* INSERT ? */
- if(TRIGGER_FIRED_BY_INSERT(trigdata->tg_event))
+ if (TRIGGER_FIRED_BY_INSERT(trigdata->tg_event))
isinsert = true;
- if(TRIGGER_FIRED_BY_UPDATE(trigdata->tg_event))
+ if (TRIGGER_FIRED_BY_UPDATE(trigdata->tg_event))
newtuple = trigdata->tg_newtuple;
trigtuple = trigdata->tg_trigtuple;
relname = SPI_getrelname(rel);
/* check if TT is OFF for this relation */
- if(0==findTTStatus(relname))
+ if (0 == findTTStatus(relname))
{
/* OFF - nothing to do */
pfree(relname);
trigger = trigdata->tg_trigger;
argc = trigger->tgnargs;
- if(argc != MinAttrNum && argc != MaxAttrNum)
+ if (argc != MinAttrNum && argc != MaxAttrNum)
elog(ERROR, "timetravel (%s): invalid (!= %d or %d) number of arguments %d",
relname, MinAttrNum, MaxAttrNum, trigger->tgnargs);
tupdesc = rel->rd_att;
natts = tupdesc->natts;
- for(i = 0 ; i < MinAttrNum ; i++)
+ for (i = 0; i < MinAttrNum; i++)
{
attnum[i] = SPI_fnumber(tupdesc, args[i]);
- if(attnum[i] < 0)
+ if (attnum[i] < 0)
elog(ERROR, "timetravel (%s): there is no attribute %s", relname, args[i]);
- if(SPI_gettypeid(tupdesc, attnum[i]) != ABSTIMEOID)
+ if (SPI_gettypeid(tupdesc, attnum[i]) != ABSTIMEOID)
elog(ERROR, "timetravel (%s): attribute %s must be of abstime type",
relname, args[i]);
}
- for( ; i < argc ; i++)
+ for (; i < argc; i++)
{
attnum[i] = SPI_fnumber(tupdesc, args[i]);
- if(attnum[i] < 0)
+ if (attnum[i] < 0)
elog(ERROR, "timetravel (%s): there is no attribute %s", relname, args[i]);
- if(SPI_gettypeid(tupdesc, attnum[i]) != TEXTOID)
+ if (SPI_gettypeid(tupdesc, attnum[i]) != TEXTOID)
elog(ERROR, "timetravel (%s): attribute %s must be of text type",
relname, args[i]);
}
/* create fields containing name */
- newuser = DirectFunctionCall1(textin, CStringGetDatum(GetUserNameFromId(GetUserId())));
+ newuser = DirectFunctionCall1(textin, CStringGetDatum(GetUserNameFromId(GetUserId())));
- nulltext = (Datum)NULL;
+ nulltext = (Datum) NULL;
- if(isinsert)
- { /* INSERT */
- int chnattrs = 0;
- int chattrs[MaxAttrNum];
- Datum newvals[MaxAttrNum];
- char newnulls[MaxAttrNum];
+ if (isinsert)
+ { /* INSERT */
+ int chnattrs = 0;
+ int chattrs[MaxAttrNum];
+ Datum newvals[MaxAttrNum];
+ char newnulls[MaxAttrNum];
oldtimeon = SPI_getbinval(trigtuple, tupdesc, attnum[a_time_on], &isnull);
- if(isnull)
+ if (isnull)
{
newvals[chnattrs] = GetCurrentAbsoluteTime();
newnulls[chnattrs] = ' ';
}
oldtimeoff = SPI_getbinval(trigtuple, tupdesc, attnum[a_time_off], &isnull);
- if(isnull)
+ if (isnull)
{
- if((chnattrs == 0 && DatumGetInt32(oldtimeon) >= NOEND_ABSTIME) ||
- (chnattrs > 0 && DatumGetInt32(newvals[a_time_on]) >= NOEND_ABSTIME))
+ if ((chnattrs == 0 && DatumGetInt32(oldtimeon) >= NOEND_ABSTIME) ||
+ (chnattrs > 0 && DatumGetInt32(newvals[a_time_on]) >= NOEND_ABSTIME))
elog(ERROR, "timetravel (%s): %s is infinity", relname, args[a_time_on]);
newvals[chnattrs] = NOEND_ABSTIME;
newnulls[chnattrs] = ' ';
}
else
{
- if((chnattrs == 0 && DatumGetInt32(oldtimeon) > DatumGetInt32(oldtimeoff)) ||
- (chnattrs > 0 && DatumGetInt32(newvals[a_time_on]) > DatumGetInt32(oldtimeoff)))
+ if ((chnattrs == 0 && DatumGetInt32(oldtimeon) > DatumGetInt32(oldtimeoff)) ||
+ (chnattrs > 0 && DatumGetInt32(newvals[a_time_on]) > DatumGetInt32(oldtimeoff)))
elog(ERROR, "timetravel (%s): %s gt %s", relname, args[a_time_on], args[a_time_off]);
}
pfree(relname);
- if(chnattrs <= 0)
+ if (chnattrs <= 0)
return PointerGetDatum(trigtuple);
- if(argc == MaxAttrNum)
+ if (argc == MaxAttrNum)
{
/* clear update_user value */
newvals[chnattrs] = nulltext;
/* UPDATE/DELETE: */
oldtimeon = SPI_getbinval(trigtuple, tupdesc, attnum[a_time_on], &isnull);
- if(isnull)
+ if (isnull)
elog(ERROR, "timetravel (%s): %s must be NOT NULL", relname, args[a_time_on]);
oldtimeoff = SPI_getbinval(trigtuple, tupdesc, attnum[a_time_off], &isnull);
- if(isnull)
+ if (isnull)
elog(ERROR, "timetravel (%s): %s must be NOT NULL", relname, args[a_time_off]);
/*
* If DELETE/UPDATE of tuple with stop_date neq INFINITY then say
* upper Executor to skip operation for this tuple
*/
- if(newtuple != NULL)
- { /* UPDATE */
+ if (newtuple != NULL)
+ { /* UPDATE */
newtimeon = SPI_getbinval(newtuple, tupdesc, attnum[a_time_on], &isnull);
- if(isnull)
+ if (isnull)
elog(ERROR, "timetravel (%s): %s must be NOT NULL", relname, args[a_time_on]);
newtimeoff = SPI_getbinval(newtuple, tupdesc, attnum[a_time_off], &isnull);
- if(isnull)
+ if (isnull)
elog(ERROR, "timetravel (%s): %s must be NOT NULL", relname, args[a_time_off]);
- if(oldtimeon != newtimeon || oldtimeoff != newtimeoff)
+ if (oldtimeon != newtimeon || oldtimeoff != newtimeoff)
elog(ERROR, "timetravel (%s): you can't change %s and/or %s columns (use set_timetravel)",
relname, args[a_time_on], args[a_time_off]);
}
- if(oldtimeoff != NOEND_ABSTIME)
- { /* current record is a deleted/updated record */
+ if (oldtimeoff != NOEND_ABSTIME)
+ { /* current record is a deleted/updated
+ * record */
pfree(relname);
return PointerGetDatum(NULL);
}
newtimeoff = GetCurrentAbsoluteTime();
/* Connect to SPI manager */
- if((ret = SPI_connect()) < 0)
+ if ((ret = SPI_connect()) < 0)
elog(ERROR, "timetravel (%s): SPI_connect returned %d", relname, ret);
/* Fetch tuple values and nulls */
cvals = (Datum *) palloc(natts * sizeof(Datum));
cnulls = (char *) palloc(natts * sizeof(char));
- for(i = 0; i < natts; i++)
+ for (i = 0; i < natts; i++)
{
cvals[i] = SPI_getbinval(trigtuple, tupdesc, i + 1, &isnull);
cnulls[i] = (isnull) ? 'n' : ' ';
}
/* change date column(s) */
- cvals[attnum[a_time_off] - 1] = newtimeoff; /* stop_date eq current date */
+ cvals[attnum[a_time_off] - 1] = newtimeoff; /* stop_date eq current
+ * date */
cnulls[attnum[a_time_off] - 1] = ' ';
- if(!newtuple)
- { /* DELETE */
- if(argc == MaxAttrNum)
+ if (!newtuple)
+ { /* DELETE */
+ if (argc == MaxAttrNum)
{
- cvals[attnum[a_del_user] - 1] = newuser; /* set delete user */
+ cvals[attnum[a_del_user] - 1] = newuser; /* set delete user */
cnulls[attnum[a_del_user] - 1] = ' ';
}
}
plan = find_plan(ident, &Plans, &nPlans);
/* if there is no plan ... */
- if(plan->splan == NULL)
+ if (plan->splan == NULL)
{
- void *pplan;
- Oid *ctypes;
- char sql[8192];
+ void *pplan;
+ Oid *ctypes;
+ char sql[8192];
/* allocate ctypes for preparation */
ctypes = (Oid *) palloc(natts * sizeof(Oid));
* Construct query: INSERT INTO _relation_ VALUES ($1, ...)
*/
snprintf(sql, sizeof(sql), "INSERT INTO %s VALUES (", relname);
- for(i = 1; i <= natts; i++)
+ for (i = 1; i <= natts; i++)
{
ctypes[i - 1] = SPI_gettypeid(tupdesc, i);
- if(!(tupdesc->attrs[i - 1]->attisdropped)) /* skip dropped columns */
- snprintf(sql + strlen(sql), sizeof(sql) - strlen(sql), "$%d%s",
- i, (i < natts) ? ", " : ")" );
+ if (!(tupdesc->attrs[i - 1]->attisdropped)) /* skip dropped columns */
+ snprintf(sql + strlen(sql), sizeof(sql) - strlen(sql), "$%d%s",
+ i, (i < natts) ? ", " : ")");
#if 0
- snprintf(sql + strlen(sql), sizeof(sql) - strlen(sql), "$%d /* %d */ %s",
- i, ctypes[i-1], (i < natts) ? ", " : ")" );
+ snprintf(sql + strlen(sql), sizeof(sql) - strlen(sql), "$%d /* %d */ %s",
+ i, ctypes[i - 1], (i < natts) ? ", " : ")");
#endif
}
/* Prepare plan for query */
pplan = SPI_prepare(sql, natts, ctypes);
- if(pplan == NULL)
+ if (pplan == NULL)
elog(ERROR, "timetravel (%s): SPI_prepare returned %d", relname, SPI_result);
/*
* use.
*/
pplan = SPI_saveplan(pplan);
- if(pplan == NULL)
+ if (pplan == NULL)
elog(ERROR, "timetravel (%s): SPI_saveplan returned %d", relname, SPI_result);
plan->splan = pplan;
*/
ret = SPI_execp(plan->splan, cvals, cnulls, 0);
- if(ret < 0)
+ if (ret < 0)
elog(ERROR, "timetravel (%s): SPI_execp returned %d", relname, ret);
/* Tuple to return to upper Executor ... */
- if(newtuple)
- { /* UPDATE */
- int chnattrs = 0;
- int chattrs[MaxAttrNum];
+ if (newtuple)
+ { /* UPDATE */
+ int chnattrs = 0;
+ int chattrs[MaxAttrNum];
Datum newvals[MaxAttrNum];
char newnulls[MaxAttrNum];
chattrs[chnattrs] = attnum[a_time_off];
chnattrs++;
- if(argc == MaxAttrNum)
+ if (argc == MaxAttrNum)
{
/* set update_user value */
newvals[chnattrs] = newuser;
*/
/* SPI_pfree(tmptuple); */
}
- else /* DELETE case */
+ else
+/* DELETE case */
rettuple = trigtuple;
SPI_finish(); /* don't forget say Bye to SPI mgr */
Datum
set_timetravel(PG_FUNCTION_ARGS)
{
- Name relname = PG_GETARG_NAME(0);
- int32 on = PG_GETARG_INT32(1);
- char *rname;
- char *d;
- char *s;
+ Name relname = PG_GETARG_NAME(0);
+ int32 on = PG_GETARG_INT32(1);
+ char *rname;
+ char *d;
+ char *s;
int32 ret;
- TTOffList *p,*pp;
+ TTOffList *p,
+ *pp;
- for(pp = (p = &TTOff)->next; pp; pp=(p=pp)->next)
+ for (pp = (p = &TTOff)->next; pp; pp = (p = pp)->next)
{
- if(namestrcmp(relname, pp->name) == 0)
+ if (namestrcmp(relname, pp->name) == 0)
break;
}
- if(pp)
+ if (pp)
{
/* OFF currently */
- if(on != 0)
+ if (on != 0)
{
/* turn ON */
p->next = pp->next;
else
{
/* ON currently */
- if(on == 0)
+ if (on == 0)
{
/* turn OFF */
s = rname = DatumGetCString(DirectFunctionCall1(nameout, NameGetDatum(relname)));
- if(s)
+ if (s)
{
- pp = malloc(sizeof(TTOffList)+strlen(rname));
- if(pp)
+ pp = malloc(sizeof(TTOffList) + strlen(rname));
+ if (pp)
{
pp->next = NULL;
p->next = pp;
d = pp->name;
while (*s)
- *d++ = tolower((unsigned char)*s++);
+ *d++ = tolower((unsigned char) *s++);
*d = '\0';
}
pfree(rname);
/*
* get_timetravel (relname) --
- * get timetravel status for specified relation (ON/OFF)
+ * get timetravel status for specified relation (ON/OFF)
*/
PG_FUNCTION_INFO_V1(get_timetravel);
get_timetravel(PG_FUNCTION_ARGS)
{
Name relname = PG_GETARG_NAME(0);
- TTOffList *pp;
+ TTOffList *pp;
- for(pp = TTOff.next; pp; pp = pp->next)
+ for (pp = TTOff.next; pp; pp = pp->next)
{
- if(namestrcmp(relname, pp->name) == 0)
+ if (namestrcmp(relname, pp->name) == 0)
PG_RETURN_INT32(0);
}
PG_RETURN_INT32(1);
static int
findTTStatus(char *name)
{
- TTOffList* pp;
- for(pp = TTOff.next; pp; pp = pp->next)
- if(strcasecmp(name, pp->name) == 0)
+ TTOffList *pp;
+
+ for (pp = TTOff.next; pp; pp = pp->next)
+ if (strcasecmp(name, pp->name) == 0)
return 0;
return 1;
}
static EPlan *
find_plan(char *ident, EPlan ** eplan, int *nplans)
{
- EPlan *newp;
- int i;
+ EPlan *newp;
+ int i;
- if(*nplans > 0)
+ if (*nplans > 0)
{
- for(i = 0; i < *nplans; i++)
+ for (i = 0; i < *nplans; i++)
{
- if(strcmp((*eplan)[i].ident, ident) == 0)
+ if (strcmp((*eplan)[i].ident, ident) == 0)
break;
}
- if(i != *nplans)
+ if (i != *nplans)
return (*eplan + i);
*eplan = (EPlan *) realloc(*eplan, (i + 1) * sizeof(EPlan));
newp = *eplan + i;
#include "tablefunc.h"
-static int load_categories_hash(char *cats_sql, MemoryContext per_query_ctx);
+static int load_categories_hash(char *cats_sql, MemoryContext per_query_ctx);
static Tuplestorestate *get_crosstab_tuplestore(char *sql,
- int num_categories,
- TupleDesc tupdesc,
- MemoryContext per_query_ctx);
+ int num_categories,
+ TupleDesc tupdesc,
+ MemoryContext per_query_ctx);
static void validateConnectbyTupleDesc(TupleDesc tupdesc, bool show_branch, bool show_serial);
static bool compatCrosstabTupleDescs(TupleDesc tupdesc1, TupleDesc tupdesc2);
static bool compatConnectbyTupleDescs(TupleDesc tupdesc1, TupleDesc tupdesc2);
static Tuplestorestate *connectby(char *relname,
char *key_fld,
char *parent_key_fld,
- char *orderby_fld,
+ char *orderby_fld,
char *branch_delim,
char *start_with,
int max_depth,
typedef struct crosstab_cat_desc
{
char *catname;
- int attidx; /* zero based */
+ int attidx; /* zero based */
} crosstab_cat_desc;
#define MAX_CATNAME_LEN NAMEDATALEN
/* hash table */
typedef struct crosstab_hashent
{
- char internal_catname[MAX_CATNAME_LEN];
- crosstab_cat_desc *catdesc;
-} crosstab_HashEnt;
+ char internal_catname[MAX_CATNAME_LEN];
+ crosstab_cat_desc *catdesc;
+} crosstab_HashEnt;
/*
* normal_rand - return requested number of random values
(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
errmsg("invalid source data SQL statement"),
errdetail("The provided SQL must return 3 " \
- " columns; rowid, category, and values.")));
+ " columns; rowid, category, and values.")));
}
else
{
}
/*
- * crosstab_hash - reimplement crosstab as materialized function and
+ * crosstab_hash - reimplement crosstab as materialized function and
* properly deal with missing values (i.e. don't pack remaining
* values to the left)
- *
+ *
* crosstab - create a crosstab of rowids and values columns from a
* SQL statement returning one rowid column, one category column,
* and one value column.
Datum
crosstab_hash(PG_FUNCTION_ARGS)
{
- char *sql = GET_STR(PG_GETARG_TEXT_P(0));
- char *cats_sql = GET_STR(PG_GETARG_TEXT_P(1));
- ReturnSetInfo *rsinfo = (ReturnSetInfo *) fcinfo->resultinfo;
- TupleDesc tupdesc;
- MemoryContext per_query_ctx;
- MemoryContext oldcontext;
- int num_categories;
+ char *sql = GET_STR(PG_GETARG_TEXT_P(0));
+ char *cats_sql = GET_STR(PG_GETARG_TEXT_P(1));
+ ReturnSetInfo *rsinfo = (ReturnSetInfo *) fcinfo->resultinfo;
+ TupleDesc tupdesc;
+ MemoryContext per_query_ctx;
+ MemoryContext oldcontext;
+ int num_categories;
/* check to see if caller supports us returning a tuplestore */
if (!rsinfo || !(rsinfo->allowedModes & SFRM_Materialize))
/*
* Check to make sure we have a reasonable tuple descriptor
*
- * Note we will attempt to coerce the values into whatever
- * the return attribute type is and depend on the "in"
- * function to complain if needed.
+ * Note we will attempt to coerce the values into whatever the return
+ * attribute type is and depend on the "in" function to complain if
+ * needed.
*/
if (tupdesc->natts < 2)
ereport(ERROR,
static int
load_categories_hash(char *cats_sql, MemoryContext per_query_ctx)
{
- HASHCTL ctl;
- int ret;
- int proc;
- MemoryContext SPIcontext;
- int num_categories = 0;
+ HASHCTL ctl;
+ int ret;
+ int proc;
+ MemoryContext SPIcontext;
+ int num_categories = 0;
/* initialize the category hash table */
ctl.keysize = MAX_CATNAME_LEN;
ctl.entrysize = sizeof(crosstab_HashEnt);
/*
- * use INIT_CATS, defined above as a guess of how
- * many hash table entries to create, initially
+ * use INIT_CATS, defined above as a guess of how many hash table
+ * entries to create, initially
*/
crosstab_HashTable = hash_create("crosstab hash", INIT_CATS, &ctl, HASH_ELEM);
/* Check for qualifying tuples */
if ((ret == SPI_OK_SELECT) && (proc > 0))
{
- SPITupleTable *spi_tuptable = SPI_tuptable;
- TupleDesc spi_tupdesc = spi_tuptable->tupdesc;
- int i;
+ SPITupleTable *spi_tuptable = SPI_tuptable;
+ TupleDesc spi_tupdesc = spi_tuptable->tupdesc;
+ int i;
/*
- * The provided categories SQL query must always return one column:
- * category - the label or identifier for each column
+ * The provided categories SQL query must always return one
+ * column: category - the label or identifier for each column
*/
if (spi_tupdesc->natts != 1)
ereport(ERROR,
for (i = 0; i < proc; i++)
{
- crosstab_cat_desc *catdesc;
- char *catname;
- HeapTuple spi_tuple;
+ crosstab_cat_desc *catdesc;
+ char *catname;
+ HeapTuple spi_tuple;
/* get the next sql result tuple */
spi_tuple = spi_tuptable->vals[i];
TupleDesc tupdesc,
MemoryContext per_query_ctx)
{
- Tuplestorestate *tupstore;
- AttInMetadata *attinmeta = TupleDescGetAttInMetadata(tupdesc);
- char **values;
- HeapTuple tuple;
- int ret;
- int proc;
- MemoryContext SPIcontext;
+ Tuplestorestate *tupstore;
+ AttInMetadata *attinmeta = TupleDescGetAttInMetadata(tupdesc);
+ char **values;
+ HeapTuple tuple;
+ int ret;
+ int proc;
+ MemoryContext SPIcontext;
/* initialize our tuplestore */
tupstore = tuplestore_begin_heap(true, false, SortMem);
/* Check for qualifying tuples */
if ((ret == SPI_OK_SELECT) && (proc > 0))
{
- SPITupleTable *spi_tuptable = SPI_tuptable;
- TupleDesc spi_tupdesc = spi_tuptable->tupdesc;
- int ncols = spi_tupdesc->natts;
- char *rowid;
- char *lastrowid = NULL;
- int i, j;
- int result_ncols;
+ SPITupleTable *spi_tuptable = SPI_tuptable;
+ TupleDesc spi_tupdesc = spi_tuptable->tupdesc;
+ int ncols = spi_tupdesc->natts;
+ char *rowid;
+ char *lastrowid = NULL;
+ int i,
+ j;
+ int result_ncols;
/*
- * The provided SQL query must always return at least three columns:
+ * The provided SQL query must always return at least three
+ * columns:
*
* 1. rowname the label for each row - column 1 in the final result
- * 2. category the label for each value-column in the final result
- * 3. value the values used to populate the value-columns
- *
+ * 2. category the label for each value-column in the final
+ * result 3. value the values used to populate the
+ * value-columns
+ *
* If there are more than three columns, the last two are taken as
- * "category" and "values". The first column is taken as "rowname".
- * Additional columns (2 thru N-2) are assumed the same for the same
- * "rowname", and are copied into the result tuple from the first
- * time we encounter a particular rowname.
+ * "category" and "values". The first column is taken as
+ * "rowname". Additional columns (2 thru N-2) are assumed the same
+ * for the same "rowname", and are copied into the result tuple
+ * from the first time we encounter a particular rowname.
*/
if (ncols < 3)
ereport(ERROR,
(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
errmsg("invalid source data SQL statement"),
errdetail("The provided SQL must return 3 " \
- " columns; rowid, category, and values.")));
+ " columns; rowid, category, and values.")));
result_ncols = (ncols - 2) + num_categories;
errmsg("invalid return type"),
errdetail("query-specified return " \
"tuple has %d columns but crosstab " \
- "returns %d", tupdesc->natts, result_ncols)));
+ "returns %d", tupdesc->natts, result_ncols)));
/* allocate space */
values = (char **) palloc(result_ncols * sizeof(char *));
for (i = 0; i < proc; i++)
{
- HeapTuple spi_tuple;
- crosstab_cat_desc *catdesc;
- char *catname;
+ HeapTuple spi_tuple;
+ crosstab_cat_desc *catdesc;
+ char *catname;
/* get the next sql result tuple */
spi_tuple = spi_tuptable->vals[i];
*/
if (lastrowid != NULL)
{
- /* switch to appropriate context while storing the tuple */
+ /*
+ * switch to appropriate context while storing the
+ * tuple
+ */
SPIcontext = MemoryContextSwitchTo(per_query_ctx);
/* rowid changed, flush the previous output row */
crosstab_HashTableLookup(catname, catdesc);
if (catdesc)
- values[catdesc->attidx + ncols - 2] =
+ values[catdesc->attidx + ncols - 2] =
SPI_getvalue(spi_tuple, spi_tupdesc, ncols);
}
*
* keyid parent_keyid pos
* ------+------------+--
- * row1 NULL 0
- * row2 row1 0
- * row3 row1 0
- * row4 row2 1
- * row5 row2 0
- * row6 row4 0
- * row7 row3 0
- * row8 row6 0
- * row9 row5 0
+ * row1 NULL 0
+ * row2 row1 0
+ * row3 row1 0
+ * row4 row2 1
+ * row5 row2 0
+ * row6 row4 0
+ * row7 row3 0
+ * row8 row6 0
+ * row9 row5 0
*
*
* connectby(text relname, text keyid_fld, text parent_keyid_fld
- * [, text orderby_fld], text start_with, int max_depth
- * [, text branch_delim])
+ * [, text orderby_fld], text start_with, int max_depth
+ * [, text branch_delim])
* connectby('foo', 'keyid', 'parent_keyid', 'pos', 'row2', 0, '~') returns:
*
- * keyid parent_id level branch serial
+ * keyid parent_id level branch serial
* ------+-----------+--------+-----------------------
- * row2 NULL 0 row2 1
- * row5 row2 1 row2~row5 2
- * row9 row5 2 row2~row5~row9 3
- * row4 row2 1 row2~row4 4
- * row6 row4 2 row2~row4~row6 5
+ * row2 NULL 0 row2 1
+ * row5 row2 1 row2~row5 2
+ * row9 row5 2 row2~row5~row9 3
+ * row4 row2 1 row2~row4 4
+ * row6 row4 2 row2~row4~row6 5
* row8 row6 3 row2~row4~row6~row8 6
*
*/
rsinfo->setResult = connectby(relname,
key_fld,
parent_key_fld,
- NULL,
+ NULL,
branch_delim,
start_with,
max_depth,
char *branch_delim = NULL;
bool show_branch = false;
bool show_serial = true;
-
+
ReturnSetInfo *rsinfo = (ReturnSetInfo *) fcinfo->resultinfo;
TupleDesc tupdesc;
AttInMetadata *attinmeta;
rsinfo->setResult = connectby(relname,
key_fld,
parent_key_fld,
- orderby_fld,
+ orderby_fld,
branch_delim,
start_with,
max_depth,
connectby(char *relname,
char *key_fld,
char *parent_key_fld,
- char *orderby_fld,
+ char *orderby_fld,
char *branch_delim,
char *start_with,
int max_depth,
bool show_branch,
- bool show_serial,
+ bool show_serial,
MemoryContext per_query_ctx,
AttInMetadata *attinmeta)
{
int ret;
MemoryContext oldcontext;
- int serial = 1;
+ int serial = 1;
/* Connect to SPI manager */
if ((ret = SPI_connect()) < 0)
if (!show_serial)
{
appendStringInfo(sql, "SELECT %s, %s FROM %s WHERE %s = '%s' AND %s IS NOT NULL",
- key_fld,
- parent_key_fld,
- relname,
- parent_key_fld,
- start_with,
- key_fld);
- serial_column=0;
+ key_fld,
+ parent_key_fld,
+ relname,
+ parent_key_fld,
+ start_with,
+ key_fld);
+ serial_column = 0;
}
else
{
appendStringInfo(sql, "SELECT %s, %s FROM %s WHERE %s = '%s' AND %s IS NOT NULL ORDER BY %s",
- key_fld,
- parent_key_fld,
- relname,
- parent_key_fld,
- start_with,
- key_fld,
- orderby_fld);
- serial_column=1;
+ key_fld,
+ parent_key_fld,
+ relname,
+ parent_key_fld,
+ start_with,
+ key_fld,
+ orderby_fld);
+ serial_column = 1;
}
/* Retrieve the desired rows */
ereport(ERROR,
(errcode(ERRCODE_SYNTAX_ERROR),
errmsg("invalid return type"),
- errdetail("Return and SQL tuple descriptions are " \
- "incompatible.")));
+ errdetail("Return and SQL tuple descriptions are " \
+ "incompatible.")));
/* root value is the one we initially start with */
values[0] = start_with;
if (show_branch)
values[4] = serial_str;
else
- values[3] = serial_str;
+ values[3] = serial_str;
}
/* construct the tuple */
static void
validateConnectbyTupleDesc(TupleDesc tupdesc, bool show_branch, bool show_serial)
{
- int serial_column=0;
+ int serial_column = 0;
if (show_serial)
- serial_column=1;
-
+ serial_column = 1;
+
/* are there the correct number of columns */
if (show_branch)
{
(errcode(ERRCODE_SYNTAX_ERROR),
errmsg("invalid return type"),
errdetail("Third column must be type %s.",
- format_type_be(INT4OID))));
+ format_type_be(INT4OID))));
/* check that the type of the fourth column is TEXT if applicable */
if (show_branch && tupdesc->attrs[3]->atttypid != TEXTOID)
(errcode(ERRCODE_SYNTAX_ERROR),
errmsg("invalid return type"),
errdetail("Fourth column must be type %s.",
- format_type_be(TEXTOID))));
+ format_type_be(TEXTOID))));
/* check that the type of the fifth column is INT4 */
if (show_branch && show_serial && tupdesc->attrs[4]->atttypid != INT4OID)
if (!show_branch && show_serial && tupdesc->attrs[3]->atttypid != INT4OID)
elog(ERROR, "Query-specified return tuple not valid for Connectby: "
"fourth column must be type %s", format_type_be(INT4OID));
-
+
/* OK, the tupdesc is valid for our purposes */
}
(errcode(ERRCODE_SYNTAX_ERROR),
errmsg("invalid return type"),
errdetail("SQL parent key field datatype does " \
- "not match return parent key field datatype.")));
+ "not match return parent key field datatype.")));
/* OK, the two tupdescs are compatible for our purposes */
return true;
#undef DICT_TABLE
/* array for storing dictionary's objects (if needed) */
-void *dictobjs[lengthof(dicts)];
+void *dictobjs[
+ lengthof(dicts)];
#define STOPLEXEM -2
#define BYLOCALE -1
}
else if (nd == BYLOCALE)
{
- continue; /* no dict for current locale */
+ continue; /* no dict for current locale */
}
else
{
#include "ts_cfg.h"
#include "dict.h"
-text*
-char2text(char* in) {
+text *
+char2text(char *in)
+{
return charl2text(in, strlen(in));
}
-text* charl2text(char* in, int len) {
- text *out=(text*)palloc(len+VARHDRSZ);
+text *
+charl2text(char *in, int len)
+{
+ text *out = (text *) palloc(len + VARHDRSZ);
+
memcpy(VARDATA(out), in, len);
- VARATT_SIZEP(out) = len+VARHDRSZ;
+ VARATT_SIZEP(out) = len + VARHDRSZ;
return out;
}
-char
-*text2char(text* in) {
- char *out=palloc( VARSIZE(in) );
- memcpy(out, VARDATA(in), VARSIZE(in)-VARHDRSZ);
- out[ VARSIZE(in)-VARHDRSZ ] ='\0';
+char
+ *
+text2char(text *in)
+{
+ char *out = palloc(VARSIZE(in));
+
+ memcpy(out, VARDATA(in), VARSIZE(in) - VARHDRSZ);
+ out[VARSIZE(in) - VARHDRSZ] = '\0';
return out;
}
-char
-*pnstrdup(char* in, int len) {
- char *out=palloc( len+1 );
+char
+ *
+pnstrdup(char *in, int len)
+{
+ char *out = palloc(len + 1);
+
memcpy(out, in, len);
- out[len]='\0';
+ out[len] = '\0';
return out;
}
-text
-*ptextdup(text* in) {
- text *out=(text*)palloc( VARSIZE(in) );
- memcpy(out,in,VARSIZE(in));
+text
+ *
+ptextdup(text *in)
+{
+ text *out = (text *) palloc(VARSIZE(in));
+
+ memcpy(out, in, VARSIZE(in));
return out;
}
-text
-*mtextdup(text* in) {
- text *out=(text*)malloc( VARSIZE(in) );
- if ( !out )
+text
+ *
+mtextdup(text *in)
+{
+ text *out = (text *) malloc(VARSIZE(in));
+
+ if (!out)
ts_error(ERROR, "No memory");
- memcpy(out,in,VARSIZE(in));
+ memcpy(out, in, VARSIZE(in));
return out;
}
-void
-ts_error(int state, const char *format, ...) {
- va_list args;
- int tlen = 128, len=0;
- char *buf;
-
+void
+ts_error(int state, const char *format,...)
+{
+ va_list args;
+ int tlen = 128,
+ len = 0;
+ char *buf;
+
reset_cfg();
reset_dict();
reset_prs();
va_start(args, format);
buf = palloc(tlen);
- len = vsnprintf(buf, tlen-1, format, args);
- if ( len >= tlen ) {
- tlen=len+1;
- buf = repalloc( buf, tlen );
- vsnprintf(buf, tlen-1, format, args);
+ len = vsnprintf(buf, tlen - 1, format, args);
+ if (len >= tlen)
+ {
+ tlen = len + 1;
+ buf = repalloc(buf, tlen);
+ vsnprintf(buf, tlen - 1, format, args);
}
va_end(args);
-
+
/* ?? internal error ?? */
elog(state, "%s", buf);
pfree(buf);
}
-int
-text_cmp(text *a, text *b) {
- if ( VARSIZE(a) == VARSIZE(b) )
- return strncmp( VARDATA(a), VARDATA(b), VARSIZE(a)-VARHDRSZ );
- return (int)VARSIZE(a) - (int)VARSIZE(b);
+int
+text_cmp(text *a, text *b)
+{
+ if (VARSIZE(a) == VARSIZE(b))
+ return strncmp(VARDATA(a), VARDATA(b), VARSIZE(a) - VARHDRSZ);
+ return (int) VARSIZE(a) - (int) VARSIZE(b);
}
-
#define PG_NARGS() (fcinfo->nargs)
#endif
-text* char2text(char* in);
-text* charl2text(char* in, int len);
-char *text2char(text* in);
-char *pnstrdup(char* in, int len);
-text *ptextdup(text* in);
-text *mtextdup(text* in);
+text *char2text(char *in);
+text *charl2text(char *in, int len);
+char *text2char(text *in);
+char *pnstrdup(char *in, int len);
+text *ptextdup(text *in);
+text *mtextdup(text *in);
-int text_cmp(text *a, text *b);
+int text_cmp(text *a, text *b);
#define NEXTVAL(x) ( (text*)( (char*)(x) + INTALIGN( VARSIZE(x) ) ) )
#define ARRNELEMS(x) ArrayGetNItems( ARR_NDIM(x), ARR_DIMS(x))
-void ts_error(int state, const char *format, ...);
+void ts_error(int state, const char *format,...);
#endif
-/*
- * interface functions to dictionary
+/*
+ * interface functions to dictionary
*/
#include <errno.h>
/*********top interface**********/
-static void *plan_getdict=NULL;
+static void *plan_getdict = NULL;
void
-init_dict(Oid id, DictInfo *dict) {
- Oid arg[1]={ OIDOID };
- bool isnull;
- Datum pars[1]={ ObjectIdGetDatum(id) };