PreviousUpNext

6.893 Architecture of Database Systems
Term Project

Creating a New Abstract Data Type

The new abstract data type, WSTD, is implemented in C and PL/pgSQL. C is used for the constructor and for the comparison operations while PL/pgSQL is used to define the rest (most) of the functions. The choice was made basically for implementational convenience.

The following is the header file wstd.h:

/* wstd.h */

typedef struct wstd
{
	int	year;
	int	day;
}		wstd;

/* These prototypes declare the requirements that Postgres places on these
   user written functions.
*/
wstd *wstd_in(char *str);
char *wstd_out(wstd * wstd);
int get_year(wstd * a);
int get_day(wstd * a);

bool wstd_lt(wstd * a, wstd * b);
bool wstd_le(wstd * a, wstd * b);
bool wstd_eq(wstd * a, wstd * b);
bool wstd_ge(wstd * a, wstd * b);
bool wstd_gt(wstd * a, wstd * b);
int4 wstd_cmp(wstd * a, wstd * b);

The following is the source code in wstd.c:

/* wstd.c */

#include <stdio.h>
#include "pgsql/postgres.h"
#include "wstd.h"

/*****************************************************************************
 * Input/Output functions
 *****************************************************************************/

wstd *wstd_in(char *str)
{
  int   year,     /* Year */
        day;      /* Day */
  wstd  *result;

	if (sscanf(str, " ( %i , %i )", &year, &day) != 2)
	{
	  fprintf(stderr, "wstd_in: error in parsing \"%s\"", str);
	  return NULL;
	}
	result = (wstd *) palloc(sizeof(wstd));
	result->year = year;
	result->day = day;
	return result;
}

char *wstd_out(wstd * wstd)
{
	char	   *result;

	if (wstd == NULL)
		return NULL;

	result = (char *) palloc(60);
	sprintf(result, "(%i,%i)", wstd->year, wstd->day);
	return result;
}


/*****************************************************************************
 * Useful Macros
 *****************************************************************************/

#define Year(c)	((c)->year)
#define Day(c)	((c)->day)

/*****************************************************************************
 * Useful Functions to allow us to get at internal state
 *****************************************************************************/

int get_year(wstd * a)
{
  return Year(a);
}

int get_day(wstd * a)
{
  return Day(a);
}

/*****************************************************************************
 * Comparison functions which will be used to define the B-tree index
 *****************************************************************************/

bool wstd_lt(wstd * a, wstd * b)
{
  int ayear = Year(a);
  int byear = Year(b);
  int aday = Day(a);
  int bday = Day(b);

  if (ayear != byear)
    return ayear < byear;
  else
    return aday < bday;
}

bool wstd_le(wstd * a, wstd * b)
{
  int ayear = Year(a);
  int byear = Year(b);
  int aday = Day(a);
  int bday = Day(b);

  if (ayear != byear)
    return ayear < byear;
  else
    return aday <= bday;
}

bool wstd_eq(wstd * a, wstd * b)
{
  int ayear = Year(a);
  int byear = Year(b);
  int aday = Day(a);
  int bday = Day(b);

  if (ayear != byear)
    return ayear == byear;
  else
    return aday == bday;
}

bool wstd_ge(wstd * a, wstd * b)
{
  int ayear = Year(a);
  int byear = Year(b);
  int aday = Day(a);
  int bday = Day(b);

  if (ayear != byear)
    return ayear > byear;
  else
    return aday >= bday;
}

bool wstd_gt(wstd * a, wstd * b)
{
  int ayear = Year(a);
  int byear = Year(b);
  int aday = Day(a);
  int bday = Day(b);

  if (ayear != byear)
    return ayear > byear;
  else
    return aday > bday;
}

int4 wstd_cmp(wstd * a, wstd * b)
{
  int ayear = Year(a);
  int byear = Year(b);
  int aday = Day(a);
  int bday = Day(b);

  if (ayear < byear)
    return -1;
  else if (ayear > byear)
    return 1;
  else {
    if (aday < bday)
      return -1;
    else if (aday > bday)
      return 1;
    else
      return 0;
  }
}

PreviousUpNext