mirror of
https://github.com/postgres/postgres.git
synced 2025-07-28 23:42:10 +03:00
pgindent run before 6.3 release, with Thomas' requested changes.
This commit is contained in:
@ -29,90 +29,113 @@
|
||||
static int32
|
||||
array_iterator(Oid elemtype, Oid proc, int and, ArrayType *array, Datum value)
|
||||
{
|
||||
HeapTuple typ_tuple;
|
||||
TypeTupleForm typ_struct;
|
||||
bool typbyval;
|
||||
int typlen;
|
||||
func_ptr proc_fn;
|
||||
int pronargs;
|
||||
int nitems, i, result;
|
||||
int ndim, *dim;
|
||||
char *p;
|
||||
HeapTuple typ_tuple;
|
||||
TypeTupleForm typ_struct;
|
||||
bool typbyval;
|
||||
int typlen;
|
||||
func_ptr proc_fn;
|
||||
int pronargs;
|
||||
int nitems,
|
||||
i,
|
||||
result;
|
||||
int ndim,
|
||||
*dim;
|
||||
char *p;
|
||||
|
||||
/* Sanity checks */
|
||||
if ((array == (ArrayType *) NULL)
|
||||
|| (ARR_IS_LO(array) == true)) {
|
||||
/* elog(NOTICE, "array_iterator: array is null"); */
|
||||
return (0);
|
||||
}
|
||||
ndim = ARR_NDIM(array);
|
||||
dim = ARR_DIMS(array);
|
||||
nitems = getNitems(ndim, dim);
|
||||
if (nitems == 0) {
|
||||
/* elog(NOTICE, "array_iterator: nitems = 0"); */
|
||||
return (0);
|
||||
}
|
||||
|
||||
/* Lookup element type information */
|
||||
typ_tuple = SearchSysCacheTuple(TYPOID, ObjectIdGetDatum(elemtype),0,0,0);
|
||||
if (!HeapTupleIsValid(typ_tuple)) {
|
||||
elog(ERROR,"array_iterator: cache lookup failed for type %d", elemtype);
|
||||
return 0;
|
||||
}
|
||||
typ_struct = (TypeTupleForm) GETSTRUCT(typ_tuple);
|
||||
typlen = typ_struct->typlen;
|
||||
typbyval = typ_struct->typbyval;
|
||||
|
||||
/* Lookup the function entry point */
|
||||
proc_fn = (func_ptr) NULL;
|
||||
fmgr_info(proc, &proc_fn, &pronargs);
|
||||
if ((proc_fn == NULL) || (pronargs != 2)) {
|
||||
elog(ERROR, "array_iterator: fmgr_info lookup failed for oid %d", proc);
|
||||
return (0);
|
||||
}
|
||||
|
||||
/* Scan the array and apply the operator to each element */
|
||||
result = 0;
|
||||
p = ARR_DATA_PTR(array);
|
||||
for (i = 0; i < nitems; i++) {
|
||||
if (typbyval) {
|
||||
switch(typlen) {
|
||||
case 1:
|
||||
result = (int) (*proc_fn)(*p, value);
|
||||
break;
|
||||
case 2:
|
||||
result = (int) (*proc_fn)(* (int16 *) p, value);
|
||||
break;
|
||||
case 3:
|
||||
case 4:
|
||||
result = (int) (*proc_fn)(* (int32 *) p, value);
|
||||
break;
|
||||
}
|
||||
p += typlen;
|
||||
} else {
|
||||
result = (int) (*proc_fn)(p, value);
|
||||
if (typlen > 0) {
|
||||
p += typlen;
|
||||
} else {
|
||||
p += INTALIGN(* (int32 *) p);
|
||||
}
|
||||
}
|
||||
if (result) {
|
||||
if (!and) {
|
||||
return (1);
|
||||
}
|
||||
} else {
|
||||
if (and) {
|
||||
/* Sanity checks */
|
||||
if ((array == (ArrayType *) NULL)
|
||||
|| (ARR_IS_LO(array) == true))
|
||||
{
|
||||
/* elog(NOTICE, "array_iterator: array is null"); */
|
||||
return (0);
|
||||
}
|
||||
ndim = ARR_NDIM(array);
|
||||
dim = ARR_DIMS(array);
|
||||
nitems = getNitems(ndim, dim);
|
||||
if (nitems == 0)
|
||||
{
|
||||
/* elog(NOTICE, "array_iterator: nitems = 0"); */
|
||||
return (0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (and && result) {
|
||||
return (1);
|
||||
} else {
|
||||
return (0);
|
||||
}
|
||||
/* Lookup element type information */
|
||||
typ_tuple = SearchSysCacheTuple(TYPOID, ObjectIdGetDatum(elemtype), 0, 0, 0);
|
||||
if (!HeapTupleIsValid(typ_tuple))
|
||||
{
|
||||
elog(ERROR, "array_iterator: cache lookup failed for type %d", elemtype);
|
||||
return 0;
|
||||
}
|
||||
typ_struct = (TypeTupleForm) GETSTRUCT(typ_tuple);
|
||||
typlen = typ_struct->typlen;
|
||||
typbyval = typ_struct->typbyval;
|
||||
|
||||
/* Lookup the function entry point */
|
||||
proc_fn = (func_ptr) NULL;
|
||||
fmgr_info(proc, &proc_fn, &pronargs);
|
||||
if ((proc_fn == NULL) || (pronargs != 2))
|
||||
{
|
||||
elog(ERROR, "array_iterator: fmgr_info lookup failed for oid %d", proc);
|
||||
return (0);
|
||||
}
|
||||
|
||||
/* Scan the array and apply the operator to each element */
|
||||
result = 0;
|
||||
p = ARR_DATA_PTR(array);
|
||||
for (i = 0; i < nitems; i++)
|
||||
{
|
||||
if (typbyval)
|
||||
{
|
||||
switch (typlen)
|
||||
{
|
||||
case 1:
|
||||
result = (int) (*proc_fn) (*p, value);
|
||||
break;
|
||||
case 2:
|
||||
result = (int) (*proc_fn) (*(int16 *) p, value);
|
||||
break;
|
||||
case 3:
|
||||
case 4:
|
||||
result = (int) (*proc_fn) (*(int32 *) p, value);
|
||||
break;
|
||||
}
|
||||
p += typlen;
|
||||
}
|
||||
else
|
||||
{
|
||||
result = (int) (*proc_fn) (p, value);
|
||||
if (typlen > 0)
|
||||
{
|
||||
p += typlen;
|
||||
}
|
||||
else
|
||||
{
|
||||
p += INTALIGN(*(int32 *) p);
|
||||
}
|
||||
}
|
||||
if (result)
|
||||
{
|
||||
if (!and)
|
||||
{
|
||||
return (1);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (and)
|
||||
{
|
||||
return (0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (and && result)
|
||||
{
|
||||
return (1);
|
||||
}
|
||||
else
|
||||
{
|
||||
return (0);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
@ -120,39 +143,39 @@ array_iterator(Oid elemtype, Oid proc, int and, ArrayType *array, Datum value)
|
||||
*/
|
||||
|
||||
int32
|
||||
array_texteq(ArrayType *array, char* value)
|
||||
array_texteq(ArrayType *array, char *value)
|
||||
{
|
||||
return array_iterator((Oid) 25, /* text */
|
||||
(Oid) 67, /* texteq */
|
||||
0, /* logical or */
|
||||
array, (Datum)value);
|
||||
return array_iterator((Oid) 25, /* text */
|
||||
(Oid) 67, /* texteq */
|
||||
0, /* logical or */
|
||||
array, (Datum) value);
|
||||
}
|
||||
|
||||
int32
|
||||
array_all_texteq(ArrayType *array, char* value)
|
||||
array_all_texteq(ArrayType *array, char *value)
|
||||
{
|
||||
return array_iterator((Oid) 25, /* text */
|
||||
(Oid) 67, /* texteq */
|
||||
1, /* logical and */
|
||||
array, (Datum)value);
|
||||
return array_iterator((Oid) 25, /* text */
|
||||
(Oid) 67, /* texteq */
|
||||
1, /* logical and */
|
||||
array, (Datum) value);
|
||||
}
|
||||
|
||||
int32
|
||||
array_textregexeq(ArrayType *array, char* value)
|
||||
array_textregexeq(ArrayType *array, char *value)
|
||||
{
|
||||
return array_iterator((Oid) 25, /* text */
|
||||
(Oid) 1254, /* textregexeq */
|
||||
0, /* logical or */
|
||||
array, (Datum)value);
|
||||
return array_iterator((Oid) 25, /* text */
|
||||
(Oid) 1254, /* textregexeq */
|
||||
0, /* logical or */
|
||||
array, (Datum) value);
|
||||
}
|
||||
|
||||
int32
|
||||
array_all_textregexeq(ArrayType *array, char* value)
|
||||
array_all_textregexeq(ArrayType *array, char *value)
|
||||
{
|
||||
return array_iterator((Oid) 25, /* text */
|
||||
(Oid) 1254, /* textregexeq */
|
||||
1, /* logical and */
|
||||
array, (Datum)value);
|
||||
return array_iterator((Oid) 25, /* text */
|
||||
(Oid) 1254, /* textregexeq */
|
||||
1, /* logical and */
|
||||
array, (Datum) value);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -161,39 +184,39 @@ array_all_textregexeq(ArrayType *array, char* value)
|
||||
*/
|
||||
|
||||
int32
|
||||
array_char16eq(ArrayType *array, char* value)
|
||||
array_char16eq(ArrayType *array, char *value)
|
||||
{
|
||||
return array_iterator((Oid) 20, /* char16 */
|
||||
(Oid) 1275, /* char16eq */
|
||||
0, /* logical or */
|
||||
array, (Datum)value);
|
||||
return array_iterator((Oid) 20, /* char16 */
|
||||
(Oid) 1275, /* char16eq */
|
||||
0, /* logical or */
|
||||
array, (Datum) value);
|
||||
}
|
||||
|
||||
int32
|
||||
array_all_char16eq(ArrayType *array, char* value)
|
||||
array_all_char16eq(ArrayType *array, char *value)
|
||||
{
|
||||
return array_iterator((Oid) 20, /* char16 */
|
||||
(Oid) 1275, /* char16eq */
|
||||
1, /* logical and */
|
||||
array, (Datum)value);
|
||||
return array_iterator((Oid) 20, /* char16 */
|
||||
(Oid) 1275, /* char16eq */
|
||||
1, /* logical and */
|
||||
array, (Datum) value);
|
||||
}
|
||||
|
||||
int32
|
||||
array_char16regexeq(ArrayType *array, char* value)
|
||||
array_char16regexeq(ArrayType *array, char *value)
|
||||
{
|
||||
return array_iterator((Oid) 20, /* char16 */
|
||||
(Oid) 1288, /* char16regexeq */
|
||||
0, /* logical or */
|
||||
array, (Datum)value);
|
||||
return array_iterator((Oid) 20, /* char16 */
|
||||
(Oid) 1288, /* char16regexeq */
|
||||
0, /* logical or */
|
||||
array, (Datum) value);
|
||||
}
|
||||
|
||||
int32
|
||||
array_all_char16regexeq(ArrayType *array, char* value)
|
||||
array_all_char16regexeq(ArrayType *array, char *value)
|
||||
{
|
||||
return array_iterator((Oid) 20, /* char16 */
|
||||
(Oid) 1288, /* char16regexeq */
|
||||
1, /* logical and */
|
||||
array, (Datum)value);
|
||||
return array_iterator((Oid) 20, /* char16 */
|
||||
(Oid) 1288, /* char16regexeq */
|
||||
1, /* logical and */
|
||||
array, (Datum) value);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -203,109 +226,109 @@ array_all_char16regexeq(ArrayType *array, char* value)
|
||||
int32
|
||||
array_int4eq(ArrayType *array, int4 value)
|
||||
{
|
||||
return array_iterator((Oid) 23, /* int4 */
|
||||
(Oid) 65, /* int4eq */
|
||||
0, /* logical or */
|
||||
array, (Datum)value);
|
||||
return array_iterator((Oid) 23, /* int4 */
|
||||
(Oid) 65, /* int4eq */
|
||||
0, /* logical or */
|
||||
array, (Datum) value);
|
||||
}
|
||||
|
||||
int32
|
||||
array_all_int4eq(ArrayType *array, int4 value)
|
||||
{
|
||||
return array_iterator((Oid) 23, /* int4 */
|
||||
(Oid) 65, /* int4eq */
|
||||
1, /* logical and */
|
||||
array, (Datum)value);
|
||||
return array_iterator((Oid) 23, /* int4 */
|
||||
(Oid) 65, /* int4eq */
|
||||
1, /* logical and */
|
||||
array, (Datum) value);
|
||||
}
|
||||
|
||||
int32
|
||||
array_int4ne(ArrayType *array, int4 value)
|
||||
{
|
||||
return array_iterator((Oid) 23, /* int4 */
|
||||
(Oid) 144, /* int4ne */
|
||||
0, /* logical or */
|
||||
array, (Datum)value);
|
||||
return array_iterator((Oid) 23, /* int4 */
|
||||
(Oid) 144, /* int4ne */
|
||||
0, /* logical or */
|
||||
array, (Datum) value);
|
||||
}
|
||||
|
||||
int32
|
||||
array_all_int4ne(ArrayType *array, int4 value)
|
||||
{
|
||||
return array_iterator((Oid) 23, /* int4 */
|
||||
(Oid) 144, /* int4ne */
|
||||
1, /* logical and */
|
||||
array, (Datum)value);
|
||||
return array_iterator((Oid) 23, /* int4 */
|
||||
(Oid) 144, /* int4ne */
|
||||
1, /* logical and */
|
||||
array, (Datum) value);
|
||||
}
|
||||
|
||||
int32
|
||||
array_int4gt(ArrayType *array, int4 value)
|
||||
{
|
||||
return array_iterator((Oid) 23, /* int4 */
|
||||
(Oid) 147, /* int4gt */
|
||||
0, /* logical or */
|
||||
array, (Datum)value);
|
||||
return array_iterator((Oid) 23, /* int4 */
|
||||
(Oid) 147, /* int4gt */
|
||||
0, /* logical or */
|
||||
array, (Datum) value);
|
||||
}
|
||||
|
||||
int32
|
||||
array_all_int4gt(ArrayType *array, int4 value)
|
||||
{
|
||||
return array_iterator((Oid) 23, /* int4 */
|
||||
(Oid) 147, /* int4gt */
|
||||
1, /* logical and */
|
||||
array, (Datum)value);
|
||||
return array_iterator((Oid) 23, /* int4 */
|
||||
(Oid) 147, /* int4gt */
|
||||
1, /* logical and */
|
||||
array, (Datum) value);
|
||||
}
|
||||
|
||||
int32
|
||||
array_int4ge(ArrayType *array, int4 value)
|
||||
{
|
||||
return array_iterator((Oid) 23, /* int4 */
|
||||
(Oid) 150, /* int4ge */
|
||||
0, /* logical or */
|
||||
array, (Datum)value);
|
||||
return array_iterator((Oid) 23, /* int4 */
|
||||
(Oid) 150, /* int4ge */
|
||||
0, /* logical or */
|
||||
array, (Datum) value);
|
||||
}
|
||||
|
||||
int32
|
||||
array_all_int4ge(ArrayType *array, int4 value)
|
||||
{
|
||||
return array_iterator((Oid) 23, /* int4 */
|
||||
(Oid) 150, /* int4ge */
|
||||
1, /* logical and */
|
||||
array, (Datum)value);
|
||||
return array_iterator((Oid) 23, /* int4 */
|
||||
(Oid) 150, /* int4ge */
|
||||
1, /* logical and */
|
||||
array, (Datum) value);
|
||||
}
|
||||
|
||||
int32
|
||||
array_int4lt(ArrayType *array, int4 value)
|
||||
{
|
||||
return array_iterator((Oid) 23, /* int4 */
|
||||
(Oid) 66, /* int4lt */
|
||||
0, /* logical or */
|
||||
array, (Datum)value);
|
||||
return array_iterator((Oid) 23, /* int4 */
|
||||
(Oid) 66, /* int4lt */
|
||||
0, /* logical or */
|
||||
array, (Datum) value);
|
||||
}
|
||||
|
||||
int32
|
||||
array_all_int4lt(ArrayType *array, int4 value)
|
||||
{
|
||||
return array_iterator((Oid) 23, /* int4 */
|
||||
(Oid) 66, /* int4lt */
|
||||
1, /* logical and */
|
||||
array, (Datum)value);
|
||||
return array_iterator((Oid) 23, /* int4 */
|
||||
(Oid) 66, /* int4lt */
|
||||
1, /* logical and */
|
||||
array, (Datum) value);
|
||||
}
|
||||
|
||||
int32
|
||||
array_int4le(ArrayType *array, int4 value)
|
||||
{
|
||||
return array_iterator((Oid) 23, /* int4 */
|
||||
(Oid) 149, /* int4le */
|
||||
0, /* logical or */
|
||||
array, (Datum)value);
|
||||
return array_iterator((Oid) 23, /* int4 */
|
||||
(Oid) 149, /* int4le */
|
||||
0, /* logical or */
|
||||
array, (Datum) value);
|
||||
}
|
||||
|
||||
int32
|
||||
array_all_int4le(ArrayType *array, int4 value)
|
||||
{
|
||||
return array_iterator((Oid) 23, /* int4 */
|
||||
(Oid) 149, /* int4le */
|
||||
1, /* logical and */
|
||||
array, (Datum)value);
|
||||
return array_iterator((Oid) 23, /* int4 */
|
||||
(Oid) 149, /* int4le */
|
||||
1, /* logical and */
|
||||
array, (Datum) value);
|
||||
}
|
||||
|
||||
/* end of file */
|
||||
|
@ -1,27 +1,28 @@
|
||||
#ifndef ARRAY_ITERATOR_H
|
||||
#define ARRAY_ITERATOR_H
|
||||
|
||||
static int32 array_iterator(Oid elemtype, Oid proc, int and,
|
||||
ArrayType *array, Datum value);
|
||||
int32 array_texteq(ArrayType *array, char* value);
|
||||
int32 array_all_texteq(ArrayType *array, char* value);
|
||||
int32 array_textregexeq(ArrayType *array, char* value);
|
||||
int32 array_all_textregexeq(ArrayType *array, char* value);
|
||||
int32 array_char16eq(ArrayType *array, char* value);
|
||||
int32 array_all_char16eq(ArrayType *array, char* value);
|
||||
int32 array_char16regexeq(ArrayType *array, char* value);
|
||||
int32 array_all_char16regexeq(ArrayType *array, char* value);
|
||||
int32 array_int4eq(ArrayType *array, int4 value);
|
||||
int32 array_all_int4eq(ArrayType *array, int4 value);
|
||||
int32 array_int4ne(ArrayType *array, int4 value);
|
||||
int32 array_all_int4ne(ArrayType *array, int4 value);
|
||||
int32 array_int4gt(ArrayType *array, int4 value);
|
||||
int32 array_all_int4gt(ArrayType *array, int4 value);
|
||||
int32 array_int4ge(ArrayType *array, int4 value);
|
||||
int32 array_all_int4ge(ArrayType *array, int4 value);
|
||||
int32 array_int4lt(ArrayType *array, int4 value);
|
||||
int32 array_all_int4lt(ArrayType *array, int4 value);
|
||||
int32 array_int4le(ArrayType *array, int4 value);
|
||||
int32 array_all_int4le(ArrayType *array, int4 value);
|
||||
static int32
|
||||
array_iterator(Oid elemtype, Oid proc, int and,
|
||||
ArrayType *array, Datum value);
|
||||
int32 array_texteq(ArrayType *array, char *value);
|
||||
int32 array_all_texteq(ArrayType *array, char *value);
|
||||
int32 array_textregexeq(ArrayType *array, char *value);
|
||||
int32 array_all_textregexeq(ArrayType *array, char *value);
|
||||
int32 array_char16eq(ArrayType *array, char *value);
|
||||
int32 array_all_char16eq(ArrayType *array, char *value);
|
||||
int32 array_char16regexeq(ArrayType *array, char *value);
|
||||
int32 array_all_char16regexeq(ArrayType *array, char *value);
|
||||
int32 array_int4eq(ArrayType *array, int4 value);
|
||||
int32 array_all_int4eq(ArrayType *array, int4 value);
|
||||
int32 array_int4ne(ArrayType *array, int4 value);
|
||||
int32 array_all_int4ne(ArrayType *array, int4 value);
|
||||
int32 array_int4gt(ArrayType *array, int4 value);
|
||||
int32 array_all_int4gt(ArrayType *array, int4 value);
|
||||
int32 array_int4ge(ArrayType *array, int4 value);
|
||||
int32 array_all_int4ge(ArrayType *array, int4 value);
|
||||
int32 array_int4lt(ArrayType *array, int4 value);
|
||||
int32 array_all_int4lt(ArrayType *array, int4 value);
|
||||
int32 array_int4le(ArrayType *array, int4 value);
|
||||
int32 array_all_int4le(ArrayType *array, int4 value);
|
||||
|
||||
#endif
|
||||
|
@ -6,7 +6,7 @@
|
||||
* Copyright (c) 1996, Massimo Dal Zotto <dz@cs.unitn.it>
|
||||
*/
|
||||
|
||||
#include <stdio.h> /* for sprintf() */
|
||||
#include <stdio.h> /* for sprintf() */
|
||||
#include <string.h>
|
||||
#include <limits.h>
|
||||
#ifdef HAVE_FLOAT_H
|
||||
@ -32,45 +32,47 @@
|
||||
* to hh:mm like in timetables.
|
||||
*/
|
||||
|
||||
TimeADT *
|
||||
TimeADT *
|
||||
hhmm_in(char *str)
|
||||
{
|
||||
TimeADT *time;
|
||||
TimeADT *time;
|
||||
|
||||
double fsec;
|
||||
struct tm tt, *tm = &tt;
|
||||
double fsec;
|
||||
struct tm tt,
|
||||
*tm = &tt;
|
||||
|
||||
int nf;
|
||||
char lowstr[MAXDATELEN+1];
|
||||
char *field[MAXDATEFIELDS];
|
||||
int dtype;
|
||||
int ftype[MAXDATEFIELDS];
|
||||
int nf;
|
||||
char lowstr[MAXDATELEN + 1];
|
||||
char *field[MAXDATEFIELDS];
|
||||
int dtype;
|
||||
int ftype[MAXDATEFIELDS];
|
||||
|
||||
if (!PointerIsValid(str))
|
||||
elog(ERROR,"Bad (null) time external representation",NULL);
|
||||
if (!PointerIsValid(str))
|
||||
elog(ERROR, "Bad (null) time external representation", NULL);
|
||||
|
||||
if ((ParseDateTime( str, lowstr, field, ftype, MAXDATEFIELDS, &nf) != 0)
|
||||
|| (DecodeTimeOnly( field, ftype, nf, &dtype, tm, &fsec) != 0))
|
||||
elog(ERROR,"Bad time external representation '%s'",str);
|
||||
if ((ParseDateTime(str, lowstr, field, ftype, MAXDATEFIELDS, &nf) != 0)
|
||||
|| (DecodeTimeOnly(field, ftype, nf, &dtype, tm, &fsec) != 0))
|
||||
elog(ERROR, "Bad time external representation '%s'", str);
|
||||
|
||||
if (tm->tm_hour<0 || tm->tm_hour>24 ||
|
||||
(tm->tm_hour==24 && (tm->tm_min!=0 || tm->tm_sec!=0 || fsec!= 0))) {
|
||||
elog(ERROR,
|
||||
"time_in: hour must be limited to values 0 through 24:00 "
|
||||
"in \"%s\"",
|
||||
str);
|
||||
}
|
||||
if ((tm->tm_min < 0) || (tm->tm_min > 59))
|
||||
elog(ERROR,"Minute must be limited to values 0 through 59 in '%s'",str);
|
||||
if ((tm->tm_sec < 0) || ((tm->tm_sec + fsec) >= 60))
|
||||
elog(ERROR,"Second must be limited to values 0 through < 60 in '%s'",
|
||||
str);
|
||||
if (tm->tm_hour < 0 || tm->tm_hour > 24 ||
|
||||
(tm->tm_hour == 24 && (tm->tm_min != 0 || tm->tm_sec != 0 || fsec != 0)))
|
||||
{
|
||||
elog(ERROR,
|
||||
"time_in: hour must be limited to values 0 through 24:00 "
|
||||
"in \"%s\"",
|
||||
str);
|
||||
}
|
||||
if ((tm->tm_min < 0) || (tm->tm_min > 59))
|
||||
elog(ERROR, "Minute must be limited to values 0 through 59 in '%s'", str);
|
||||
if ((tm->tm_sec < 0) || ((tm->tm_sec + fsec) >= 60))
|
||||
elog(ERROR, "Second must be limited to values 0 through < 60 in '%s'",
|
||||
str);
|
||||
|
||||
time = palloc(sizeof(TimeADT));
|
||||
time = palloc(sizeof(TimeADT));
|
||||
|
||||
*time = ((((tm->tm_hour*60)+tm->tm_min)*60));
|
||||
*time = ((((tm->tm_hour * 60) + tm->tm_min) * 60));
|
||||
|
||||
return(time);
|
||||
return (time);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -82,132 +84,143 @@ hhmm_in(char *str)
|
||||
char *
|
||||
hhmm_out(TimeADT *time)
|
||||
{
|
||||
char *result;
|
||||
struct tm tt, *tm = &tt;
|
||||
char buf[MAXDATELEN+1];
|
||||
char *result;
|
||||
struct tm tt,
|
||||
*tm = &tt;
|
||||
char buf[MAXDATELEN + 1];
|
||||
|
||||
if (!PointerIsValid(time))
|
||||
return NULL;
|
||||
if (!PointerIsValid(time))
|
||||
return NULL;
|
||||
|
||||
tm->tm_hour = (*time / (60*60));
|
||||
tm->tm_min = (((int) (*time / 60)) % 60);
|
||||
tm->tm_sec = (((int) *time) % 60);
|
||||
tm->tm_hour = (*time / (60 * 60));
|
||||
tm->tm_min = (((int) (*time / 60)) % 60);
|
||||
tm->tm_sec = (((int) *time) % 60);
|
||||
|
||||
if (tm->tm_sec == 0) {
|
||||
sprintf(buf, "%02d:%02d", tm->tm_hour, tm->tm_min);
|
||||
} else {
|
||||
sprintf(buf, "%02d:%02d:%02d", tm->tm_hour, tm->tm_min, tm->tm_sec);
|
||||
}
|
||||
if (tm->tm_sec == 0)
|
||||
{
|
||||
sprintf(buf, "%02d:%02d", tm->tm_hour, tm->tm_min);
|
||||
}
|
||||
else
|
||||
{
|
||||
sprintf(buf, "%02d:%02d:%02d", tm->tm_hour, tm->tm_min, tm->tm_sec);
|
||||
}
|
||||
|
||||
result = palloc(strlen(buf)+1);
|
||||
result = palloc(strlen(buf) + 1);
|
||||
|
||||
strcpy( result, buf);
|
||||
strcpy(result, buf);
|
||||
|
||||
return(result);
|
||||
return (result);
|
||||
}
|
||||
|
||||
TimeADT *
|
||||
TimeADT *
|
||||
hhmm(TimeADT *time)
|
||||
{
|
||||
TimeADT *result = palloc(sizeof(TimeADT));
|
||||
TimeADT *result = palloc(sizeof(TimeADT));
|
||||
|
||||
*result = (((int) *time) / 60 * 60);
|
||||
*result = (((int) *time) / 60 * 60);
|
||||
|
||||
return(result);
|
||||
return (result);
|
||||
}
|
||||
|
||||
TimeADT *
|
||||
TimeADT *
|
||||
time_difference(TimeADT *time1, TimeADT *time2)
|
||||
{
|
||||
TimeADT *time = palloc(sizeof(TimeADT));
|
||||
TimeADT *time = palloc(sizeof(TimeADT));
|
||||
|
||||
*time = (*time1 - *time2);
|
||||
return(time);
|
||||
*time = (*time1 - *time2);
|
||||
return (time);
|
||||
}
|
||||
|
||||
int4
|
||||
time_hours(TimeADT *time)
|
||||
{
|
||||
return (((int) *time) / 3600);
|
||||
return (((int) *time) / 3600);
|
||||
}
|
||||
|
||||
int4
|
||||
time_minutes(TimeADT *time)
|
||||
{
|
||||
return ((((int) *time) / 60) % 60);
|
||||
return ((((int) *time) / 60) % 60);
|
||||
}
|
||||
|
||||
int4
|
||||
time_seconds(TimeADT *time)
|
||||
{
|
||||
return (((int) *time) % 60);
|
||||
return (((int) *time) % 60);
|
||||
}
|
||||
|
||||
int4
|
||||
as_minutes(TimeADT *time)
|
||||
{
|
||||
return (((int) *time) / 60);
|
||||
return (((int) *time) / 60);
|
||||
}
|
||||
|
||||
int4
|
||||
as_seconds(TimeADT *time)
|
||||
{
|
||||
return ((int) *time);
|
||||
return ((int) *time);
|
||||
}
|
||||
|
||||
int4
|
||||
date_day(DateADT val)
|
||||
{
|
||||
int year, month, day;
|
||||
int year,
|
||||
month,
|
||||
day;
|
||||
|
||||
j2date(val + JDATE_2000, &year, &month, &day);
|
||||
j2date(val + JDATE_2000, &year, &month, &day);
|
||||
|
||||
return (day);
|
||||
return (day);
|
||||
}
|
||||
|
||||
int4
|
||||
date_month(DateADT val)
|
||||
{
|
||||
int year, month, day;
|
||||
int year,
|
||||
month,
|
||||
day;
|
||||
|
||||
j2date(val + JDATE_2000, &year, &month, &day);
|
||||
j2date(val + JDATE_2000, &year, &month, &day);
|
||||
|
||||
return (month);
|
||||
return (month);
|
||||
}
|
||||
|
||||
int4
|
||||
date_year(DateADT val)
|
||||
{
|
||||
int year, month, day;
|
||||
int year,
|
||||
month,
|
||||
day;
|
||||
|
||||
j2date(val + JDATE_2000, &year, &month, &day);
|
||||
j2date(val + JDATE_2000, &year, &month, &day);
|
||||
|
||||
return (year);
|
||||
return (year);
|
||||
}
|
||||
|
||||
TimeADT *
|
||||
TimeADT *
|
||||
currenttime()
|
||||
{
|
||||
TimeADT *result = palloc(sizeof(TimeADT));
|
||||
struct tm *tm;
|
||||
time_t current_time;
|
||||
TimeADT *result = palloc(sizeof(TimeADT));
|
||||
struct tm *tm;
|
||||
time_t current_time;
|
||||
|
||||
current_time = time(NULL);
|
||||
tm = localtime(¤t_time);
|
||||
*result = ((((tm->tm_hour*60)+tm->tm_min)*60)+tm->tm_sec);
|
||||
current_time = time(NULL);
|
||||
tm = localtime(¤t_time);
|
||||
*result = ((((tm->tm_hour * 60) + tm->tm_min) * 60) + tm->tm_sec);
|
||||
|
||||
return (result);
|
||||
return (result);
|
||||
}
|
||||
|
||||
DateADT
|
||||
currentdate()
|
||||
{
|
||||
DateADT date;
|
||||
struct tm tt, *tm = &tt;
|
||||
DateADT date;
|
||||
struct tm tt,
|
||||
*tm = &tt;
|
||||
|
||||
GetCurrentTime(tm);
|
||||
date = (date2j( tm->tm_year, tm->tm_mon, tm->tm_mday) - JDATE_2000);
|
||||
return (date);
|
||||
GetCurrentTime(tm);
|
||||
date = (date2j(tm->tm_year, tm->tm_mon, tm->tm_mday) - JDATE_2000);
|
||||
return (date);
|
||||
}
|
||||
|
||||
/* end of file */
|
||||
|
@ -1,19 +1,19 @@
|
||||
#ifndef DATETIME_FUNCTIONS_H
|
||||
#define DATETIME_FUNCTIONS_H
|
||||
|
||||
TimeADT *hhmm_in(char *str);
|
||||
char *hhmm_out(TimeADT *time);
|
||||
TimeADT *hhmm(TimeADT *time);
|
||||
TimeADT *time_difference(TimeADT *time1, TimeADT *time2);
|
||||
int4 time_hours(TimeADT *time);
|
||||
int4 time_minutes(TimeADT *time);
|
||||
int4 time_seconds(TimeADT *time);
|
||||
int4 as_minutes(TimeADT *time);
|
||||
int4 as_seconds(TimeADT *time);
|
||||
int4 date_day(DateADT val);
|
||||
int4 date_month(DateADT val);
|
||||
int4 date_year(DateADT val);
|
||||
TimeADT *currenttime(void);
|
||||
DateADT currentdate(void);
|
||||
TimeADT *hhmm_in(char *str);
|
||||
char *hhmm_out(TimeADT *time);
|
||||
TimeADT *hhmm(TimeADT *time);
|
||||
TimeADT *time_difference(TimeADT *time1, TimeADT *time2);
|
||||
int4 time_hours(TimeADT *time);
|
||||
int4 time_minutes(TimeADT *time);
|
||||
int4 time_seconds(TimeADT *time);
|
||||
int4 as_minutes(TimeADT *time);
|
||||
int4 as_seconds(TimeADT *time);
|
||||
int4 date_day(DateADT val);
|
||||
int4 date_month(DateADT val);
|
||||
int4 date_year(DateADT val);
|
||||
TimeADT *currenttime(void);
|
||||
DateADT currentdate(void);
|
||||
|
||||
#endif
|
||||
|
@ -89,7 +89,7 @@ int64 *dtoi8(float64 val);
|
||||
|
||||
/* int8in()
|
||||
*/
|
||||
int64 *
|
||||
int64 *
|
||||
int8in(char *str)
|
||||
{
|
||||
int64 *result = palloc(sizeof(int64));
|
||||
@ -107,12 +107,12 @@ int8in(char *str)
|
||||
#endif
|
||||
|
||||
return (result);
|
||||
} /* int8in() */
|
||||
} /* int8in() */
|
||||
|
||||
|
||||
/* int8out()
|
||||
*/
|
||||
char *
|
||||
char *
|
||||
int8out(int64 * val)
|
||||
{
|
||||
char *result;
|
||||
@ -137,7 +137,7 @@ int8out(int64 * val)
|
||||
#endif
|
||||
|
||||
return (result);
|
||||
} /* int8out() */
|
||||
} /* int8out() */
|
||||
|
||||
|
||||
/*----------------------------------------------------------
|
||||
@ -151,37 +151,37 @@ bool
|
||||
int8eq(int64 * val1, int64 * val2)
|
||||
{
|
||||
return (*val1 == *val2);
|
||||
} /* int8eq() */
|
||||
} /* int8eq() */
|
||||
|
||||
bool
|
||||
int8ne(int64 * val1, int64 * val2)
|
||||
{
|
||||
return (*val1 != *val2);
|
||||
} /* int8ne() */
|
||||
} /* int8ne() */
|
||||
|
||||
bool
|
||||
int8lt(int64 * val1, int64 * val2)
|
||||
{
|
||||
return (*val1 < *val2);
|
||||
} /* int8lt() */
|
||||
} /* int8lt() */
|
||||
|
||||
bool
|
||||
int8gt(int64 * val1, int64 * val2)
|
||||
{
|
||||
return (*val1 > *val2);
|
||||
} /* int8gt() */
|
||||
} /* int8gt() */
|
||||
|
||||
bool
|
||||
int8le(int64 * val1, int64 * val2)
|
||||
{
|
||||
return (*val1 <= *val2);
|
||||
} /* int8le() */
|
||||
} /* int8le() */
|
||||
|
||||
bool
|
||||
int8ge(int64 * val1, int64 * val2)
|
||||
{
|
||||
return (*val1 >= *val2);
|
||||
} /* int8ge() */
|
||||
} /* int8ge() */
|
||||
|
||||
|
||||
/* int84relop()
|
||||
@ -191,44 +191,44 @@ bool
|
||||
int84eq(int64 * val1, int32 val2)
|
||||
{
|
||||
return (*val1 == val2);
|
||||
} /* int84eq() */
|
||||
} /* int84eq() */
|
||||
|
||||
bool
|
||||
int84ne(int64 * val1, int32 val2)
|
||||
{
|
||||
return (*val1 != val2);
|
||||
} /* int84ne() */
|
||||
} /* int84ne() */
|
||||
|
||||
bool
|
||||
int84lt(int64 * val1, int32 val2)
|
||||
{
|
||||
return (*val1 < val2);
|
||||
} /* int84lt() */
|
||||
} /* int84lt() */
|
||||
|
||||
bool
|
||||
int84gt(int64 * val1, int32 val2)
|
||||
{
|
||||
return (*val1 > val2);
|
||||
} /* int84gt() */
|
||||
} /* int84gt() */
|
||||
|
||||
bool
|
||||
int84le(int64 * val1, int32 val2)
|
||||
{
|
||||
return (*val1 <= val2);
|
||||
} /* int84le() */
|
||||
} /* int84le() */
|
||||
|
||||
bool
|
||||
int84ge(int64 * val1, int32 val2)
|
||||
{
|
||||
return (*val1 >= val2);
|
||||
} /* int84ge() */
|
||||
} /* int84ge() */
|
||||
|
||||
|
||||
/*----------------------------------------------------------
|
||||
* Arithmetic operators on 64-bit integers.
|
||||
*---------------------------------------------------------*/
|
||||
|
||||
int64 *
|
||||
int64 *
|
||||
int8um(int64 * val)
|
||||
{
|
||||
int64 *result = palloc(sizeof(int64));
|
||||
@ -239,9 +239,9 @@ int8um(int64 * val)
|
||||
*result = (-*val);
|
||||
|
||||
return (result);
|
||||
} /* int8um() */
|
||||
} /* int8um() */
|
||||
|
||||
int64 *
|
||||
int64 *
|
||||
int8pl(int64 * val1, int64 * val2)
|
||||
{
|
||||
int64 *result = palloc(sizeof(int64));
|
||||
@ -252,9 +252,9 @@ int8pl(int64 * val1, int64 * val2)
|
||||
*result = *val1 + *val2;
|
||||
|
||||
return (result);
|
||||
} /* int8pl() */
|
||||
} /* int8pl() */
|
||||
|
||||
int64 *
|
||||
int64 *
|
||||
int8mi(int64 * val1, int64 * val2)
|
||||
{
|
||||
int64 *result = palloc(sizeof(int64));
|
||||
@ -265,9 +265,9 @@ int8mi(int64 * val1, int64 * val2)
|
||||
*result = *val1 - *val2;
|
||||
|
||||
return (result);
|
||||
} /* int8mi() */
|
||||
} /* int8mi() */
|
||||
|
||||
int64 *
|
||||
int64 *
|
||||
int8mul(int64 * val1, int64 * val2)
|
||||
{
|
||||
int64 *result = palloc(sizeof(int64));
|
||||
@ -278,9 +278,9 @@ int8mul(int64 * val1, int64 * val2)
|
||||
*result = *val1 * *val2;
|
||||
|
||||
return (result);
|
||||
} /* int8mul() */
|
||||
} /* int8mul() */
|
||||
|
||||
int64 *
|
||||
int64 *
|
||||
int8div(int64 * val1, int64 * val2)
|
||||
{
|
||||
int64 *result = palloc(sizeof(int64));
|
||||
@ -291,14 +291,14 @@ int8div(int64 * val1, int64 * val2)
|
||||
*result = *val1 / *val2;
|
||||
|
||||
return (result);
|
||||
} /* int8div() */
|
||||
} /* int8div() */
|
||||
|
||||
|
||||
/*----------------------------------------------------------
|
||||
* Conversion operators.
|
||||
*---------------------------------------------------------*/
|
||||
|
||||
int64 *
|
||||
int64 *
|
||||
int48(int32 val)
|
||||
{
|
||||
int64 *result = palloc(sizeof(int64));
|
||||
@ -306,7 +306,7 @@ int48(int32 val)
|
||||
*result = val;
|
||||
|
||||
return (result);
|
||||
} /* int48() */
|
||||
} /* int48() */
|
||||
|
||||
int32
|
||||
int84(int64 * val)
|
||||
@ -322,10 +322,10 @@ int84(int64 * val)
|
||||
result = *val;
|
||||
|
||||
return (result);
|
||||
} /* int84() */
|
||||
} /* int84() */
|
||||
|
||||
#if FALSE
|
||||
int64 *
|
||||
int64 *
|
||||
int28 (int16 val)
|
||||
{
|
||||
int64 *result;
|
||||
@ -336,7 +336,7 @@ int28 (int16 val)
|
||||
*result = val;
|
||||
|
||||
return (result);
|
||||
} /* int28() */
|
||||
} /* int28() */
|
||||
|
||||
int16
|
||||
int82(int64 * val)
|
||||
@ -349,7 +349,7 @@ int82(int64 * val)
|
||||
result = *val;
|
||||
|
||||
return (result);
|
||||
} /* int82() */
|
||||
} /* int82() */
|
||||
|
||||
#endif
|
||||
|
||||
@ -361,9 +361,9 @@ i8tod(int64 * val)
|
||||
*result = *val;
|
||||
|
||||
return (result);
|
||||
} /* i8tod() */
|
||||
} /* i8tod() */
|
||||
|
||||
int64 *
|
||||
int64 *
|
||||
dtoi8(float64 val)
|
||||
{
|
||||
int64 *result = palloc(sizeof(int64));
|
||||
@ -374,4 +374,4 @@ dtoi8(float64 val)
|
||||
*result = *val;
|
||||
|
||||
return (result);
|
||||
} /* dtoi8() */
|
||||
} /* dtoi8() */
|
||||
|
@ -1,7 +1,7 @@
|
||||
/*
|
||||
* PostgreSQL type definitions for IP addresses.
|
||||
*
|
||||
* $Id: ip.c,v 1.2 1998/02/14 17:58:03 scrappy Exp $
|
||||
* $Id: ip.c,v 1.3 1998/02/26 04:27:37 momjian Exp $
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
@ -13,83 +13,98 @@
|
||||
* This is the internal storage format for IP addresses:
|
||||
*/
|
||||
|
||||
typedef struct ipaddr {
|
||||
uint32 address;
|
||||
int16 width;
|
||||
} ipaddr;
|
||||
typedef struct ipaddr
|
||||
{
|
||||
uint32 address;
|
||||
int16 width;
|
||||
} ipaddr;
|
||||
|
||||
/*
|
||||
* Various forward declarations:
|
||||
*/
|
||||
|
||||
ipaddr *ipaddr_in(char *str);
|
||||
char *ipaddr_out(ipaddr *addr);
|
||||
ipaddr *ipaddr_in(char *str);
|
||||
char *ipaddr_out(ipaddr * addr);
|
||||
|
||||
bool ipaddr_lt(ipaddr *a1, ipaddr *a2);
|
||||
bool ipaddr_le(ipaddr *a1, ipaddr *a2);
|
||||
bool ipaddr_eq(ipaddr *a1, ipaddr *a2);
|
||||
bool ipaddr_ge(ipaddr *a1, ipaddr *a2);
|
||||
bool ipaddr_gt(ipaddr *a1, ipaddr *a2);
|
||||
bool ipaddr_lt(ipaddr * a1, ipaddr * a2);
|
||||
bool ipaddr_le(ipaddr * a1, ipaddr * a2);
|
||||
bool ipaddr_eq(ipaddr * a1, ipaddr * a2);
|
||||
bool ipaddr_ge(ipaddr * a1, ipaddr * a2);
|
||||
bool ipaddr_gt(ipaddr * a1, ipaddr * a2);
|
||||
|
||||
bool ipaddr_ne(ipaddr *a1, ipaddr *a2);
|
||||
bool ipaddr_ne(ipaddr * a1, ipaddr * a2);
|
||||
|
||||
int4 ipaddr_cmp(ipaddr *a1, ipaddr *a2);
|
||||
int4 ipaddr_cmp(ipaddr * a1, ipaddr * a2);
|
||||
|
||||
bool ipaddr_in_net(ipaddr *a1, ipaddr *a2);
|
||||
ipaddr *ipaddr_mask(ipaddr *a);
|
||||
ipaddr *ipaddr_bcast(ipaddr *a);
|
||||
bool ipaddr_in_net(ipaddr * a1, ipaddr * a2);
|
||||
ipaddr *ipaddr_mask(ipaddr * a);
|
||||
ipaddr *ipaddr_bcast(ipaddr * a);
|
||||
|
||||
/*
|
||||
* Build a mask of a given width:
|
||||
*/
|
||||
|
||||
unsigned long build_mask(unsigned char bits) {
|
||||
unsigned long mask = 0;
|
||||
int i;
|
||||
for (i = 0; i < bits; i++)
|
||||
mask = (mask >> 1) | 0x80000000;
|
||||
return mask;
|
||||
unsigned long
|
||||
build_mask(unsigned char bits)
|
||||
{
|
||||
unsigned long mask = 0;
|
||||
int i;
|
||||
|
||||
for (i = 0; i < bits; i++)
|
||||
mask = (mask >> 1) | 0x80000000;
|
||||
return mask;
|
||||
}
|
||||
|
||||
/*
|
||||
* IP address reader. Note how the count returned by sscanf()
|
||||
* IP address reader. Note how the count returned by sscanf()
|
||||
* is used to determine whether the mask size was specified.
|
||||
*/
|
||||
|
||||
ipaddr *ipaddr_in(char *str) {
|
||||
int a, b, c, d, w;
|
||||
ipaddr *result;
|
||||
int count;
|
||||
ipaddr *
|
||||
ipaddr_in(char *str)
|
||||
{
|
||||
int a,
|
||||
b,
|
||||
c,
|
||||
d,
|
||||
w;
|
||||
ipaddr *result;
|
||||
int count;
|
||||
|
||||
if (strlen(str) > 0) {
|
||||
if (strlen(str) > 0)
|
||||
{
|
||||
|
||||
count = sscanf(str, "%d.%d.%d.%d/%d", &a, &b, &c, &d, &w);
|
||||
count = sscanf(str, "%d.%d.%d.%d/%d", &a, &b, &c, &d, &w);
|
||||
|
||||
if (count < 4) {
|
||||
elog(ERROR, "ipaddr_in: error in parsing \"%s\"", str);
|
||||
return(NULL);
|
||||
}
|
||||
if (count < 4)
|
||||
{
|
||||
elog(ERROR, "ipaddr_in: error in parsing \"%s\"", str);
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
if (count == 4)
|
||||
w = 32;
|
||||
if (count == 4)
|
||||
w = 32;
|
||||
|
||||
if ((a < 0) || (a > 255) || (b < 0) || (b > 255) ||
|
||||
(c < 0) || (c > 255) || (d < 0) || (d > 255) ||
|
||||
(w < 0) || (w > 32)) {
|
||||
elog(ERROR, "ipaddr_in: illegal address \"%s\"", str);
|
||||
return(NULL);
|
||||
}
|
||||
} else {
|
||||
a = b = c = d = w = 0; /* special case for missing address */
|
||||
}
|
||||
if ((a < 0) || (a > 255) || (b < 0) || (b > 255) ||
|
||||
(c < 0) || (c > 255) || (d < 0) || (d > 255) ||
|
||||
(w < 0) || (w > 32))
|
||||
{
|
||||
elog(ERROR, "ipaddr_in: illegal address \"%s\"", str);
|
||||
return (NULL);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
a = b = c = d = w = 0; /* special case for missing address */
|
||||
}
|
||||
|
||||
result = (ipaddr *)palloc(sizeof(ipaddr));
|
||||
result = (ipaddr *) palloc(sizeof(ipaddr));
|
||||
|
||||
result->address = (uint32) ((a<<24)|(b<<16)|(c<<8)|d);
|
||||
result->address &= build_mask(w);
|
||||
result->width = w;
|
||||
result->address = (uint32) ((a << 24) | (b << 16) | (c << 8) | d);
|
||||
result->address &= build_mask(w);
|
||||
result->width = w;
|
||||
|
||||
return(result);
|
||||
return (result);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -97,118 +112,144 @@ ipaddr *ipaddr_in(char *str) {
|
||||
* generated only for subnets, not for plain host addresses.
|
||||
*/
|
||||
|
||||
char *ipaddr_out(ipaddr *addr) {
|
||||
char *result;
|
||||
char *
|
||||
ipaddr_out(ipaddr * addr)
|
||||
{
|
||||
char *result;
|
||||
|
||||
if (addr == NULL)
|
||||
return(NULL);
|
||||
if (addr == NULL)
|
||||
return (NULL);
|
||||
|
||||
result = (char *)palloc(32);
|
||||
result = (char *) palloc(32);
|
||||
|
||||
if (addr->address > 0) {
|
||||
if (addr->width == 32)
|
||||
sprintf(result, "%d.%d.%d.%d",
|
||||
(addr->address >> 24) & 0xff,
|
||||
(addr->address >> 16) & 0xff,
|
||||
(addr->address >> 8) & 0xff,
|
||||
addr->address & 0xff);
|
||||
else
|
||||
sprintf(result, "%d.%d.%d.%d/%d",
|
||||
(addr->address >> 24) & 0xff,
|
||||
(addr->address >> 16) & 0xff,
|
||||
(addr->address >> 8) & 0xff,
|
||||
addr->address & 0xff,
|
||||
addr->width);
|
||||
} else {
|
||||
result[0] = 0; /* special case for missing address */
|
||||
}
|
||||
return(result);
|
||||
if (addr->address > 0)
|
||||
{
|
||||
if (addr->width == 32)
|
||||
sprintf(result, "%d.%d.%d.%d",
|
||||
(addr->address >> 24) & 0xff,
|
||||
(addr->address >> 16) & 0xff,
|
||||
(addr->address >> 8) & 0xff,
|
||||
addr->address & 0xff);
|
||||
else
|
||||
sprintf(result, "%d.%d.%d.%d/%d",
|
||||
(addr->address >> 24) & 0xff,
|
||||
(addr->address >> 16) & 0xff,
|
||||
(addr->address >> 8) & 0xff,
|
||||
addr->address & 0xff,
|
||||
addr->width);
|
||||
}
|
||||
else
|
||||
{
|
||||
result[0] = 0; /* special case for missing address */
|
||||
}
|
||||
return (result);
|
||||
}
|
||||
|
||||
/*
|
||||
* Boolean tests for magnitude.
|
||||
*/
|
||||
|
||||
bool ipaddr_lt(ipaddr *a1, ipaddr *a2) {
|
||||
return (a1->address < a2->address);
|
||||
bool
|
||||
ipaddr_lt(ipaddr * a1, ipaddr * a2)
|
||||
{
|
||||
return (a1->address < a2->address);
|
||||
};
|
||||
|
||||
bool ipaddr_le(ipaddr *a1, ipaddr *a2) {
|
||||
return (a1->address <= a2->address);
|
||||
bool
|
||||
ipaddr_le(ipaddr * a1, ipaddr * a2)
|
||||
{
|
||||
return (a1->address <= a2->address);
|
||||
};
|
||||
|
||||
bool ipaddr_eq(ipaddr *a1, ipaddr *a2) {
|
||||
return (a1->address == a2->address);
|
||||
bool
|
||||
ipaddr_eq(ipaddr * a1, ipaddr * a2)
|
||||
{
|
||||
return (a1->address == a2->address);
|
||||
};
|
||||
|
||||
bool ipaddr_ge(ipaddr *a1, ipaddr *a2) {
|
||||
return (a1->address >= a2->address);
|
||||
bool
|
||||
ipaddr_ge(ipaddr * a1, ipaddr * a2)
|
||||
{
|
||||
return (a1->address >= a2->address);
|
||||
};
|
||||
|
||||
bool ipaddr_gt(ipaddr *a1, ipaddr *a2) {
|
||||
return (a1->address > a2->address);
|
||||
bool
|
||||
ipaddr_gt(ipaddr * a1, ipaddr * a2)
|
||||
{
|
||||
return (a1->address > a2->address);
|
||||
};
|
||||
|
||||
bool ipaddr_ne(ipaddr *a1, ipaddr *a2) {
|
||||
return (a1->address != a2->address);
|
||||
bool
|
||||
ipaddr_ne(ipaddr * a1, ipaddr * a2)
|
||||
{
|
||||
return (a1->address != a2->address);
|
||||
};
|
||||
|
||||
/*
|
||||
* Comparison function for sorting:
|
||||
*/
|
||||
|
||||
int4 ipaddr_cmp(ipaddr *a1, ipaddr *a2) {
|
||||
if (a1->address < a2->address)
|
||||
return -1;
|
||||
else if (a1->address > a2->address)
|
||||
return 1;
|
||||
else
|
||||
return 0;
|
||||
int4
|
||||
ipaddr_cmp(ipaddr * a1, ipaddr * a2)
|
||||
{
|
||||
if (a1->address < a2->address)
|
||||
return -1;
|
||||
else if (a1->address > a2->address)
|
||||
return 1;
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Test whether an address is within a given subnet:
|
||||
*/
|
||||
|
||||
bool ipaddr_in_net(ipaddr *a1, ipaddr *a2) {
|
||||
uint32 maskbits;
|
||||
if (a1->width < a2->width)
|
||||
return FALSE;
|
||||
if ((a1->width == 32) && (a2->width == 32))
|
||||
return ipaddr_eq(a1, a2);
|
||||
maskbits = build_mask(a2->width);
|
||||
if ((a1->address & maskbits) == (a2->address & maskbits))
|
||||
return TRUE;
|
||||
return FALSE;
|
||||
bool
|
||||
ipaddr_in_net(ipaddr * a1, ipaddr * a2)
|
||||
{
|
||||
uint32 maskbits;
|
||||
|
||||
if (a1->width < a2->width)
|
||||
return FALSE;
|
||||
if ((a1->width == 32) && (a2->width == 32))
|
||||
return ipaddr_eq(a1, a2);
|
||||
maskbits = build_mask(a2->width);
|
||||
if ((a1->address & maskbits) == (a2->address & maskbits))
|
||||
return TRUE;
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/*
|
||||
* Pick out just the mask of a network:
|
||||
*/
|
||||
|
||||
ipaddr *ipaddr_mask(ipaddr *a) {
|
||||
ipaddr *result;
|
||||
ipaddr *
|
||||
ipaddr_mask(ipaddr * a)
|
||||
{
|
||||
ipaddr *result;
|
||||
|
||||
result = (ipaddr *)palloc(sizeof(ipaddr));
|
||||
result->address = build_mask(a->width);
|
||||
result->width = 32;
|
||||
result = (ipaddr *) palloc(sizeof(ipaddr));
|
||||
result->address = build_mask(a->width);
|
||||
result->width = 32;
|
||||
|
||||
return result;
|
||||
return result;
|
||||
}
|
||||
|
||||
/*
|
||||
* Return the broadcast address of a network:
|
||||
*/
|
||||
|
||||
ipaddr *ipaddr_bcast(ipaddr *a) {
|
||||
ipaddr *result;
|
||||
ipaddr *
|
||||
ipaddr_bcast(ipaddr * a)
|
||||
{
|
||||
ipaddr *result;
|
||||
|
||||
result = (ipaddr *)palloc(sizeof(ipaddr));
|
||||
result->address = a->address;
|
||||
result->address |= (build_mask(32 - a->width) >> a->width);
|
||||
result->width = 32;
|
||||
result = (ipaddr *) palloc(sizeof(ipaddr));
|
||||
result->address = a->address;
|
||||
result->address |= (build_mask(32 - a->width) >> a->width);
|
||||
result->width = 32;
|
||||
|
||||
return result;
|
||||
return result;
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -1,7 +1,7 @@
|
||||
/*
|
||||
* PostgreSQL type definitions for MAC addresses.
|
||||
*
|
||||
* $Id: mac.c,v 1.2 1998/02/14 17:58:05 scrappy Exp $
|
||||
* $Id: mac.c,v 1.3 1998/02/26 04:27:44 momjian Exp $
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
@ -15,33 +15,34 @@
|
||||
* This is the internal storage format for MAC addresses:
|
||||
*/
|
||||
|
||||
typedef struct macaddr {
|
||||
unsigned char a;
|
||||
unsigned char b;
|
||||
unsigned char c;
|
||||
unsigned char d;
|
||||
unsigned char e;
|
||||
unsigned char f;
|
||||
} macaddr;
|
||||
typedef struct macaddr
|
||||
{
|
||||
unsigned char a;
|
||||
unsigned char b;
|
||||
unsigned char c;
|
||||
unsigned char d;
|
||||
unsigned char e;
|
||||
unsigned char f;
|
||||
} macaddr;
|
||||
|
||||
/*
|
||||
* Various forward declarations:
|
||||
*/
|
||||
|
||||
macaddr *macaddr_in(char *str);
|
||||
char *macaddr_out(macaddr *addr);
|
||||
macaddr *macaddr_in(char *str);
|
||||
char *macaddr_out(macaddr * addr);
|
||||
|
||||
bool macaddr_lt(macaddr *a1, macaddr *a2);
|
||||
bool macaddr_le(macaddr *a1, macaddr *a2);
|
||||
bool macaddr_eq(macaddr *a1, macaddr *a2);
|
||||
bool macaddr_ge(macaddr *a1, macaddr *a2);
|
||||
bool macaddr_gt(macaddr *a1, macaddr *a2);
|
||||
bool macaddr_lt(macaddr * a1, macaddr * a2);
|
||||
bool macaddr_le(macaddr * a1, macaddr * a2);
|
||||
bool macaddr_eq(macaddr * a1, macaddr * a2);
|
||||
bool macaddr_ge(macaddr * a1, macaddr * a2);
|
||||
bool macaddr_gt(macaddr * a1, macaddr * a2);
|
||||
|
||||
bool macaddr_ne(macaddr *a1, macaddr *a2);
|
||||
bool macaddr_ne(macaddr * a1, macaddr * a2);
|
||||
|
||||
int4 macaddr_cmp(macaddr *a1, macaddr *a2);
|
||||
int4 macaddr_cmp(macaddr * a1, macaddr * a2);
|
||||
|
||||
text *macaddr_manuf(macaddr *addr);
|
||||
text *macaddr_manuf(macaddr * addr);
|
||||
|
||||
/*
|
||||
* Utility macros used for sorting and comparing:
|
||||
@ -57,147 +58,185 @@ text *macaddr_manuf(macaddr *addr);
|
||||
* MAC address reader. Accepts several common notations.
|
||||
*/
|
||||
|
||||
macaddr *macaddr_in(char *str) {
|
||||
int a, b, c, d, e, f;
|
||||
macaddr *result;
|
||||
int count;
|
||||
macaddr *
|
||||
macaddr_in(char *str)
|
||||
{
|
||||
int a,
|
||||
b,
|
||||
c,
|
||||
d,
|
||||
e,
|
||||
f;
|
||||
macaddr *result;
|
||||
int count;
|
||||
|
||||
if (strlen(str) > 0) {
|
||||
if (strlen(str) > 0)
|
||||
{
|
||||
|
||||
count = sscanf(str, "%x:%x:%x:%x:%x:%x", &a, &b, &c, &d, &e, &f);
|
||||
if (count != 6)
|
||||
count = sscanf(str, "%x-%x-%x-%x-%x-%x", &a, &b, &c, &d, &e, &f);
|
||||
if (count != 6)
|
||||
count = sscanf(str, "%2x%2x%2x:%2x%2x%2x", &a, &b, &c, &d, &e, &f);
|
||||
if (count != 6)
|
||||
count = sscanf(str, "%2x%2x%2x-%2x%2x%2x", &a, &b, &c, &d, &e, &f);
|
||||
if (count != 6)
|
||||
count = sscanf(str, "%2x%2x.%2x%2x.%2x%2x", &a, &b, &c, &d, &e, &f);
|
||||
|
||||
if (count != 6) {
|
||||
elog(ERROR, "macaddr_in: error in parsing \"%s\"", str);
|
||||
return(NULL);
|
||||
}
|
||||
|
||||
if ((a < 0) || (a > 255) || (b < 0) || (b > 255) ||
|
||||
(c < 0) || (c > 255) || (d < 0) || (d > 255) ||
|
||||
(e < 0) || (e > 255) || (f < 0) || (f > 255)) {
|
||||
elog(ERROR, "macaddr_in: illegal address \"%s\"", str);
|
||||
return(NULL);
|
||||
}
|
||||
} else {
|
||||
a = b = c = d = e = f = 0; /* special case for missing address */
|
||||
}
|
||||
count = sscanf(str, "%x:%x:%x:%x:%x:%x", &a, &b, &c, &d, &e, &f);
|
||||
if (count != 6)
|
||||
count = sscanf(str, "%x-%x-%x-%x-%x-%x", &a, &b, &c, &d, &e, &f);
|
||||
if (count != 6)
|
||||
count = sscanf(str, "%2x%2x%2x:%2x%2x%2x", &a, &b, &c, &d, &e, &f);
|
||||
if (count != 6)
|
||||
count = sscanf(str, "%2x%2x%2x-%2x%2x%2x", &a, &b, &c, &d, &e, &f);
|
||||
if (count != 6)
|
||||
count = sscanf(str, "%2x%2x.%2x%2x.%2x%2x", &a, &b, &c, &d, &e, &f);
|
||||
|
||||
result = (macaddr *)palloc(sizeof(macaddr));
|
||||
if (count != 6)
|
||||
{
|
||||
elog(ERROR, "macaddr_in: error in parsing \"%s\"", str);
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
result->a = a;
|
||||
result->b = b;
|
||||
result->c = c;
|
||||
result->d = d;
|
||||
result->e = e;
|
||||
result->f = f;
|
||||
if ((a < 0) || (a > 255) || (b < 0) || (b > 255) ||
|
||||
(c < 0) || (c > 255) || (d < 0) || (d > 255) ||
|
||||
(e < 0) || (e > 255) || (f < 0) || (f > 255))
|
||||
{
|
||||
elog(ERROR, "macaddr_in: illegal address \"%s\"", str);
|
||||
return (NULL);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
a = b = c = d = e = f = 0; /* special case for missing
|
||||
* address */
|
||||
}
|
||||
|
||||
return(result);
|
||||
result = (macaddr *) palloc(sizeof(macaddr));
|
||||
|
||||
result->a = a;
|
||||
result->b = b;
|
||||
result->c = c;
|
||||
result->d = d;
|
||||
result->e = e;
|
||||
result->f = f;
|
||||
|
||||
return (result);
|
||||
}
|
||||
|
||||
/*
|
||||
* MAC address output function. Fixed format.
|
||||
*/
|
||||
|
||||
char *macaddr_out(macaddr *addr) {
|
||||
char *result;
|
||||
char *
|
||||
macaddr_out(macaddr * addr)
|
||||
{
|
||||
char *result;
|
||||
|
||||
if (addr == NULL)
|
||||
return(NULL);
|
||||
if (addr == NULL)
|
||||
return (NULL);
|
||||
|
||||
result = (char *)palloc(32);
|
||||
result = (char *) palloc(32);
|
||||
|
||||
if ((hibits(addr) > 0) || (lobits(addr) > 0)) {
|
||||
sprintf(result, "%02x:%02x:%02x:%02x:%02x:%02x",
|
||||
addr->a, addr->b, addr->c, addr->d, addr->e, addr->f);
|
||||
} else {
|
||||
result[0] = 0; /* special case for missing address */
|
||||
}
|
||||
return(result);
|
||||
if ((hibits(addr) > 0) || (lobits(addr) > 0))
|
||||
{
|
||||
sprintf(result, "%02x:%02x:%02x:%02x:%02x:%02x",
|
||||
addr->a, addr->b, addr->c, addr->d, addr->e, addr->f);
|
||||
}
|
||||
else
|
||||
{
|
||||
result[0] = 0; /* special case for missing address */
|
||||
}
|
||||
return (result);
|
||||
}
|
||||
|
||||
/*
|
||||
* Boolean tests.
|
||||
*/
|
||||
|
||||
bool macaddr_lt(macaddr *a1, macaddr *a2) {
|
||||
return((hibits(a1) < hibits(a2)) ||
|
||||
((hibits(a1) == hibits(a2)) && lobits(a1) < lobits(a2)));
|
||||
bool
|
||||
macaddr_lt(macaddr * a1, macaddr * a2)
|
||||
{
|
||||
return ((hibits(a1) < hibits(a2)) ||
|
||||
((hibits(a1) == hibits(a2)) && lobits(a1) < lobits(a2)));
|
||||
};
|
||||
|
||||
bool macaddr_le(macaddr *a1, macaddr *a2) {
|
||||
return((hibits(a1) < hibits(a2)) ||
|
||||
((hibits(a1) == hibits(a2)) && lobits(a1) <= lobits(a2)));
|
||||
bool
|
||||
macaddr_le(macaddr * a1, macaddr * a2)
|
||||
{
|
||||
return ((hibits(a1) < hibits(a2)) ||
|
||||
((hibits(a1) == hibits(a2)) && lobits(a1) <= lobits(a2)));
|
||||
};
|
||||
|
||||
bool macaddr_eq(macaddr *a1, macaddr *a2) {
|
||||
return ((hibits(a1) == hibits(a2)) && (lobits(a1) == lobits(a2)));
|
||||
bool
|
||||
macaddr_eq(macaddr * a1, macaddr * a2)
|
||||
{
|
||||
return ((hibits(a1) == hibits(a2)) && (lobits(a1) == lobits(a2)));
|
||||
};
|
||||
|
||||
bool macaddr_ge(macaddr *a1, macaddr *a2) {
|
||||
return((hibits(a1) > hibits(a2)) ||
|
||||
((hibits(a1) == hibits(a2)) && lobits(a1) >= lobits(a2)));
|
||||
bool
|
||||
macaddr_ge(macaddr * a1, macaddr * a2)
|
||||
{
|
||||
return ((hibits(a1) > hibits(a2)) ||
|
||||
((hibits(a1) == hibits(a2)) && lobits(a1) >= lobits(a2)));
|
||||
};
|
||||
|
||||
bool macaddr_gt(macaddr *a1, macaddr *a2) {
|
||||
return((hibits(a1) > hibits(a2)) ||
|
||||
((hibits(a1) == hibits(a2)) && lobits(a1) > lobits(a2)));
|
||||
bool
|
||||
macaddr_gt(macaddr * a1, macaddr * a2)
|
||||
{
|
||||
return ((hibits(a1) > hibits(a2)) ||
|
||||
((hibits(a1) == hibits(a2)) && lobits(a1) > lobits(a2)));
|
||||
};
|
||||
|
||||
bool macaddr_ne(macaddr *a1, macaddr *a2) {
|
||||
return ((hibits(a1) != hibits(a2)) || (lobits(a1) != lobits(a2)));
|
||||
bool
|
||||
macaddr_ne(macaddr * a1, macaddr * a2)
|
||||
{
|
||||
return ((hibits(a1) != hibits(a2)) || (lobits(a1) != lobits(a2)));
|
||||
};
|
||||
|
||||
/*
|
||||
* Comparison function for sorting:
|
||||
*/
|
||||
|
||||
int4 macaddr_cmp(macaddr *a1, macaddr *a2) {
|
||||
if (hibits(a1) < hibits(a2))
|
||||
return -1;
|
||||
else if (hibits(a1) > hibits(a2))
|
||||
return 1;
|
||||
else if (lobits(a1) < lobits(a2))
|
||||
return -1;
|
||||
else if (lobits(a1) > lobits(a2))
|
||||
return 1;
|
||||
else
|
||||
return 0;
|
||||
int4
|
||||
macaddr_cmp(macaddr * a1, macaddr * a2)
|
||||
{
|
||||
if (hibits(a1) < hibits(a2))
|
||||
return -1;
|
||||
else if (hibits(a1) > hibits(a2))
|
||||
return 1;
|
||||
else if (lobits(a1) < lobits(a2))
|
||||
return -1;
|
||||
else if (lobits(a1) > lobits(a2))
|
||||
return 1;
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* The special manufacturer fetching function. See "mac.h".
|
||||
*/
|
||||
|
||||
text *macaddr_manuf(macaddr *addr) {
|
||||
manufacturer *manuf;
|
||||
int length;
|
||||
text *result;
|
||||
text *
|
||||
macaddr_manuf(macaddr * addr)
|
||||
{
|
||||
manufacturer *manuf;
|
||||
int length;
|
||||
text *result;
|
||||
|
||||
for (manuf = manufacturers; manuf->name != NULL; manuf++) {
|
||||
if ((manuf->a == addr->a) &&
|
||||
(manuf->b == addr->b) &&
|
||||
(manuf->c == addr->c))
|
||||
break;
|
||||
}
|
||||
if (manuf->name == NULL) {
|
||||
result = palloc(VARHDRSZ + 1);
|
||||
memset(result, 0, VARHDRSZ + 1);
|
||||
VARSIZE(result) = VARHDRSZ + 1;
|
||||
} else {
|
||||
length = strlen(manuf->name) + 1;
|
||||
result = palloc(length + VARHDRSZ);
|
||||
memset(result, 0, length + VARHDRSZ);
|
||||
VARSIZE(result) = length + VARHDRSZ;
|
||||
memcpy(VARDATA(result), manuf->name, length);
|
||||
}
|
||||
return result;
|
||||
for (manuf = manufacturers; manuf->name != NULL; manuf++)
|
||||
{
|
||||
if ((manuf->a == addr->a) &&
|
||||
(manuf->b == addr->b) &&
|
||||
(manuf->c == addr->c))
|
||||
break;
|
||||
}
|
||||
if (manuf->name == NULL)
|
||||
{
|
||||
result = palloc(VARHDRSZ + 1);
|
||||
memset(result, 0, VARHDRSZ + 1);
|
||||
VARSIZE(result) = VARHDRSZ + 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
length = strlen(manuf->name) + 1;
|
||||
result = palloc(length + VARHDRSZ);
|
||||
memset(result, 0, length + VARHDRSZ);
|
||||
VARSIZE(result) = length + VARHDRSZ;
|
||||
memcpy(VARDATA(result), manuf->name, length);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -1,130 +1,131 @@
|
||||
/*
|
||||
* PostgreSQL type definitions for MAC addresses.
|
||||
*
|
||||
* $Id: mac.h,v 1.2 1998/02/14 17:58:07 scrappy Exp $
|
||||
* $Id: mac.h,v 1.3 1998/02/26 04:27:50 momjian Exp $
|
||||
*/
|
||||
|
||||
typedef struct manufacturer {
|
||||
unsigned char a;
|
||||
unsigned char b;
|
||||
unsigned char c;
|
||||
char *name;
|
||||
} manufacturer;
|
||||
typedef struct manufacturer
|
||||
{
|
||||
unsigned char a;
|
||||
unsigned char b;
|
||||
unsigned char c;
|
||||
char *name;
|
||||
} manufacturer;
|
||||
|
||||
manufacturer manufacturers[] = {
|
||||
{0x00, 0x00, 0x0C, "Cisco"},
|
||||
{0x00, 0x00, 0x0E, "Fujitsu"},
|
||||
{0x00, 0x00, 0x0F, "NeXT"},
|
||||
{0x00, 0x00, 0x10, "Sytek"},
|
||||
{0x00, 0x00, 0x1D, "Cabletron"},
|
||||
{0x00, 0x00, 0x20, "DIAB"},
|
||||
{0x00, 0x00, 0x22, "Visual Technology"},
|
||||
{0x00, 0x00, 0x2A, "TRW"},
|
||||
{0x00, 0x00, 0x32, "GPT Limited"},
|
||||
{0x00, 0x00, 0x5A, "S & Koch"},
|
||||
{0x00, 0x00, 0x5E, "IANA"},
|
||||
{0x00, 0x00, 0x65, "Network General"},
|
||||
{0x00, 0x00, 0x6B, "MIPS"},
|
||||
{0x00, 0x00, 0x77, "MIPS"},
|
||||
{0x00, 0x00, 0x7A, "Ardent"},
|
||||
{0x00, 0x00, 0x89, "Cayman Systems"},
|
||||
{0x00, 0x00, 0x93, "Proteon"},
|
||||
{0x00, 0x00, 0x9F, "Ameristar Technology"},
|
||||
{0x00, 0x00, 0xA2, "Wellfleet"},
|
||||
{0x00, 0x00, 0xA3, "Network Application Technology"},
|
||||
{0x00, 0x00, 0xA6, "Network General"},
|
||||
{0x00, 0x00, 0xA7, "NCD"},
|
||||
{0x00, 0x00, 0xA9, "Network Systems"},
|
||||
{0x00, 0x00, 0xAA, "Xerox"},
|
||||
{0x00, 0x00, 0xB3, "CIMLinc"},
|
||||
{0x00, 0x00, 0xB7, "Dove Fastnet"},
|
||||
{0x00, 0x00, 0xBC, "Allen-Bradley"},
|
||||
{0x00, 0x00, 0xC0, "Western Digital"},
|
||||
{0x00, 0x00, 0xC5, "Farallon"},
|
||||
{0x00, 0x00, 0xC6, "Hewlett-Packard"},
|
||||
{0x00, 0x00, 0xC8, "Altos"},
|
||||
{0x00, 0x00, 0xC9, "Emulex"},
|
||||
{0x00, 0x00, 0xD7, "Dartmouth College"},
|
||||
{0x00, 0x00, 0xD8, "3Com (?)"},
|
||||
{0x00, 0x00, 0xDD, "Gould"},
|
||||
{0x00, 0x00, 0xDE, "Unigraph"},
|
||||
{0x00, 0x00, 0xE2, "Acer Counterpoint"},
|
||||
{0x00, 0x00, 0xEF, "Alantec"},
|
||||
{0x00, 0x00, 0xFD, "High Level Hardware"},
|
||||
{0x00, 0x01, 0x02, "BBN internal usage"},
|
||||
{0x00, 0x20, 0xAF, "3Com"},
|
||||
{0x00, 0x17, 0x00, "Kabel"},
|
||||
{0x00, 0x80, 0x64, "Wyse Technology"},
|
||||
{0x00, 0x80, 0x2B, "IMAC (?)"},
|
||||
{0x00, 0x80, 0x2D, "Xylogics, Inc."},
|
||||
{0x00, 0x80, 0x8C, "Frontier Software Development"},
|
||||
{0x00, 0x80, 0xC2, "IEEE 802.1 Committee"},
|
||||
{0x00, 0x80, 0xD3, "Shiva"},
|
||||
{0x00, 0xAA, 0x00, "Intel"},
|
||||
{0x00, 0xDD, 0x00, "Ungermann-Bass"},
|
||||
{0x00, 0xDD, 0x01, "Ungermann-Bass"},
|
||||
{0x02, 0x07, 0x01, "Racal InterLan"},
|
||||
{0x02, 0x04, 0x06, "BBN internal usage"},
|
||||
{0x02, 0x60, 0x86, "Satelcom MegaPac"},
|
||||
{0x02, 0x60, 0x8C, "3Com"},
|
||||
{0x02, 0xCF, 0x1F, "CMC"},
|
||||
{0x08, 0x00, 0x02, "3Com"},
|
||||
{0x08, 0x00, 0x03, "ACC"},
|
||||
{0x08, 0x00, 0x05, "Symbolics"},
|
||||
{0x08, 0x00, 0x08, "BBN"},
|
||||
{0x08, 0x00, 0x09, "Hewlett-Packard"},
|
||||
{0x08, 0x00, 0x0A, "Nestar Systems"},
|
||||
{0x08, 0x00, 0x0B, "Unisys"},
|
||||
{0x08, 0x00, 0x11, "Tektronix"},
|
||||
{0x08, 0x00, 0x14, "Excelan"},
|
||||
{0x08, 0x00, 0x17, "NSC"},
|
||||
{0x08, 0x00, 0x1A, "Data General"},
|
||||
{0x08, 0x00, 0x1B, "Data General"},
|
||||
{0x08, 0x00, 0x1E, "Apollo"},
|
||||
{0x08, 0x00, 0x20, "Sun"},
|
||||
{0x08, 0x00, 0x22, "NBI"},
|
||||
{0x08, 0x00, 0x25, "CDC"},
|
||||
{0x08, 0x00, 0x26, "Norsk Data"},
|
||||
{0x08, 0x00, 0x27, "PCS Computer Systems GmbH"},
|
||||
{0x08, 0x00, 0x28, "Texas Instruments"},
|
||||
{0x08, 0x00, 0x2B, "DEC"},
|
||||
{0x08, 0x00, 0x2E, "Metaphor"},
|
||||
{0x08, 0x00, 0x2F, "Prime Computer"},
|
||||
{0x08, 0x00, 0x36, "Intergraph"},
|
||||
{0x08, 0x00, 0x37, "Fujitsu-Xerox"},
|
||||
{0x08, 0x00, 0x38, "Bull"},
|
||||
{0x08, 0x00, 0x39, "Spider Systems"},
|
||||
{0x08, 0x00, 0x41, "DCA Digital Comm. Assoc."},
|
||||
{0x08, 0x00, 0x45, "Xylogics (?)"},
|
||||
{0x08, 0x00, 0x46, "Sony"},
|
||||
{0x08, 0x00, 0x47, "Sequent"},
|
||||
{0x08, 0x00, 0x49, "Univation"},
|
||||
{0x08, 0x00, 0x4C, "Encore"},
|
||||
{0x08, 0x00, 0x4E, "BICC"},
|
||||
{0x08, 0x00, 0x56, "Stanford University"},
|
||||
{0x08, 0x00, 0x58, "DECsystem 20 (?)"},
|
||||
{0x08, 0x00, 0x5A, "IBM"},
|
||||
{0x08, 0x00, 0x67, "Comdesign"},
|
||||
{0x08, 0x00, 0x68, "Ridge"},
|
||||
{0x08, 0x00, 0x69, "Silicon Graphics"},
|
||||
{0x08, 0x00, 0x6E, "Concurrent"},
|
||||
{0x08, 0x00, 0x75, "DDE"},
|
||||
{0x08, 0x00, 0x7C, "Vitalink"},
|
||||
{0x08, 0x00, 0x80, "XIOS"},
|
||||
{0x08, 0x00, 0x86, "Imagen/QMS"},
|
||||
{0x08, 0x00, 0x87, "Xyplex"},
|
||||
{0x08, 0x00, 0x89, "Kinetics"},
|
||||
{0x08, 0x00, 0x8B, "Pyramid"},
|
||||
{0x08, 0x00, 0x8D, "XyVision"},
|
||||
{0x08, 0x00, 0x90, "Retix Inc"},
|
||||
{0x48, 0x44, 0x53, "HDS (?)"},
|
||||
{0x80, 0x00, 0x10, "AT&T"},
|
||||
{0xAA, 0x00, 0x00, "DEC"},
|
||||
{0xAA, 0x00, 0x01, "DEC"},
|
||||
{0xAA, 0x00, 0x02, "DEC"},
|
||||
{0xAA, 0x00, 0x03, "DEC"},
|
||||
{0xAA, 0x00, 0x04, "DEC"},
|
||||
{0x00, 0x00, 0x00, NULL}
|
||||
{0x00, 0x00, 0x0C, "Cisco"},
|
||||
{0x00, 0x00, 0x0E, "Fujitsu"},
|
||||
{0x00, 0x00, 0x0F, "NeXT"},
|
||||
{0x00, 0x00, 0x10, "Sytek"},
|
||||
{0x00, 0x00, 0x1D, "Cabletron"},
|
||||
{0x00, 0x00, 0x20, "DIAB"},
|
||||
{0x00, 0x00, 0x22, "Visual Technology"},
|
||||
{0x00, 0x00, 0x2A, "TRW"},
|
||||
{0x00, 0x00, 0x32, "GPT Limited"},
|
||||
{0x00, 0x00, 0x5A, "S & Koch"},
|
||||
{0x00, 0x00, 0x5E, "IANA"},
|
||||
{0x00, 0x00, 0x65, "Network General"},
|
||||
{0x00, 0x00, 0x6B, "MIPS"},
|
||||
{0x00, 0x00, 0x77, "MIPS"},
|
||||
{0x00, 0x00, 0x7A, "Ardent"},
|
||||
{0x00, 0x00, 0x89, "Cayman Systems"},
|
||||
{0x00, 0x00, 0x93, "Proteon"},
|
||||
{0x00, 0x00, 0x9F, "Ameristar Technology"},
|
||||
{0x00, 0x00, 0xA2, "Wellfleet"},
|
||||
{0x00, 0x00, 0xA3, "Network Application Technology"},
|
||||
{0x00, 0x00, 0xA6, "Network General"},
|
||||
{0x00, 0x00, 0xA7, "NCD"},
|
||||
{0x00, 0x00, 0xA9, "Network Systems"},
|
||||
{0x00, 0x00, 0xAA, "Xerox"},
|
||||
{0x00, 0x00, 0xB3, "CIMLinc"},
|
||||
{0x00, 0x00, 0xB7, "Dove Fastnet"},
|
||||
{0x00, 0x00, 0xBC, "Allen-Bradley"},
|
||||
{0x00, 0x00, 0xC0, "Western Digital"},
|
||||
{0x00, 0x00, 0xC5, "Farallon"},
|
||||
{0x00, 0x00, 0xC6, "Hewlett-Packard"},
|
||||
{0x00, 0x00, 0xC8, "Altos"},
|
||||
{0x00, 0x00, 0xC9, "Emulex"},
|
||||
{0x00, 0x00, 0xD7, "Dartmouth College"},
|
||||
{0x00, 0x00, 0xD8, "3Com (?)"},
|
||||
{0x00, 0x00, 0xDD, "Gould"},
|
||||
{0x00, 0x00, 0xDE, "Unigraph"},
|
||||
{0x00, 0x00, 0xE2, "Acer Counterpoint"},
|
||||
{0x00, 0x00, 0xEF, "Alantec"},
|
||||
{0x00, 0x00, 0xFD, "High Level Hardware"},
|
||||
{0x00, 0x01, 0x02, "BBN internal usage"},
|
||||
{0x00, 0x20, 0xAF, "3Com"},
|
||||
{0x00, 0x17, 0x00, "Kabel"},
|
||||
{0x00, 0x80, 0x64, "Wyse Technology"},
|
||||
{0x00, 0x80, 0x2B, "IMAC (?)"},
|
||||
{0x00, 0x80, 0x2D, "Xylogics, Inc."},
|
||||
{0x00, 0x80, 0x8C, "Frontier Software Development"},
|
||||
{0x00, 0x80, 0xC2, "IEEE 802.1 Committee"},
|
||||
{0x00, 0x80, 0xD3, "Shiva"},
|
||||
{0x00, 0xAA, 0x00, "Intel"},
|
||||
{0x00, 0xDD, 0x00, "Ungermann-Bass"},
|
||||
{0x00, 0xDD, 0x01, "Ungermann-Bass"},
|
||||
{0x02, 0x07, 0x01, "Racal InterLan"},
|
||||
{0x02, 0x04, 0x06, "BBN internal usage"},
|
||||
{0x02, 0x60, 0x86, "Satelcom MegaPac"},
|
||||
{0x02, 0x60, 0x8C, "3Com"},
|
||||
{0x02, 0xCF, 0x1F, "CMC"},
|
||||
{0x08, 0x00, 0x02, "3Com"},
|
||||
{0x08, 0x00, 0x03, "ACC"},
|
||||
{0x08, 0x00, 0x05, "Symbolics"},
|
||||
{0x08, 0x00, 0x08, "BBN"},
|
||||
{0x08, 0x00, 0x09, "Hewlett-Packard"},
|
||||
{0x08, 0x00, 0x0A, "Nestar Systems"},
|
||||
{0x08, 0x00, 0x0B, "Unisys"},
|
||||
{0x08, 0x00, 0x11, "Tektronix"},
|
||||
{0x08, 0x00, 0x14, "Excelan"},
|
||||
{0x08, 0x00, 0x17, "NSC"},
|
||||
{0x08, 0x00, 0x1A, "Data General"},
|
||||
{0x08, 0x00, 0x1B, "Data General"},
|
||||
{0x08, 0x00, 0x1E, "Apollo"},
|
||||
{0x08, 0x00, 0x20, "Sun"},
|
||||
{0x08, 0x00, 0x22, "NBI"},
|
||||
{0x08, 0x00, 0x25, "CDC"},
|
||||
{0x08, 0x00, 0x26, "Norsk Data"},
|
||||
{0x08, 0x00, 0x27, "PCS Computer Systems GmbH"},
|
||||
{0x08, 0x00, 0x28, "Texas Instruments"},
|
||||
{0x08, 0x00, 0x2B, "DEC"},
|
||||
{0x08, 0x00, 0x2E, "Metaphor"},
|
||||
{0x08, 0x00, 0x2F, "Prime Computer"},
|
||||
{0x08, 0x00, 0x36, "Intergraph"},
|
||||
{0x08, 0x00, 0x37, "Fujitsu-Xerox"},
|
||||
{0x08, 0x00, 0x38, "Bull"},
|
||||
{0x08, 0x00, 0x39, "Spider Systems"},
|
||||
{0x08, 0x00, 0x41, "DCA Digital Comm. Assoc."},
|
||||
{0x08, 0x00, 0x45, "Xylogics (?)"},
|
||||
{0x08, 0x00, 0x46, "Sony"},
|
||||
{0x08, 0x00, 0x47, "Sequent"},
|
||||
{0x08, 0x00, 0x49, "Univation"},
|
||||
{0x08, 0x00, 0x4C, "Encore"},
|
||||
{0x08, 0x00, 0x4E, "BICC"},
|
||||
{0x08, 0x00, 0x56, "Stanford University"},
|
||||
{0x08, 0x00, 0x58, "DECsystem 20 (?)"},
|
||||
{0x08, 0x00, 0x5A, "IBM"},
|
||||
{0x08, 0x00, 0x67, "Comdesign"},
|
||||
{0x08, 0x00, 0x68, "Ridge"},
|
||||
{0x08, 0x00, 0x69, "Silicon Graphics"},
|
||||
{0x08, 0x00, 0x6E, "Concurrent"},
|
||||
{0x08, 0x00, 0x75, "DDE"},
|
||||
{0x08, 0x00, 0x7C, "Vitalink"},
|
||||
{0x08, 0x00, 0x80, "XIOS"},
|
||||
{0x08, 0x00, 0x86, "Imagen/QMS"},
|
||||
{0x08, 0x00, 0x87, "Xyplex"},
|
||||
{0x08, 0x00, 0x89, "Kinetics"},
|
||||
{0x08, 0x00, 0x8B, "Pyramid"},
|
||||
{0x08, 0x00, 0x8D, "XyVision"},
|
||||
{0x08, 0x00, 0x90, "Retix Inc"},
|
||||
{0x48, 0x44, 0x53, "HDS (?)"},
|
||||
{0x80, 0x00, 0x10, "AT&T"},
|
||||
{0xAA, 0x00, 0x00, "DEC"},
|
||||
{0xAA, 0x00, 0x01, "DEC"},
|
||||
{0xAA, 0x00, 0x02, "DEC"},
|
||||
{0xAA, 0x00, 0x03, "DEC"},
|
||||
{0xAA, 0x00, 0x04, "DEC"},
|
||||
{0x00, 0x00, 0x00, NULL}
|
||||
};
|
||||
|
||||
/*
|
||||
|
@ -9,19 +9,19 @@
|
||||
#include "postgres.h"
|
||||
#include "assert_test.h"
|
||||
|
||||
extern int assertTest(int val);
|
||||
extern int assertEnable(int val);
|
||||
extern int assertTest(int val);
|
||||
extern int assertEnable(int val);
|
||||
|
||||
int
|
||||
assert_enable(int val)
|
||||
{
|
||||
return assertEnable(val);
|
||||
return assertEnable(val);
|
||||
}
|
||||
|
||||
int
|
||||
assert_test(int val)
|
||||
{
|
||||
return assertTest(val);
|
||||
return assertTest(val);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -29,14 +29,14 @@ assert_test(int val)
|
||||
-- Enable/disable Postgres assert checking.
|
||||
--
|
||||
create function assert_enable(int4) returns int4
|
||||
as '/usr/local/pgsql/lib/assert_test.so'
|
||||
language 'C';
|
||||
as '/usr/local/pgsql/lib/assert_test.so'
|
||||
language 'C';
|
||||
|
||||
-- Test Postgres assert checking.
|
||||
--
|
||||
create function assert_test(int4) returns int4
|
||||
as '/usr/local/pgsql/lib/assert_test.so'
|
||||
language 'C';
|
||||
as '/usr/local/pgsql/lib/assert_test.so'
|
||||
language 'C';
|
||||
|
||||
*/
|
||||
|
||||
|
@ -1,7 +1,7 @@
|
||||
#ifndef ASSERT_TEST_H
|
||||
#define ASSERT_TEST_H
|
||||
|
||||
int assert_enable(int val);
|
||||
int assert_test(int val);
|
||||
int assert_enable(int val);
|
||||
int assert_test(int val);
|
||||
|
||||
#endif
|
||||
|
@ -13,38 +13,38 @@
|
||||
|
||||
#include "misc_utils.h"
|
||||
|
||||
extern int ExecutorLimit(int limit);
|
||||
extern int ExecutorLimit(int limit);
|
||||
extern void Async_Unlisten(char *relname, int pid);
|
||||
|
||||
int
|
||||
query_limit(int limit)
|
||||
{
|
||||
return ExecutorLimit(limit);
|
||||
return ExecutorLimit(limit);
|
||||
}
|
||||
|
||||
int
|
||||
backend_pid()
|
||||
{
|
||||
return getpid();
|
||||
return getpid();
|
||||
}
|
||||
|
||||
int
|
||||
unlisten(char *relname)
|
||||
{
|
||||
Async_Unlisten(relname, getpid());
|
||||
return 0;
|
||||
Async_Unlisten(relname, getpid());
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
max(int x, int y)
|
||||
{
|
||||
return ((x > y) ? x : y);
|
||||
return ((x > y) ? x : y);
|
||||
}
|
||||
|
||||
int
|
||||
min(int x, int y)
|
||||
{
|
||||
return ((x < y) ? x : y);
|
||||
return ((x < y) ? x : y);
|
||||
}
|
||||
|
||||
/* end of file */
|
||||
|
@ -1,10 +1,10 @@
|
||||
#ifndef MISC_UTILS_H
|
||||
#define MISC_UTILS_H
|
||||
|
||||
int query_limit(int limit);
|
||||
int backend_pid(void);
|
||||
int unlisten(char *relname);
|
||||
int max(int x, int y);
|
||||
int min(int x, int y);
|
||||
int query_limit(int limit);
|
||||
int backend_pid(void);
|
||||
int unlisten(char *relname);
|
||||
int max(int x, int y);
|
||||
int min(int x, int y);
|
||||
|
||||
#endif
|
||||
|
@ -30,7 +30,7 @@ static int tuple;
|
||||
** connectdb - returns PGconn structure
|
||||
**
|
||||
*/
|
||||
PGconn *
|
||||
PGconn *
|
||||
connectdb(char *dbName,
|
||||
char *pghost,
|
||||
char *pgport,
|
||||
|
@ -12,30 +12,30 @@
|
||||
|
||||
#include "set_sequence.h"
|
||||
|
||||
extern int setval(struct varlena *seqin, int4 val);
|
||||
extern int setval(struct varlena * seqin, int4 val);
|
||||
|
||||
int
|
||||
set_currval(struct varlena *sequence, int4 nextval)
|
||||
set_currval(struct varlena * sequence, int4 nextval)
|
||||
{
|
||||
return setval(sequence, nextval);
|
||||
return setval(sequence, nextval);
|
||||
}
|
||||
|
||||
int
|
||||
next_id(struct varlena *sequence)
|
||||
next_id(struct varlena * sequence)
|
||||
{
|
||||
return nextval(sequence);
|
||||
return nextval(sequence);
|
||||
}
|
||||
|
||||
int
|
||||
last_id(struct varlena *sequence)
|
||||
last_id(struct varlena * sequence)
|
||||
{
|
||||
return currval(sequence);
|
||||
return currval(sequence);
|
||||
}
|
||||
|
||||
int
|
||||
set_last_id(struct varlena *sequence, int4 nextval)
|
||||
set_last_id(struct varlena * sequence, int4 nextval)
|
||||
{
|
||||
return setval(sequence, nextval);
|
||||
return setval(sequence, nextval);
|
||||
}
|
||||
|
||||
/* end of file */
|
||||
|
@ -1,9 +1,9 @@
|
||||
#ifndef SET_SEQUENCE_H
|
||||
#define SET_SEQUENCE_H
|
||||
|
||||
int set_currval(struct varlena *sequence, int4 nextval);
|
||||
int next_id(struct varlena *sequence);
|
||||
int last_id(struct varlena *sequence);
|
||||
int set_last_id(struct varlena *sequence, int4 nextval);
|
||||
int set_currval(struct varlena * sequence, int4 nextval);
|
||||
int next_id(struct varlena * sequence);
|
||||
int last_id(struct varlena * sequence);
|
||||
int set_last_id(struct varlena * sequence, int4 nextval);
|
||||
|
||||
#endif
|
||||
|
@ -13,7 +13,7 @@
|
||||
/* prototype for soundex function */
|
||||
char *soundex(char *instr, char *outstr);
|
||||
|
||||
text *
|
||||
text *
|
||||
text_soundex(text *t)
|
||||
{
|
||||
/* ABCDEFGHIJKLMNOPQRSTUVWXYZ */
|
||||
@ -47,7 +47,7 @@ text_soundex(text *t)
|
||||
return (new_t);
|
||||
}
|
||||
|
||||
char *
|
||||
char *
|
||||
soundex(char *instr, char *outstr)
|
||||
{ /* ABCDEFGHIJKLMNOPQRSTUVWXYZ */
|
||||
char *table = "01230120022455012623010202";
|
||||
|
@ -2,9 +2,9 @@
|
||||
#include "executor/spi.h" /* this is what you need to work with SPI */
|
||||
#include "commands/trigger.h" /* -"- and triggers */
|
||||
|
||||
HeapTuple autoinc(void);
|
||||
HeapTuple autoinc(void);
|
||||
|
||||
extern int4 nextval(struct varlena * seqin);
|
||||
extern int4 nextval(struct varlena * seqin);
|
||||
|
||||
HeapTuple
|
||||
autoinc()
|
||||
@ -28,73 +28,73 @@ autoinc()
|
||||
elog(ERROR, "autoinc: can't process STATEMENT events");
|
||||
if (TRIGGER_FIRED_AFTER(CurrentTriggerData->tg_event))
|
||||
elog(ERROR, "autoinc: must be fired before event");
|
||||
|
||||
|
||||
if (TRIGGER_FIRED_BY_INSERT(CurrentTriggerData->tg_event))
|
||||
rettuple = CurrentTriggerData->tg_trigtuple;
|
||||
else if (TRIGGER_FIRED_BY_UPDATE(CurrentTriggerData->tg_event))
|
||||
rettuple = CurrentTriggerData->tg_newtuple;
|
||||
else
|
||||
elog(ERROR, "autoinc: can't process DELETE events");
|
||||
|
||||
|
||||
rel = CurrentTriggerData->tg_relation;
|
||||
relname = SPI_getrelname(rel);
|
||||
|
||||
|
||||
trigger = CurrentTriggerData->tg_trigger;
|
||||
|
||||
nargs = trigger->tgnargs;
|
||||
if (nargs <= 0 || nargs % 2 != 0)
|
||||
elog(ERROR, "autoinc (%s): even number gt 0 of arguments was expected", relname);
|
||||
|
||||
|
||||
args = trigger->tgargs;
|
||||
tupdesc = rel->rd_att;
|
||||
|
||||
|
||||
CurrentTriggerData = NULL;
|
||||
|
||||
chattrs = (int *) palloc (nargs/2 * sizeof (int));
|
||||
newvals = (Datum *) palloc (nargs/2 * sizeof (Datum));
|
||||
|
||||
for (i = 0; i < nargs; )
|
||||
|
||||
chattrs = (int *) palloc(nargs / 2 * sizeof(int));
|
||||
newvals = (Datum *) palloc(nargs / 2 * sizeof(Datum));
|
||||
|
||||
for (i = 0; i < nargs;)
|
||||
{
|
||||
struct varlena *seqname;
|
||||
int attnum = SPI_fnumber (tupdesc, args[i]);
|
||||
int32 val;
|
||||
|
||||
if ( attnum < 0 )
|
||||
struct varlena *seqname;
|
||||
int attnum = SPI_fnumber(tupdesc, args[i]);
|
||||
int32 val;
|
||||
|
||||
if (attnum < 0)
|
||||
elog(ERROR, "autoinc (%s): there is no attribute %s", relname, args[i]);
|
||||
if (SPI_gettypeid (tupdesc, attnum) != INT4OID)
|
||||
elog(ERROR, "autoinc (%s): attribute %s must be of INT4 type",
|
||||
relname, args[i]);
|
||||
|
||||
val = DatumGetInt32 (SPI_getbinval (rettuple, tupdesc, attnum, &isnull));
|
||||
|
||||
if (SPI_gettypeid(tupdesc, attnum) != INT4OID)
|
||||
elog(ERROR, "autoinc (%s): attribute %s must be of INT4 type",
|
||||
relname, args[i]);
|
||||
|
||||
val = DatumGetInt32(SPI_getbinval(rettuple, tupdesc, attnum, &isnull));
|
||||
|
||||
if (!isnull && val != 0)
|
||||
{
|
||||
i += 2;
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
i++;
|
||||
chattrs[chnattrs] = attnum;
|
||||
seqname = textin (args[i]);
|
||||
newvals[chnattrs] = Int32GetDatum (nextval (seqname));
|
||||
if ( DatumGetInt32 (newvals[chnattrs]) == 0 )
|
||||
newvals[chnattrs] = Int32GetDatum (nextval (seqname));
|
||||
pfree (seqname);
|
||||
seqname = textin(args[i]);
|
||||
newvals[chnattrs] = Int32GetDatum(nextval(seqname));
|
||||
if (DatumGetInt32(newvals[chnattrs]) == 0)
|
||||
newvals[chnattrs] = Int32GetDatum(nextval(seqname));
|
||||
pfree(seqname);
|
||||
chnattrs++;
|
||||
i++;
|
||||
}
|
||||
|
||||
|
||||
if (chnattrs > 0)
|
||||
{
|
||||
rettuple = SPI_modifytuple (rel, rettuple, chnattrs, chattrs, newvals, NULL);
|
||||
if ( rettuple == NULL )
|
||||
elog (ERROR, "autoinc (%s): %d returned by SPI_modifytuple",
|
||||
relname, SPI_result);
|
||||
rettuple = SPI_modifytuple(rel, rettuple, chnattrs, chattrs, newvals, NULL);
|
||||
if (rettuple == NULL)
|
||||
elog(ERROR, "autoinc (%s): %d returned by SPI_modifytuple",
|
||||
relname, SPI_result);
|
||||
}
|
||||
|
||||
pfree (relname);
|
||||
pfree (chattrs);
|
||||
pfree (newvals);
|
||||
|
||||
pfree(relname);
|
||||
pfree(chattrs);
|
||||
pfree(newvals);
|
||||
|
||||
return (rettuple);
|
||||
}
|
||||
|
@ -7,71 +7,71 @@
|
||||
*/
|
||||
|
||||
#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() */
|
||||
|
||||
HeapTuple insert_username (void);
|
||||
HeapTuple insert_username(void);
|
||||
|
||||
HeapTuple
|
||||
insert_username ()
|
||||
insert_username()
|
||||
{
|
||||
Trigger *trigger; /* to get trigger name */
|
||||
Trigger *trigger; /* to get trigger name */
|
||||
int nargs; /* # of arguments */
|
||||
Datum newval; /* new value of column */
|
||||
char **args; /* arguments */
|
||||
char *relname; /* triggered relation name */
|
||||
char **args; /* arguments */
|
||||
char *relname; /* triggered relation name */
|
||||
Relation rel; /* triggered relation */
|
||||
HeapTuple rettuple = NULL;
|
||||
TupleDesc tupdesc; /* tuple description */
|
||||
int attnum;
|
||||
|
||||
/* sanity checks from autoinc.c */
|
||||
/* sanity checks from autoinc.c */
|
||||
if (!CurrentTriggerData)
|
||||
elog(ERROR, "insert_username: triggers are not initialized");
|
||||
if (TRIGGER_FIRED_FOR_STATEMENT(CurrentTriggerData->tg_event))
|
||||
elog(ERROR, "insert_username: can't process STATEMENT events");
|
||||
if (TRIGGER_FIRED_AFTER(CurrentTriggerData->tg_event))
|
||||
elog(ERROR, "insert_username: must be fired before event");
|
||||
|
||||
|
||||
if (TRIGGER_FIRED_BY_INSERT(CurrentTriggerData->tg_event))
|
||||
rettuple = CurrentTriggerData->tg_trigtuple;
|
||||
else if (TRIGGER_FIRED_BY_UPDATE(CurrentTriggerData->tg_event))
|
||||
rettuple = CurrentTriggerData->tg_newtuple;
|
||||
else
|
||||
elog(ERROR, "insert_username: can't process DELETE events");
|
||||
|
||||
|
||||
rel = CurrentTriggerData->tg_relation;
|
||||
relname = SPI_getrelname(rel);
|
||||
|
||||
|
||||
trigger = CurrentTriggerData->tg_trigger;
|
||||
|
||||
nargs = trigger->tgnargs;
|
||||
if (nargs != 1)
|
||||
elog(ERROR, "insert_username (%s): one argument was expected", relname);
|
||||
|
||||
|
||||
args = trigger->tgargs;
|
||||
tupdesc = rel->rd_att;
|
||||
|
||||
|
||||
CurrentTriggerData = NULL;
|
||||
|
||||
attnum = SPI_fnumber (tupdesc, args[0]);
|
||||
|
||||
if ( attnum < 0 )
|
||||
|
||||
attnum = SPI_fnumber(tupdesc, args[0]);
|
||||
|
||||
if (attnum < 0)
|
||||
elog(ERROR, "insert_username (%s): there is no attribute %s", relname, args[0]);
|
||||
if (SPI_gettypeid (tupdesc, attnum) != TEXTOID)
|
||||
elog(ERROR, "insert_username (%s): attribute %s must be of TEXT type",
|
||||
relname, args[0]);
|
||||
if (SPI_gettypeid(tupdesc, attnum) != TEXTOID)
|
||||
elog(ERROR, "insert_username (%s): attribute %s must be of TEXT type",
|
||||
relname, args[0]);
|
||||
|
||||
/* create fields containing name */
|
||||
newval = PointerGetDatum (textin (GetPgUserName ()));
|
||||
/* create fields containing name */
|
||||
newval = PointerGetDatum(textin(GetPgUserName()));
|
||||
|
||||
/* construct new tuple */
|
||||
rettuple = SPI_modifytuple (rel, rettuple, 1, &attnum, &newval, NULL);
|
||||
if ( rettuple == NULL )
|
||||
elog (ERROR, "insert_username (%s): %d returned by SPI_modifytuple",
|
||||
relname, SPI_result);
|
||||
|
||||
pfree (relname);
|
||||
/* construct new tuple */
|
||||
rettuple = SPI_modifytuple(rel, rettuple, 1, &attnum, &newval, NULL);
|
||||
if (rettuple == NULL)
|
||||
elog(ERROR, "insert_username (%s): %d returned by SPI_modifytuple",
|
||||
relname, SPI_result);
|
||||
|
||||
pfree(relname);
|
||||
|
||||
return (rettuple);
|
||||
}
|
||||
|
@ -190,7 +190,7 @@ check_primary_key()
|
||||
* Ok, execute prepared plan.
|
||||
*/
|
||||
ret = SPI_execp(*(plan->splan), kvals, NULL, 1);
|
||||
/* we have no NULLs - so we pass ^^^^ here */
|
||||
/* we have no NULLs - so we pass ^^^^ here */
|
||||
|
||||
if (ret < 0)
|
||||
elog(ERROR, "check_primary_key: SPI_execp returned %d", ret);
|
||||
@ -481,7 +481,7 @@ check_foreign_key()
|
||||
relname = args[0];
|
||||
|
||||
ret = SPI_execp(plan->splan[r], kvals, NULL, tcount);
|
||||
/* we have no NULLs - so we pass ^^^^ here */
|
||||
/* we have no NULLs - so we pass ^^^^ here */
|
||||
|
||||
if (ret < 0)
|
||||
elog(ERROR, "check_foreign_key: SPI_execp returned %d", ret);
|
||||
|
@ -9,38 +9,38 @@
|
||||
|
||||
#define ABSTIMEOID 702 /* it should be in pg_type.h */
|
||||
|
||||
AbsoluteTime currabstime(void);
|
||||
HeapTuple timetravel(void);
|
||||
int32 set_timetravel(Name relname, int32 on);
|
||||
AbsoluteTime currabstime(void);
|
||||
HeapTuple timetravel(void);
|
||||
int32 set_timetravel(Name relname, int32 on);
|
||||
|
||||
typedef struct
|
||||
{
|
||||
char *ident;
|
||||
void *splan;
|
||||
} EPlan;
|
||||
char *ident;
|
||||
void *splan;
|
||||
} EPlan;
|
||||
|
||||
static EPlan *Plans = NULL; /* for UPDATE/DELETE */
|
||||
static int nPlans = 0;
|
||||
|
||||
static char **TTOff = NULL;
|
||||
static int nTTOff = 0;
|
||||
static char **TTOff = NULL;
|
||||
static int nTTOff = 0;
|
||||
|
||||
static EPlan *find_plan(char *ident, EPlan ** eplan, int *nplans);
|
||||
|
||||
/*
|
||||
* timetravel () --
|
||||
* 1. IF an update affects tuple with stop_date eq INFINITY
|
||||
* then form (and return) new tuple with stop_date eq current date
|
||||
* and all other column values as in old tuple, and insert tuple
|
||||
* with new data and start_date eq current date and
|
||||
* stop_date eq INFINITY
|
||||
* ELSE - skip updation of tuple.
|
||||
* 2. IF an delete affects tuple with stop_date eq INFINITY
|
||||
* then insert the same tuple with stop_date eq current date
|
||||
* ELSE - skip deletion of tuple.
|
||||
* 3. On INSERT, if start_date is NULL then current date will be
|
||||
* inserted, if stop_date is NULL then INFINITY will be inserted.
|
||||
*
|
||||
* timetravel () --
|
||||
* 1. IF an update affects tuple with stop_date eq INFINITY
|
||||
* then form (and return) new tuple with stop_date eq current date
|
||||
* and all other column values as in old tuple, and insert tuple
|
||||
* with new data and start_date eq current date and
|
||||
* stop_date eq INFINITY
|
||||
* ELSE - skip updation of tuple.
|
||||
* 2. IF an delete affects tuple with stop_date eq INFINITY
|
||||
* then insert the same tuple with stop_date eq current date
|
||||
* ELSE - skip deletion of tuple.
|
||||
* 3. On INSERT, if start_date is NULL then current date will be
|
||||
* inserted, if stop_date is NULL then INFINITY will be inserted.
|
||||
*
|
||||
* In CREATE TRIGGER you are to specify start_date and stop_date column
|
||||
* names:
|
||||
* EXECUTE PROCEDURE
|
||||
@ -53,8 +53,10 @@ timetravel()
|
||||
Trigger *trigger; /* to get trigger name */
|
||||
char **args; /* arguments */
|
||||
int attnum[2]; /* fnumbers of start/stop columns */
|
||||
Datum oldon, oldoff;
|
||||
Datum newon, newoff;
|
||||
Datum oldon,
|
||||
oldoff;
|
||||
Datum newon,
|
||||
newoff;
|
||||
Datum *cvals; /* column values */
|
||||
char *cnulls; /* column nulls */
|
||||
char *relname; /* triggered relation name */
|
||||
@ -78,11 +80,11 @@ timetravel()
|
||||
/* Called by trigger manager ? */
|
||||
if (!CurrentTriggerData)
|
||||
elog(ERROR, "timetravel: triggers are not initialized");
|
||||
|
||||
|
||||
/* Should be called for ROW trigger */
|
||||
if (TRIGGER_FIRED_FOR_STATEMENT(CurrentTriggerData->tg_event))
|
||||
elog(ERROR, "timetravel: can't process STATEMENT events");
|
||||
|
||||
|
||||
/* Should be called BEFORE */
|
||||
if (TRIGGER_FIRED_AFTER(CurrentTriggerData->tg_event))
|
||||
elog(ERROR, "timetravel: must be fired before event");
|
||||
@ -90,196 +92,197 @@ timetravel()
|
||||
/* INSERT ? */
|
||||
if (TRIGGER_FIRED_BY_INSERT(CurrentTriggerData->tg_event))
|
||||
isinsert = true;
|
||||
|
||||
|
||||
if (TRIGGER_FIRED_BY_UPDATE(CurrentTriggerData->tg_event))
|
||||
newtuple = CurrentTriggerData->tg_newtuple;
|
||||
|
||||
|
||||
trigtuple = CurrentTriggerData->tg_trigtuple;
|
||||
|
||||
|
||||
rel = CurrentTriggerData->tg_relation;
|
||||
relname = SPI_getrelname(rel);
|
||||
|
||||
|
||||
/* check if TT is OFF for this relation */
|
||||
for (i = 0; i < nTTOff; i++)
|
||||
if (strcasecmp (TTOff[i], relname) == 0)
|
||||
if (strcasecmp(TTOff[i], relname) == 0)
|
||||
break;
|
||||
if (i < nTTOff) /* OFF - nothing to do */
|
||||
{
|
||||
pfree (relname);
|
||||
pfree(relname);
|
||||
return ((newtuple != NULL) ? newtuple : trigtuple);
|
||||
}
|
||||
|
||||
|
||||
trigger = CurrentTriggerData->tg_trigger;
|
||||
|
||||
if (trigger->tgnargs != 2)
|
||||
elog(ERROR, "timetravel (%s): invalid (!= 2) number of arguments %d",
|
||||
relname, trigger->tgnargs);
|
||||
|
||||
elog(ERROR, "timetravel (%s): invalid (!= 2) number of arguments %d",
|
||||
relname, trigger->tgnargs);
|
||||
|
||||
args = trigger->tgargs;
|
||||
tupdesc = rel->rd_att;
|
||||
natts = tupdesc->natts;
|
||||
|
||||
|
||||
/*
|
||||
* Setting CurrentTriggerData to NULL prevents direct calls to trigger
|
||||
* functions in queries. Normally, trigger functions have to be called
|
||||
* by trigger manager code only.
|
||||
*/
|
||||
CurrentTriggerData = NULL;
|
||||
|
||||
for (i = 0; i < 2; i++ )
|
||||
|
||||
for (i = 0; i < 2; i++)
|
||||
{
|
||||
attnum[i] = SPI_fnumber (tupdesc, args[i]);
|
||||
if ( attnum[i] < 0 )
|
||||
attnum[i] = SPI_fnumber(tupdesc, args[i]);
|
||||
if (attnum[i] < 0)
|
||||
elog(ERROR, "timetravel (%s): there is no attribute %s", relname, args[i]);
|
||||
if (SPI_gettypeid (tupdesc, attnum[i]) != ABSTIMEOID)
|
||||
elog(ERROR, "timetravel (%s): attributes %s and %s must be of abstime type",
|
||||
relname, args[0], args[1]);
|
||||
if (SPI_gettypeid(tupdesc, attnum[i]) != ABSTIMEOID)
|
||||
elog(ERROR, "timetravel (%s): attributes %s and %s must be of abstime type",
|
||||
relname, args[0], args[1]);
|
||||
}
|
||||
|
||||
if (isinsert) /* INSERT */
|
||||
|
||||
if (isinsert) /* INSERT */
|
||||
{
|
||||
int chnattrs = 0;
|
||||
int chattrs[2];
|
||||
Datum newvals[2];
|
||||
|
||||
oldon = SPI_getbinval (trigtuple, tupdesc, attnum[0], &isnull);
|
||||
int chnattrs = 0;
|
||||
int chattrs[2];
|
||||
Datum newvals[2];
|
||||
|
||||
oldon = SPI_getbinval(trigtuple, tupdesc, attnum[0], &isnull);
|
||||
if (isnull)
|
||||
{
|
||||
newvals[chnattrs] = GetCurrentAbsoluteTime ();
|
||||
newvals[chnattrs] = GetCurrentAbsoluteTime();
|
||||
chattrs[chnattrs] = attnum[0];
|
||||
chnattrs++;
|
||||
}
|
||||
|
||||
oldoff = SPI_getbinval (trigtuple, tupdesc, attnum[1], &isnull);
|
||||
|
||||
oldoff = SPI_getbinval(trigtuple, tupdesc, attnum[1], &isnull);
|
||||
if (isnull)
|
||||
{
|
||||
if ((chnattrs == 0 && DatumGetInt32 (oldon) >= NOEND_ABSTIME) ||
|
||||
(chnattrs > 0 && DatumGetInt32 (newvals[0]) >= NOEND_ABSTIME))
|
||||
elog (ERROR, "timetravel (%s): %s ge %s",
|
||||
relname, args[0], args[1]);
|
||||
if ((chnattrs == 0 && DatumGetInt32(oldon) >= NOEND_ABSTIME) ||
|
||||
(chnattrs > 0 && DatumGetInt32(newvals[0]) >= NOEND_ABSTIME))
|
||||
elog(ERROR, "timetravel (%s): %s ge %s",
|
||||
relname, args[0], args[1]);
|
||||
newvals[chnattrs] = NOEND_ABSTIME;
|
||||
chattrs[chnattrs] = attnum[1];
|
||||
chnattrs++;
|
||||
}
|
||||
else
|
||||
{
|
||||
if ((chnattrs == 0 && DatumGetInt32 (oldon) >=
|
||||
DatumGetInt32 (oldoff)) ||
|
||||
(chnattrs > 0 && DatumGetInt32 (newvals[0]) >=
|
||||
DatumGetInt32 (oldoff)))
|
||||
elog (ERROR, "timetravel (%s): %s ge %s",
|
||||
relname, args[0], args[1]);
|
||||
if ((chnattrs == 0 && DatumGetInt32(oldon) >=
|
||||
DatumGetInt32(oldoff)) ||
|
||||
(chnattrs > 0 && DatumGetInt32(newvals[0]) >=
|
||||
DatumGetInt32(oldoff)))
|
||||
elog(ERROR, "timetravel (%s): %s ge %s",
|
||||
relname, args[0], args[1]);
|
||||
}
|
||||
|
||||
pfree (relname);
|
||||
if ( chnattrs <= 0 )
|
||||
|
||||
pfree(relname);
|
||||
if (chnattrs <= 0)
|
||||
return (trigtuple);
|
||||
|
||||
rettuple = SPI_modifytuple (rel, trigtuple, chnattrs,
|
||||
chattrs, newvals, NULL);
|
||||
|
||||
rettuple = SPI_modifytuple(rel, trigtuple, chnattrs,
|
||||
chattrs, newvals, NULL);
|
||||
return (rettuple);
|
||||
}
|
||||
|
||||
oldon = SPI_getbinval (trigtuple, tupdesc, attnum[0], &isnull);
|
||||
|
||||
oldon = SPI_getbinval(trigtuple, tupdesc, attnum[0], &isnull);
|
||||
if (isnull)
|
||||
elog(ERROR, "timetravel (%s): %s must be NOT NULL", relname, args[0]);
|
||||
|
||||
oldoff = SPI_getbinval (trigtuple, tupdesc, attnum[1], &isnull);
|
||||
|
||||
oldoff = SPI_getbinval(trigtuple, tupdesc, attnum[1], &isnull);
|
||||
if (isnull)
|
||||
elog(ERROR, "timetravel (%s): %s must be NOT NULL", relname, args[1]);
|
||||
|
||||
/*
|
||||
* If DELETE/UPDATE of tuple with stop_date neq INFINITY
|
||||
* then say upper Executor to skip operation for this tuple
|
||||
* 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 */
|
||||
{
|
||||
newon = SPI_getbinval (newtuple, tupdesc, attnum[0], &isnull);
|
||||
newon = SPI_getbinval(newtuple, tupdesc, attnum[0], &isnull);
|
||||
if (isnull)
|
||||
elog(ERROR, "timetravel (%s): %s must be NOT NULL", relname, args[0]);
|
||||
newoff = SPI_getbinval (newtuple, tupdesc, attnum[1], &isnull);
|
||||
newoff = SPI_getbinval(newtuple, tupdesc, attnum[1], &isnull);
|
||||
if (isnull)
|
||||
elog(ERROR, "timetravel (%s): %s must be NOT NULL", relname, args[1]);
|
||||
|
||||
if ( oldon != newon || oldoff != newoff )
|
||||
elog (ERROR, "timetravel (%s): you can't change %s and/or %s columns (use set_timetravel)",
|
||||
relname, args[0], args[1]);
|
||||
|
||||
if ( newoff != NOEND_ABSTIME )
|
||||
|
||||
if (oldon != newon || oldoff != newoff)
|
||||
elog(ERROR, "timetravel (%s): you can't change %s and/or %s columns (use set_timetravel)",
|
||||
relname, args[0], args[1]);
|
||||
|
||||
if (newoff != NOEND_ABSTIME)
|
||||
{
|
||||
pfree (relname); /* allocated in upper executor context */
|
||||
pfree(relname); /* allocated in upper executor context */
|
||||
return (NULL);
|
||||
}
|
||||
}
|
||||
else if (oldoff != NOEND_ABSTIME) /* DELETE */
|
||||
else if (oldoff != NOEND_ABSTIME) /* DELETE */
|
||||
{
|
||||
pfree (relname);
|
||||
pfree(relname);
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
newoff = GetCurrentAbsoluteTime ();
|
||||
|
||||
|
||||
newoff = GetCurrentAbsoluteTime();
|
||||
|
||||
/* Connect to SPI manager */
|
||||
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));
|
||||
cvals = (Datum *) palloc(natts * sizeof(Datum));
|
||||
cnulls = (char *) palloc(natts * sizeof(char));
|
||||
for (i = 0; i < natts; i++)
|
||||
{
|
||||
cvals[i] = SPI_getbinval ((newtuple != NULL) ? newtuple : trigtuple,
|
||||
tupdesc, i + 1, &isnull);
|
||||
cvals[i] = SPI_getbinval((newtuple != NULL) ? newtuple : trigtuple,
|
||||
tupdesc, i + 1, &isnull);
|
||||
cnulls[i] = (isnull) ? 'n' : ' ';
|
||||
}
|
||||
|
||||
|
||||
/* change date column(s) */
|
||||
if (newtuple) /* UPDATE */
|
||||
if (newtuple) /* UPDATE */
|
||||
{
|
||||
cvals[attnum[0] - 1] = newoff; /* start_date eq current date */
|
||||
cvals[attnum[0] - 1] = newoff; /* start_date eq current date */
|
||||
cnulls[attnum[0] - 1] = ' ';
|
||||
cvals[attnum[1] - 1] = NOEND_ABSTIME; /* stop_date eq INFINITY */
|
||||
cnulls[attnum[1] - 1] = ' ';
|
||||
}
|
||||
else /* DELETE */
|
||||
else
|
||||
/* DELETE */
|
||||
{
|
||||
cvals[attnum[1] - 1] = newoff; /* stop_date eq current date */
|
||||
cvals[attnum[1] - 1] = newoff; /* stop_date eq current date */
|
||||
cnulls[attnum[1] - 1] = ' ';
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Construct ident string as TriggerName $ TriggeredRelationId
|
||||
* and try to find prepared execution plan.
|
||||
* Construct ident string as TriggerName $ TriggeredRelationId and try
|
||||
* to find prepared execution plan.
|
||||
*/
|
||||
sprintf(ident, "%s$%u", trigger->tgname, rel->rd_id);
|
||||
plan = find_plan(ident, &Plans, &nPlans);
|
||||
|
||||
|
||||
/* if there is no plan ... */
|
||||
if (plan->splan == NULL)
|
||||
{
|
||||
void *pplan;
|
||||
Oid *ctypes;
|
||||
char sql[8192];
|
||||
|
||||
|
||||
/* allocate ctypes for preparation */
|
||||
ctypes = (Oid *) palloc(natts * sizeof(Oid));
|
||||
|
||||
|
||||
/*
|
||||
* Construct query:
|
||||
* INSERT INTO _relation_ VALUES ($1, ...)
|
||||
* Construct query: INSERT INTO _relation_ VALUES ($1, ...)
|
||||
*/
|
||||
sprintf(sql, "INSERT INTO %s VALUES (", relname);
|
||||
for (i = 1; i <= natts; i++)
|
||||
{
|
||||
sprintf(sql + strlen(sql), "$%d%s",
|
||||
i, (i < natts) ? ", " : ")");
|
||||
i, (i < natts) ? ", " : ")");
|
||||
ctypes[i - 1] = SPI_gettypeid(tupdesc, i);
|
||||
}
|
||||
|
||||
|
||||
/* Prepare plan for query */
|
||||
pplan = SPI_prepare(sql, natts, ctypes);
|
||||
if (pplan == NULL)
|
||||
elog(ERROR, "timetravel (%s): SPI_prepare returned %d", relname, SPI_result);
|
||||
|
||||
|
||||
/*
|
||||
* Remember that SPI_prepare places plan in current memory context
|
||||
* - so, we have to save plan in Top memory context for latter
|
||||
@ -288,101 +291,103 @@ timetravel()
|
||||
pplan = SPI_saveplan(pplan);
|
||||
if (pplan == NULL)
|
||||
elog(ERROR, "timetravel (%s): SPI_saveplan returned %d", relname, SPI_result);
|
||||
|
||||
|
||||
plan->splan = pplan;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Ok, execute prepared plan.
|
||||
*/
|
||||
ret = SPI_execp(plan->splan, cvals, cnulls, 0);
|
||||
|
||||
|
||||
if (ret < 0)
|
||||
elog(ERROR, "timetravel (%s): SPI_execp returned %d", relname, ret);
|
||||
|
||||
|
||||
/* Tuple to return to upper Executor ... */
|
||||
if (newtuple) /* UPDATE */
|
||||
if (newtuple) /* UPDATE */
|
||||
{
|
||||
HeapTuple tmptuple;
|
||||
|
||||
tmptuple = SPI_copytuple (trigtuple);
|
||||
rettuple = SPI_modifytuple (rel, tmptuple, 1, &(attnum[1]), &newoff, NULL);
|
||||
|
||||
tmptuple = SPI_copytuple(trigtuple);
|
||||
rettuple = SPI_modifytuple(rel, tmptuple, 1, &(attnum[1]), &newoff, NULL);
|
||||
|
||||
/*
|
||||
* SPI_copytuple allocates tmptuple in upper executor context -
|
||||
* have to free allocation using SPI_pfree
|
||||
*/
|
||||
SPI_pfree (tmptuple);
|
||||
SPI_pfree(tmptuple);
|
||||
}
|
||||
else /* DELETE */
|
||||
else
|
||||
/* DELETE */
|
||||
rettuple = trigtuple;
|
||||
|
||||
SPI_finish(); /* don't forget say Bye to SPI mgr */
|
||||
|
||||
pfree (relname);
|
||||
|
||||
SPI_finish(); /* don't forget say Bye to SPI mgr */
|
||||
|
||||
pfree(relname);
|
||||
|
||||
return (rettuple);
|
||||
}
|
||||
|
||||
/*
|
||||
* set_timetravel () --
|
||||
* turn timetravel for specified relation ON/OFF
|
||||
* turn timetravel for specified relation ON/OFF
|
||||
*/
|
||||
int32
|
||||
set_timetravel(Name relname, int32 on)
|
||||
{
|
||||
char *rname;
|
||||
char *d;
|
||||
char *s;
|
||||
int i;
|
||||
|
||||
char *rname;
|
||||
char *d;
|
||||
char *s;
|
||||
int i;
|
||||
|
||||
for (i = 0; i < nTTOff; i++)
|
||||
if (namestrcmp (relname, TTOff[i]) == 0)
|
||||
if (namestrcmp(relname, TTOff[i]) == 0)
|
||||
break;
|
||||
|
||||
|
||||
if (i < nTTOff) /* OFF currently */
|
||||
{
|
||||
if (on == 0)
|
||||
return (0);
|
||||
|
||||
|
||||
/* turn ON */
|
||||
free (TTOff[i]);
|
||||
free(TTOff[i]);
|
||||
if (nTTOff == 1)
|
||||
free (TTOff);
|
||||
free(TTOff);
|
||||
else
|
||||
{
|
||||
if (i < nTTOff - 1)
|
||||
memcpy (&(TTOff[i]), &(TTOff[i + 1]), (nTTOff - i) * sizeof (char*));
|
||||
TTOff = realloc (TTOff, (nTTOff - 1) * sizeof (char*));
|
||||
memcpy(&(TTOff[i]), &(TTOff[i + 1]), (nTTOff - i) * sizeof(char *));
|
||||
TTOff = realloc(TTOff, (nTTOff - 1) * sizeof(char *));
|
||||
}
|
||||
nTTOff--;
|
||||
return (0);
|
||||
}
|
||||
|
||||
|
||||
/* ON currently */
|
||||
if (on != 0)
|
||||
return (1);
|
||||
|
||||
|
||||
/* turn OFF */
|
||||
if (nTTOff == 0)
|
||||
TTOff = malloc (sizeof (char*));
|
||||
TTOff = malloc(sizeof(char *));
|
||||
else
|
||||
TTOff = realloc (TTOff, (nTTOff + 1) * sizeof (char*));
|
||||
s = rname = nameout (relname);
|
||||
d = TTOff[nTTOff] = malloc (strlen (rname) + 1);
|
||||
TTOff = realloc(TTOff, (nTTOff + 1) * sizeof(char *));
|
||||
s = rname = nameout(relname);
|
||||
d = TTOff[nTTOff] = malloc(strlen(rname) + 1);
|
||||
while (*s)
|
||||
*d++ = tolower (*s++);
|
||||
*d++ = tolower(*s++);
|
||||
*d = 0;
|
||||
pfree (rname);
|
||||
pfree(rname);
|
||||
nTTOff++;
|
||||
|
||||
|
||||
return (1);
|
||||
|
||||
}
|
||||
|
||||
AbsoluteTime
|
||||
currabstime ()
|
||||
currabstime()
|
||||
{
|
||||
return (GetCurrentAbsoluteTime ());
|
||||
return (GetCurrentAbsoluteTime());
|
||||
}
|
||||
|
||||
static EPlan *
|
||||
|
@ -20,13 +20,13 @@
|
||||
#define ISO8859
|
||||
|
||||
#define MIN(x, y) ((x) < (y) ? (x) : (y))
|
||||
#define VALUE(char) ((char) - '0')
|
||||
#define DIGIT(val) ((val) + '0')
|
||||
#define ISOCTAL(c) (((c) >= '0') && ((c) <= '7'))
|
||||
#define VALUE(char) ((char) - '0')
|
||||
#define DIGIT(val) ((val) + '0')
|
||||
#define ISOCTAL(c) (((c) >= '0') && ((c) <= '7'))
|
||||
#ifndef ISO8859
|
||||
#define NOTPRINTABLE(c) (!isprint(c))
|
||||
#define NOTPRINTABLE(c) (!isprint(c))
|
||||
#else
|
||||
#define NOTPRINTABLE(c) (!isprint(c) && ((c) < 0xa0))
|
||||
#define NOTPRINTABLE(c) (!isprint(c) && ((c) < 0xa0))
|
||||
#endif
|
||||
|
||||
/*
|
||||
@ -50,103 +50,117 @@
|
||||
char *
|
||||
string_output(char *data, int size)
|
||||
{
|
||||
register unsigned char c, *p, *r, *result;
|
||||
register int l, len;
|
||||
register unsigned char c,
|
||||
*p,
|
||||
*r,
|
||||
*result;
|
||||
register int l,
|
||||
len;
|
||||
|
||||
if (data == NULL) {
|
||||
result = (char *) palloc(2);
|
||||
result[0] = '-';
|
||||
result[1] = '\0';
|
||||
return (result);
|
||||
}
|
||||
|
||||
if (size < 0) {
|
||||
size = strlen(data);
|
||||
}
|
||||
|
||||
/* adjust string length for escapes */
|
||||
len = size;
|
||||
for (p=data,l=size; l>0; p++,l--) {
|
||||
switch (*p) {
|
||||
case '\\':
|
||||
case '"' :
|
||||
case '{':
|
||||
case '}':
|
||||
case '\b':
|
||||
case '\f':
|
||||
case '\n':
|
||||
case '\r':
|
||||
case '\t':
|
||||
case '\v':
|
||||
len++;
|
||||
break;
|
||||
default:
|
||||
if (NOTPRINTABLE(*p)) {
|
||||
len += 3;
|
||||
}
|
||||
if (data == NULL)
|
||||
{
|
||||
result = (char *) palloc(2);
|
||||
result[0] = '-';
|
||||
result[1] = '\0';
|
||||
return (result);
|
||||
}
|
||||
}
|
||||
len++;
|
||||
|
||||
result = (char *) palloc(len);
|
||||
|
||||
for (p=data,r=result,l=size; (l > 0) && (c = *p); p++,l--) {
|
||||
switch (c) {
|
||||
case '\\':
|
||||
case '"' :
|
||||
case '{':
|
||||
case '}':
|
||||
*r++ = '\\';
|
||||
*r++ = c;
|
||||
break;
|
||||
case '\b':
|
||||
*r++ = '\\';
|
||||
*r++ = 'b';
|
||||
break;
|
||||
case '\f':
|
||||
*r++ = '\\';
|
||||
*r++ = 'f';
|
||||
break;
|
||||
case '\n':
|
||||
*r++ = '\\';
|
||||
*r++ = 'n';
|
||||
break;
|
||||
case '\r':
|
||||
*r++ = '\\';
|
||||
*r++ = 'r';
|
||||
break;
|
||||
case '\t':
|
||||
*r++ = '\\';
|
||||
*r++ = 't';
|
||||
break;
|
||||
case '\v':
|
||||
*r++ = '\\';
|
||||
*r++ = 'v';
|
||||
break;
|
||||
default:
|
||||
if (NOTPRINTABLE(c)) {
|
||||
*r = '\\';
|
||||
r += 3;
|
||||
*r-- = DIGIT(c & 07);
|
||||
c >>= 3;
|
||||
*r-- = DIGIT(c & 07);
|
||||
c >>= 3;
|
||||
*r = DIGIT(c & 03);
|
||||
r += 3;
|
||||
} else {
|
||||
*r++ = c;
|
||||
}
|
||||
if (size < 0)
|
||||
{
|
||||
size = strlen(data);
|
||||
}
|
||||
}
|
||||
*r = '\0';
|
||||
|
||||
return((char *) result);
|
||||
/* adjust string length for escapes */
|
||||
len = size;
|
||||
for (p = data, l = size; l > 0; p++, l--)
|
||||
{
|
||||
switch (*p)
|
||||
{
|
||||
case '\\':
|
||||
case '"':
|
||||
case '{':
|
||||
case '}':
|
||||
case '\b':
|
||||
case '\f':
|
||||
case '\n':
|
||||
case '\r':
|
||||
case '\t':
|
||||
case '\v':
|
||||
len++;
|
||||
break;
|
||||
default:
|
||||
if (NOTPRINTABLE(*p))
|
||||
{
|
||||
len += 3;
|
||||
}
|
||||
}
|
||||
}
|
||||
len++;
|
||||
|
||||
result = (char *) palloc(len);
|
||||
|
||||
for (p = data, r = result, l = size; (l > 0) && (c = *p); p++, l--)
|
||||
{
|
||||
switch (c)
|
||||
{
|
||||
case '\\':
|
||||
case '"':
|
||||
case '{':
|
||||
case '}':
|
||||
*r++ = '\\';
|
||||
*r++ = c;
|
||||
break;
|
||||
case '\b':
|
||||
*r++ = '\\';
|
||||
*r++ = 'b';
|
||||
break;
|
||||
case '\f':
|
||||
*r++ = '\\';
|
||||
*r++ = 'f';
|
||||
break;
|
||||
case '\n':
|
||||
*r++ = '\\';
|
||||
*r++ = 'n';
|
||||
break;
|
||||
case '\r':
|
||||
*r++ = '\\';
|
||||
*r++ = 'r';
|
||||
break;
|
||||
case '\t':
|
||||
*r++ = '\\';
|
||||
*r++ = 't';
|
||||
break;
|
||||
case '\v':
|
||||
*r++ = '\\';
|
||||
*r++ = 'v';
|
||||
break;
|
||||
default:
|
||||
if (NOTPRINTABLE(c))
|
||||
{
|
||||
*r = '\\';
|
||||
r += 3;
|
||||
*r-- = DIGIT(c & 07);
|
||||
c >>= 3;
|
||||
*r-- = DIGIT(c & 07);
|
||||
c >>= 3;
|
||||
*r = DIGIT(c & 03);
|
||||
r += 3;
|
||||
}
|
||||
else
|
||||
{
|
||||
*r++ = c;
|
||||
}
|
||||
}
|
||||
}
|
||||
*r = '\0';
|
||||
|
||||
return ((char *) result);
|
||||
}
|
||||
|
||||
/*
|
||||
* string_input() --
|
||||
*
|
||||
* This function accepts a C string in input and copies it into a new
|
||||
* This function accepts a C string in input and copies it into a new
|
||||
* object allocated with palloc() translating all escape sequences.
|
||||
* An optional header can be allocatd before the string, for example
|
||||
* to hold the length of a varlena object.
|
||||
@ -172,136 +186,155 @@ string_output(char *data, int size)
|
||||
char *
|
||||
string_input(char *str, int size, int hdrsize, int *rtn_size)
|
||||
{
|
||||
register unsigned char *p, *r;
|
||||
unsigned char *result;
|
||||
int len;
|
||||
register unsigned char *p,
|
||||
*r;
|
||||
unsigned char *result;
|
||||
int len;
|
||||
|
||||
if ((str == NULL) || (hdrsize < 0)) {
|
||||
return (char *) NULL;
|
||||
}
|
||||
|
||||
/* Compute result size */
|
||||
len = strlen(str);
|
||||
for (p=str; *p; ) {
|
||||
if (*p++ == '\\') {
|
||||
if (ISOCTAL(*p)) {
|
||||
if (ISOCTAL(*(p+1))) {
|
||||
p++;
|
||||
len--;
|
||||
}
|
||||
if (ISOCTAL(*(p+1))) {
|
||||
p++;
|
||||
len--;
|
||||
}
|
||||
}
|
||||
if (*p) p++;
|
||||
len--;
|
||||
if ((str == NULL) || (hdrsize < 0))
|
||||
{
|
||||
return (char *) NULL;
|
||||
}
|
||||
}
|
||||
|
||||
/* result has variable length */
|
||||
if (size == 0) {
|
||||
size = len+1;
|
||||
} else
|
||||
|
||||
/* result has variable length with maximum size */
|
||||
if (size < 0) {
|
||||
size = MIN(len, - size)+1;
|
||||
}
|
||||
|
||||
result = (char *) palloc(hdrsize+size);
|
||||
memset(result, 0, hdrsize+size);
|
||||
if (rtn_size) {
|
||||
*rtn_size = size;
|
||||
}
|
||||
|
||||
r = result + hdrsize;
|
||||
for (p=str; *p; ) {
|
||||
register unsigned char c;
|
||||
if ((c = *p++) == '\\') {
|
||||
switch (c = *p++) {
|
||||
case '\0':
|
||||
p--;
|
||||
break;
|
||||
case '0':
|
||||
case '1':
|
||||
case '2':
|
||||
case '3':
|
||||
case '4':
|
||||
case '5':
|
||||
case '6':
|
||||
case '7':
|
||||
c = VALUE(c);
|
||||
if (isdigit(*p)) {
|
||||
c = (c<<3) + VALUE(*p++);
|
||||
/* Compute result size */
|
||||
len = strlen(str);
|
||||
for (p = str; *p;)
|
||||
{
|
||||
if (*p++ == '\\')
|
||||
{
|
||||
if (ISOCTAL(*p))
|
||||
{
|
||||
if (ISOCTAL(*(p + 1)))
|
||||
{
|
||||
p++;
|
||||
len--;
|
||||
}
|
||||
if (ISOCTAL(*(p + 1)))
|
||||
{
|
||||
p++;
|
||||
len--;
|
||||
}
|
||||
}
|
||||
if (*p)
|
||||
p++;
|
||||
len--;
|
||||
}
|
||||
if (isdigit(*p)) {
|
||||
c = (c<<3) + VALUE(*p++);
|
||||
}
|
||||
*r++ = c;
|
||||
break;
|
||||
case 'b':
|
||||
*r++ = '\b';
|
||||
break;
|
||||
case 'f':
|
||||
*r++ = '\f';
|
||||
break;
|
||||
case 'n':
|
||||
*r++ = '\n';
|
||||
break;
|
||||
case 'r':
|
||||
*r++ = '\r';
|
||||
break;
|
||||
case 't':
|
||||
*r++ = '\t';
|
||||
break;
|
||||
case 'v':
|
||||
*r++ = '\v';
|
||||
break;
|
||||
default:
|
||||
*r++ = c;
|
||||
}
|
||||
} else {
|
||||
*r++ = c;
|
||||
}
|
||||
}
|
||||
|
||||
return((char *) result);
|
||||
/* result has variable length */
|
||||
if (size == 0)
|
||||
{
|
||||
size = len + 1;
|
||||
}
|
||||
else
|
||||
/* result has variable length with maximum size */
|
||||
if (size < 0)
|
||||
{
|
||||
size = MIN(len, -size) + 1;
|
||||
}
|
||||
|
||||
result = (char *) palloc(hdrsize + size);
|
||||
memset(result, 0, hdrsize + size);
|
||||
if (rtn_size)
|
||||
{
|
||||
*rtn_size = size;
|
||||
}
|
||||
|
||||
r = result + hdrsize;
|
||||
for (p = str; *p;)
|
||||
{
|
||||
register unsigned char c;
|
||||
|
||||
if ((c = *p++) == '\\')
|
||||
{
|
||||
switch (c = *p++)
|
||||
{
|
||||
case '\0':
|
||||
p--;
|
||||
break;
|
||||
case '0':
|
||||
case '1':
|
||||
case '2':
|
||||
case '3':
|
||||
case '4':
|
||||
case '5':
|
||||
case '6':
|
||||
case '7':
|
||||
c = VALUE(c);
|
||||
if (isdigit(*p))
|
||||
{
|
||||
c = (c << 3) + VALUE(*p++);
|
||||
}
|
||||
if (isdigit(*p))
|
||||
{
|
||||
c = (c << 3) + VALUE(*p++);
|
||||
}
|
||||
*r++ = c;
|
||||
break;
|
||||
case 'b':
|
||||
*r++ = '\b';
|
||||
break;
|
||||
case 'f':
|
||||
*r++ = '\f';
|
||||
break;
|
||||
case 'n':
|
||||
*r++ = '\n';
|
||||
break;
|
||||
case 'r':
|
||||
*r++ = '\r';
|
||||
break;
|
||||
case 't':
|
||||
*r++ = '\t';
|
||||
break;
|
||||
case 'v':
|
||||
*r++ = '\v';
|
||||
break;
|
||||
default:
|
||||
*r++ = c;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
*r++ = c;
|
||||
}
|
||||
}
|
||||
|
||||
return ((char *) result);
|
||||
}
|
||||
|
||||
char *
|
||||
c_charout(int32 c)
|
||||
{
|
||||
char str[2];
|
||||
char str[2];
|
||||
|
||||
str[0] = (char) c;
|
||||
str[1] = '\0';
|
||||
str[0] = (char) c;
|
||||
str[1] = '\0';
|
||||
|
||||
return (string_output(str, 1));
|
||||
return (string_output(str, 1));
|
||||
}
|
||||
|
||||
char *
|
||||
c_char2out(uint16 s)
|
||||
{
|
||||
return (string_output((char *) &s, 2));
|
||||
return (string_output((char *) &s, 2));
|
||||
}
|
||||
|
||||
char *
|
||||
c_char4out(uint32 s)
|
||||
{
|
||||
return (string_output((char *) &s, 4));
|
||||
return (string_output((char *) &s, 4));
|
||||
}
|
||||
|
||||
char *
|
||||
c_char8out(char *s)
|
||||
{
|
||||
return (string_output(s, 8));
|
||||
return (string_output(s, 8));
|
||||
}
|
||||
|
||||
char *
|
||||
c_char16out(char *s)
|
||||
{
|
||||
return (string_output(s, 16));
|
||||
return (string_output(s, 16));
|
||||
}
|
||||
|
||||
/*
|
||||
@ -309,16 +342,17 @@ c_char16out(char *s)
|
||||
*/
|
||||
|
||||
char *
|
||||
c_textout(struct varlena *vlena)
|
||||
c_textout(struct varlena * vlena)
|
||||
{
|
||||
int len = 0;
|
||||
char *s = NULL;
|
||||
int len = 0;
|
||||
char *s = NULL;
|
||||
|
||||
if (vlena) {
|
||||
len = VARSIZE(vlena) - VARHDRSZ;
|
||||
s = VARDATA(vlena);
|
||||
}
|
||||
return (string_output(s, len));
|
||||
if (vlena)
|
||||
{
|
||||
len = VARSIZE(vlena) - VARHDRSZ;
|
||||
s = VARDATA(vlena);
|
||||
}
|
||||
return (string_output(s, len));
|
||||
}
|
||||
|
||||
/*
|
||||
@ -328,37 +362,40 @@ c_textout(struct varlena *vlena)
|
||||
char *
|
||||
c_varcharout(char *s)
|
||||
{
|
||||
int len = 0;
|
||||
int len = 0;
|
||||
|
||||
if (s) {
|
||||
len = *(int32*)s - 4;
|
||||
s += 4;
|
||||
}
|
||||
return (string_output(s, len));
|
||||
if (s)
|
||||
{
|
||||
len = *(int32 *) s - 4;
|
||||
s += 4;
|
||||
}
|
||||
return (string_output(s, len));
|
||||
}
|
||||
|
||||
#if 0
|
||||
struct varlena *
|
||||
c_textin(char *str)
|
||||
{
|
||||
struct varlena *result;
|
||||
int len;
|
||||
struct varlena *result;
|
||||
int len;
|
||||
|
||||
if (str == NULL) {
|
||||
return ((struct varlena *) NULL);
|
||||
}
|
||||
if (str == NULL)
|
||||
{
|
||||
return ((struct varlena *) NULL);
|
||||
}
|
||||
|
||||
result = (struct varlena *) string_input(str, 0, VARHDRSZ, &len);
|
||||
VARSIZE(result) = len;
|
||||
result = (struct varlena *) string_input(str, 0, VARHDRSZ, &len);
|
||||
VARSIZE(result) = len;
|
||||
|
||||
return (result);
|
||||
return (result);
|
||||
}
|
||||
|
||||
char *
|
||||
c_char16in(char *str)
|
||||
{
|
||||
return (string_input(str, 16, 0, NULL));
|
||||
return (string_input(str, 16, 0, NULL));
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
|
@ -1,19 +1,20 @@
|
||||
#ifndef STRING_IO_H
|
||||
#define STRING_IO_H
|
||||
|
||||
char *string_output(char *data, int size);
|
||||
char *string_input(char *str, int size, int hdrsize, int *rtn_size);
|
||||
char *c_charout(int32 c);
|
||||
char *c_char2out(uint16 s);
|
||||
char *c_char4out(uint32 s);
|
||||
char *c_char8out(char *s);
|
||||
char *c_char16out(char *s);
|
||||
char *c_textout(struct varlena *vlena);
|
||||
char *c_varcharout(char *s);
|
||||
char *string_output(char *data, int size);
|
||||
char *string_input(char *str, int size, int hdrsize, int *rtn_size);
|
||||
char *c_charout(int32 c);
|
||||
char *c_char2out(uint16 s);
|
||||
char *c_char4out(uint32 s);
|
||||
char *c_char8out(char *s);
|
||||
char *c_char16out(char *s);
|
||||
char *c_textout(struct varlena * vlena);
|
||||
char *c_varcharout(char *s);
|
||||
|
||||
#if 0
|
||||
struct varlena *c_textin(char *str);
|
||||
char *c_char16in(char *str);
|
||||
char *c_char16in(char *str);
|
||||
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
@ -22,79 +22,80 @@
|
||||
|
||||
#include "user_locks.h"
|
||||
|
||||
#define USER_LOCKS_TABLE_ID 0
|
||||
#define USER_LOCKS_TABLE_ID 0
|
||||
|
||||
extern Oid MyDatabaseId;
|
||||
extern Oid MyDatabaseId;
|
||||
|
||||
int
|
||||
user_lock(unsigned int id1, unsigned int id2, LOCKT lockt)
|
||||
{
|
||||
LOCKTAG tag;
|
||||
LOCKTAG tag;
|
||||
|
||||
memset(&tag,0,sizeof(LOCKTAG));
|
||||
tag.relId = 0;
|
||||
tag.dbId = MyDatabaseId;
|
||||
tag.tupleId.ip_blkid.bi_hi = id2 >> 16;
|
||||
tag.tupleId.ip_blkid.bi_lo = id2 & 0xffff;
|
||||
tag.tupleId.ip_posid = (unsigned short) (id1 & 0xffff);
|
||||
memset(&tag, 0, sizeof(LOCKTAG));
|
||||
tag.relId = 0;
|
||||
tag.dbId = MyDatabaseId;
|
||||
tag.tupleId.ip_blkid.bi_hi = id2 >> 16;
|
||||
tag.tupleId.ip_blkid.bi_lo = id2 & 0xffff;
|
||||
tag.tupleId.ip_posid = (unsigned short) (id1 & 0xffff);
|
||||
|
||||
return LockAcquire(USER_LOCKS_TABLE_ID, &tag, lockt);
|
||||
return LockAcquire(USER_LOCKS_TABLE_ID, &tag, lockt);
|
||||
}
|
||||
|
||||
int
|
||||
user_unlock(unsigned int id1, unsigned int id2, LOCKT lockt)
|
||||
{
|
||||
LOCKTAG tag;
|
||||
LOCKTAG tag;
|
||||
|
||||
memset(&tag, 0,sizeof(LOCKTAG));
|
||||
tag.relId = 0;
|
||||
tag.dbId = MyDatabaseId;
|
||||
tag.tupleId.ip_blkid.bi_hi = id2 >> 16;
|
||||
tag.tupleId.ip_blkid.bi_lo = id2 & 0xffff;
|
||||
tag.tupleId.ip_posid = (unsigned short) (id1 & 0xffff);
|
||||
|
||||
return LockRelease(USER_LOCKS_TABLE_ID, &tag, lockt);
|
||||
memset(&tag, 0, sizeof(LOCKTAG));
|
||||
tag.relId = 0;
|
||||
tag.dbId = MyDatabaseId;
|
||||
tag.tupleId.ip_blkid.bi_hi = id2 >> 16;
|
||||
tag.tupleId.ip_blkid.bi_lo = id2 & 0xffff;
|
||||
tag.tupleId.ip_posid = (unsigned short) (id1 & 0xffff);
|
||||
|
||||
return LockRelease(USER_LOCKS_TABLE_ID, &tag, lockt);
|
||||
}
|
||||
|
||||
int
|
||||
user_write_lock(unsigned int id1, unsigned int id2)
|
||||
{
|
||||
return user_lock(id1, id2, WRITE_LOCK);
|
||||
return user_lock(id1, id2, WRITE_LOCK);
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
user_write_unlock(unsigned int id1, unsigned int id2)
|
||||
{
|
||||
return user_unlock(id1, id2, WRITE_LOCK);
|
||||
return user_unlock(id1, id2, WRITE_LOCK);
|
||||
}
|
||||
|
||||
int
|
||||
user_write_lock_oid(Oid oid)
|
||||
{
|
||||
return user_lock(0, oid, WRITE_LOCK);
|
||||
return user_lock(0, oid, WRITE_LOCK);
|
||||
}
|
||||
|
||||
int
|
||||
user_write_unlock_oid(Oid oid)
|
||||
{
|
||||
return user_unlock(0, oid, WRITE_LOCK);
|
||||
return user_unlock(0, oid, WRITE_LOCK);
|
||||
}
|
||||
|
||||
int
|
||||
user_unlock_all()
|
||||
{
|
||||
PROC *proc;
|
||||
SHMEM_OFFSET location;
|
||||
PROC *proc;
|
||||
SHMEM_OFFSET location;
|
||||
|
||||
ShmemPIDLookup(getpid(),&location);
|
||||
if (location == INVALID_OFFSET) {
|
||||
elog(NOTICE, "UserUnlockAll: unable to get proc ptr");
|
||||
return -1;
|
||||
}
|
||||
ShmemPIDLookup(getpid(), &location);
|
||||
if (location == INVALID_OFFSET)
|
||||
{
|
||||
elog(NOTICE, "UserUnlockAll: unable to get proc ptr");
|
||||
return -1;
|
||||
}
|
||||
|
||||
proc = (PROC *) MAKE_PTR(location);
|
||||
return LockReleaseAll(USER_LOCKS_TABLE_ID, &proc->lockQueue);
|
||||
proc = (PROC *) MAKE_PTR(location);
|
||||
return LockReleaseAll(USER_LOCKS_TABLE_ID, &proc->lockQueue);
|
||||
}
|
||||
|
||||
/* end of file */
|
||||
|
@ -1,12 +1,12 @@
|
||||
#ifndef USER_LOCKS_H
|
||||
#define USER_LOCKS_H
|
||||
|
||||
int user_lock(unsigned int id1, unsigned int id2, LOCKT lockt);
|
||||
int user_unlock(unsigned int id1, unsigned int id2, LOCKT lockt);
|
||||
int user_write_lock(unsigned int id1, unsigned int id2);
|
||||
int user_write_unlock(unsigned int id1, unsigned int id2);
|
||||
int user_write_lock_oid(Oid oid);
|
||||
int user_write_unlock_oid(Oid oid);
|
||||
int user_unlock_all(void);
|
||||
int user_lock(unsigned int id1, unsigned int id2, LOCKT lockt);
|
||||
int user_unlock(unsigned int id1, unsigned int id2, LOCKT lockt);
|
||||
int user_write_lock(unsigned int id1, unsigned int id2);
|
||||
int user_write_unlock(unsigned int id1, unsigned int id2);
|
||||
int user_write_lock_oid(Oid oid);
|
||||
int user_write_unlock_oid(Oid oid);
|
||||
int user_unlock_all(void);
|
||||
|
||||
#endif
|
||||
|
Reference in New Issue
Block a user