pgindent run before 6.3 release, with Thomas' requested changes.
This commit is contained in:
parent
757bf69a2e
commit
a32450a585
430 changed files with 12390 additions and 10292 deletions
|
@ -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
|
||||
|
|
|
@ -8,7 +8,7 @@
|
|||
*
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $Header: /cvsroot/pgsql/src/backend/access/common/heaptuple.c,v 1.36 1998/02/11 19:09:21 momjian Exp $
|
||||
* $Header: /cvsroot/pgsql/src/backend/access/common/heaptuple.c,v 1.37 1998/02/26 04:29:15 momjian Exp $
|
||||
*
|
||||
* NOTES
|
||||
* The old interface functions have been converted to macros
|
||||
|
@ -34,14 +34,14 @@
|
|||
#endif
|
||||
|
||||
/* Used by heap_getattr() macro, for speed */
|
||||
long heap_sysoffset[] = {
|
||||
long heap_sysoffset[] = {
|
||||
/* Only the first one is pass-by-ref, and is handled specially in the macro */
|
||||
offsetof(HeapTupleData, t_ctid),
|
||||
offsetof(HeapTupleData, t_oid),
|
||||
offsetof(HeapTupleData, t_xmin),
|
||||
offsetof(HeapTupleData, t_cmin),
|
||||
offsetof(HeapTupleData, t_xmax),
|
||||
offsetof(HeapTupleData, t_cmax)
|
||||
offsetof(HeapTupleData, t_ctid),
|
||||
offsetof(HeapTupleData, t_oid),
|
||||
offsetof(HeapTupleData, t_xmin),
|
||||
offsetof(HeapTupleData, t_cmin),
|
||||
offsetof(HeapTupleData, t_xmax),
|
||||
offsetof(HeapTupleData, t_cmax)
|
||||
};
|
||||
|
||||
/* ----------------------------------------------------------------
|
||||
|
@ -350,7 +350,7 @@ heap_getsysattr(HeapTuple tup, Buffer b, int attnum)
|
|||
{
|
||||
switch (attnum)
|
||||
{
|
||||
case SelfItemPointerAttributeNumber:
|
||||
case SelfItemPointerAttributeNumber:
|
||||
return ((Datum) &tup->t_ctid);
|
||||
case ObjectIdAttributeNumber:
|
||||
return ((Datum) (long) tup->t_oid);
|
||||
|
@ -389,16 +389,16 @@ heap_getsysattr(HeapTuple tup, Buffer b, int attnum)
|
|||
*/
|
||||
Datum
|
||||
nocachegetattr(HeapTuple tup,
|
||||
int attnum,
|
||||
TupleDesc tupleDesc,
|
||||
bool *isnull)
|
||||
int attnum,
|
||||
TupleDesc tupleDesc,
|
||||
bool *isnull)
|
||||
{
|
||||
char *tp; /* ptr to att in tuple */
|
||||
bits8 *bp = tup->t_bits; /* ptr to att in tuple */
|
||||
bits8 *bp = tup->t_bits; /* ptr to att in tuple */
|
||||
int slow; /* do we have to walk nulls? */
|
||||
AttributeTupleForm *att = tupleDesc->attrs;
|
||||
|
||||
|
||||
|
||||
#if IN_MACRO
|
||||
/* This is handled in the macro */
|
||||
Assert(attnum > 0);
|
||||
|
@ -430,6 +430,7 @@ nocachegetattr(HeapTuple tup,
|
|||
}
|
||||
else if (attnum == 0)
|
||||
{
|
||||
|
||||
/*
|
||||
* first attribute is always at position zero
|
||||
*/
|
||||
|
@ -470,11 +471,11 @@ nocachegetattr(HeapTuple tup,
|
|||
* ----------------
|
||||
*/
|
||||
{
|
||||
int i = 0; /* current offset in bp */
|
||||
int mask; /* bit in byte we're looking at */
|
||||
char n; /* current byte in bp */
|
||||
int byte,
|
||||
finalbit;
|
||||
int i = 0; /* current offset in bp */
|
||||
int mask; /* bit in byte we're looking at */
|
||||
char n; /* current byte in bp */
|
||||
int byte,
|
||||
finalbit;
|
||||
|
||||
byte = attnum >> 3;
|
||||
finalbit = attnum & 0x07;
|
||||
|
@ -486,14 +487,14 @@ nocachegetattr(HeapTuple tup,
|
|||
{
|
||||
/* check for nulls in any "earlier" bytes */
|
||||
if ((~n) != 0)
|
||||
slow=1;
|
||||
slow = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* check for nulls "before" final bit of last byte */
|
||||
mask = (1 << finalbit) - 1;
|
||||
if ((~n) & mask)
|
||||
slow=1;
|
||||
slow = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -508,8 +509,8 @@ nocachegetattr(HeapTuple tup,
|
|||
{
|
||||
if (att[attnum]->attcacheoff != -1)
|
||||
{
|
||||
return (Datum)fetchatt(&(att[attnum]),
|
||||
tp + att[attnum]->attcacheoff);
|
||||
return (Datum) fetchatt(&(att[attnum]),
|
||||
tp + att[attnum]->attcacheoff);
|
||||
}
|
||||
else if (attnum == 0)
|
||||
{
|
||||
|
@ -517,11 +518,11 @@ nocachegetattr(HeapTuple tup,
|
|||
}
|
||||
else if (!HeapTupleAllFixed(tup))
|
||||
{
|
||||
int j = 0;
|
||||
int j = 0;
|
||||
|
||||
/*
|
||||
* In for(), we make this <= and not < because we want to
|
||||
* test if we can go past it in initializing offsets.
|
||||
* In for(), we make this <= and not < because we want to test
|
||||
* if we can go past it in initializing offsets.
|
||||
*/
|
||||
for (j = 0; j <= attnum && !slow; j++)
|
||||
if (att[j]->attlen < 1 && !VARLENA_FIXED_SIZE(att[j]))
|
||||
|
@ -536,8 +537,8 @@ nocachegetattr(HeapTuple tup,
|
|||
*/
|
||||
if (!slow)
|
||||
{
|
||||
int j = 1;
|
||||
long off;
|
||||
int j = 1;
|
||||
long off;
|
||||
|
||||
/*
|
||||
* need to set cache for some atts
|
||||
|
@ -554,13 +555,14 @@ nocachegetattr(HeapTuple tup,
|
|||
off = att[j - 1]->attcacheoff + att[j - 1]->atttypmod;
|
||||
|
||||
for (; j <= attnum ||
|
||||
/* Can we compute more? We will probably need them */
|
||||
(j < tup->t_natts &&
|
||||
att[j]->attcacheoff == -1 &&
|
||||
(HeapTupleNoNulls(tup) || !att_isnull(j, bp)) &&
|
||||
(HeapTupleAllFixed(tup)||
|
||||
att[j]->attlen > 0 || VARLENA_FIXED_SIZE(att[j]))); j++)
|
||||
/* Can we compute more? We will probably need them */
|
||||
(j < tup->t_natts &&
|
||||
att[j]->attcacheoff == -1 &&
|
||||
(HeapTupleNoNulls(tup) || !att_isnull(j, bp)) &&
|
||||
(HeapTupleAllFixed(tup) ||
|
||||
att[j]->attlen > 0 || VARLENA_FIXED_SIZE(att[j]))); j++)
|
||||
{
|
||||
|
||||
/*
|
||||
* Fix me when going to a machine with more than a four-byte
|
||||
* word!
|
||||
|
@ -605,7 +607,7 @@ nocachegetattr(HeapTuple tup,
|
|||
break;
|
||||
case -1:
|
||||
Assert(!VARLENA_FIXED_SIZE(att[j]) ||
|
||||
att[j]->atttypmod == VARSIZE(tp + off));
|
||||
att[j]->atttypmod == VARSIZE(tp + off));
|
||||
off += VARSIZE(tp + off);
|
||||
break;
|
||||
default:
|
||||
|
@ -618,9 +620,9 @@ nocachegetattr(HeapTuple tup,
|
|||
}
|
||||
else
|
||||
{
|
||||
bool usecache = true;
|
||||
int off = 0;
|
||||
int i;
|
||||
bool usecache = true;
|
||||
int off = 0;
|
||||
int i;
|
||||
|
||||
/*
|
||||
* Now we know that we have to walk the tuple CAREFULLY.
|
||||
|
@ -665,7 +667,7 @@ nocachegetattr(HeapTuple tup,
|
|||
default:
|
||||
if (att[i]->attlen < sizeof(int32))
|
||||
elog(ERROR,
|
||||
"nocachegetattr2: attribute %d has len %d",
|
||||
"nocachegetattr2: attribute %d has len %d",
|
||||
i, att[i]->attlen);
|
||||
if (att[i]->attalign == 'd')
|
||||
off = DOUBLEALIGN(off);
|
||||
|
@ -690,7 +692,7 @@ nocachegetattr(HeapTuple tup,
|
|||
break;
|
||||
case -1:
|
||||
Assert(!VARLENA_FIXED_SIZE(att[i]) ||
|
||||
att[i]->atttypmod == VARSIZE(tp + off));
|
||||
att[i]->atttypmod == VARSIZE(tp + off));
|
||||
off += VARSIZE(tp + off);
|
||||
if (!VARLENA_FIXED_SIZE(att[i]))
|
||||
usecache = false;
|
||||
|
@ -965,9 +967,9 @@ heap_modifytuple(HeapTuple tuple,
|
|||
* ----------------
|
||||
*/
|
||||
infomask = newTuple->t_infomask;
|
||||
memmove((char *) &newTuple->t_oid, /* XXX */
|
||||
memmove((char *) &newTuple->t_oid, /* XXX */
|
||||
(char *) &tuple->t_oid,
|
||||
((char *) &tuple->t_hoff - (char *) &tuple->t_oid)); /* XXX */
|
||||
((char *) &tuple->t_hoff - (char *) &tuple->t_oid)); /* XXX */
|
||||
newTuple->t_infomask = infomask;
|
||||
newTuple->t_natts = numberOfAttributes; /* fix t_natts just in
|
||||
* case */
|
||||
|
@ -993,7 +995,7 @@ heap_addheader(uint32 natts, /* max domain index */
|
|||
int structlen, /* its length */
|
||||
char *structure) /* pointer to the struct */
|
||||
{
|
||||
char *tp; /* tuple data pointer */
|
||||
char *tp; /* tuple data pointer */
|
||||
HeapTuple tup;
|
||||
long len;
|
||||
int hoff;
|
||||
|
@ -1018,4 +1020,3 @@ heap_addheader(uint32 natts, /* max domain index */
|
|||
|
||||
return (tup);
|
||||
}
|
||||
|
||||
|
|
|
@ -8,7 +8,7 @@
|
|||
*
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $Header: /cvsroot/pgsql/src/backend/access/common/indextuple.c,v 1.27 1998/02/11 19:09:23 momjian Exp $
|
||||
* $Header: /cvsroot/pgsql/src/backend/access/common/indextuple.c,v 1.28 1998/02/26 04:29:18 momjian Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
|
@ -41,7 +41,7 @@ index_formtuple(TupleDesc tupleDescriptor,
|
|||
Datum value[],
|
||||
char null[])
|
||||
{
|
||||
char *tp; /* tuple pointer */
|
||||
char *tp; /* tuple pointer */
|
||||
IndexTuple tuple; /* return tuple */
|
||||
Size size,
|
||||
hoff;
|
||||
|
@ -133,14 +133,14 @@ index_formtuple(TupleDesc tupleDescriptor,
|
|||
*/
|
||||
Datum
|
||||
nocache_index_getattr(IndexTuple tup,
|
||||
int attnum,
|
||||
TupleDesc tupleDesc,
|
||||
bool *isnull)
|
||||
int attnum,
|
||||
TupleDesc tupleDesc,
|
||||
bool *isnull)
|
||||
{
|
||||
char *tp; /* ptr to att in tuple */
|
||||
char *bp = NULL; /* ptr to att in tuple */
|
||||
char *tp; /* ptr to att in tuple */
|
||||
char *bp = NULL; /* ptr to att in tuple */
|
||||
int slow; /* do we have to walk nulls? */
|
||||
int data_off; /* tuple data offset */
|
||||
int data_off; /* tuple data offset */
|
||||
AttributeTupleForm *att = tupleDesc->attrs;
|
||||
|
||||
/* ----------------
|
||||
|
@ -174,7 +174,7 @@ nocache_index_getattr(IndexTuple tup,
|
|||
|
||||
#ifdef IN_MACRO
|
||||
/* This is handled in the macro */
|
||||
|
||||
|
||||
/* first attribute is always at position zero */
|
||||
|
||||
if (attnum == 1)
|
||||
|
@ -184,8 +184,8 @@ nocache_index_getattr(IndexTuple tup,
|
|||
if (att[attnum]->attcacheoff != -1)
|
||||
{
|
||||
return (Datum) fetchatt(&(att[attnum]),
|
||||
(char *) tup + data_off +
|
||||
att[attnum]->attcacheoff);
|
||||
(char *) tup + data_off +
|
||||
att[attnum]->attcacheoff);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
@ -206,11 +206,11 @@ nocache_index_getattr(IndexTuple tup,
|
|||
* here! */
|
||||
#ifdef IN_MACRO
|
||||
/* This is handled in the macro */
|
||||
|
||||
|
||||
if (att_isnull(attnum, bp))
|
||||
{
|
||||
*isnull = true;
|
||||
return (Datum)NULL;
|
||||
return (Datum) NULL;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
@ -219,11 +219,11 @@ nocache_index_getattr(IndexTuple tup,
|
|||
* ----------------
|
||||
*/
|
||||
{
|
||||
int i = 0; /* current offset in bp */
|
||||
int mask; /* bit in byte we're looking at */
|
||||
char n; /* current byte in bp */
|
||||
int byte,
|
||||
finalbit;
|
||||
int i = 0; /* current offset in bp */
|
||||
int mask; /* bit in byte we're looking at */
|
||||
char n; /* current byte in bp */
|
||||
int byte,
|
||||
finalbit;
|
||||
|
||||
byte = attnum >> 3;
|
||||
finalbit = attnum & 0x07;
|
||||
|
@ -235,14 +235,14 @@ nocache_index_getattr(IndexTuple tup,
|
|||
{
|
||||
/* check for nulls in any "earlier" bytes */
|
||||
if ((~n) != 0)
|
||||
slow=1;
|
||||
slow = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* check for nulls "before" final bit of last byte */
|
||||
mask = (1 << finalbit) - 1;
|
||||
if ((~n) & mask)
|
||||
slow=1;
|
||||
slow = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -257,7 +257,7 @@ nocache_index_getattr(IndexTuple tup,
|
|||
if (att[attnum]->attcacheoff != -1)
|
||||
{
|
||||
return (Datum) fetchatt(&(att[attnum]),
|
||||
tp + att[attnum]->attcacheoff);
|
||||
tp + att[attnum]->attcacheoff);
|
||||
}
|
||||
else if (attnum == 0)
|
||||
{
|
||||
|
@ -265,7 +265,7 @@ nocache_index_getattr(IndexTuple tup,
|
|||
}
|
||||
else if (!IndexTupleAllFixed(tup))
|
||||
{
|
||||
int j = 0;
|
||||
int j = 0;
|
||||
|
||||
for (j = 0; j < attnum && !slow; j++)
|
||||
if (att[j]->attlen < 1 && !VARLENA_FIXED_SIZE(att[j]))
|
||||
|
@ -281,8 +281,8 @@ nocache_index_getattr(IndexTuple tup,
|
|||
|
||||
if (!slow)
|
||||
{
|
||||
int j = 1;
|
||||
long off;
|
||||
int j = 1;
|
||||
long off;
|
||||
|
||||
/*
|
||||
* need to set cache for some atts
|
||||
|
@ -293,13 +293,14 @@ nocache_index_getattr(IndexTuple tup,
|
|||
while (att[j]->attcacheoff != -1)
|
||||
j++;
|
||||
|
||||
if (!VARLENA_FIXED_SIZE(att[j-1]))
|
||||
if (!VARLENA_FIXED_SIZE(att[j - 1]))
|
||||
off = att[j - 1]->attcacheoff + att[j - 1]->attlen;
|
||||
else
|
||||
off = att[j - 1]->attcacheoff + att[j - 1]->atttypmod;
|
||||
|
||||
for (; j < attnum + 1; j++)
|
||||
{
|
||||
|
||||
/*
|
||||
* Fix me when going to a machine with more than a four-byte
|
||||
* word!
|
||||
|
@ -346,9 +347,9 @@ nocache_index_getattr(IndexTuple tup,
|
|||
}
|
||||
else
|
||||
{
|
||||
bool usecache = true;
|
||||
int off = 0;
|
||||
int i;
|
||||
bool usecache = true;
|
||||
int off = 0;
|
||||
int i;
|
||||
|
||||
/*
|
||||
* Now we know that we have to walk the tuple CAREFULLY.
|
||||
|
@ -387,7 +388,7 @@ nocache_index_getattr(IndexTuple tup,
|
|||
default:
|
||||
if (att[i]->attlen < sizeof(int32))
|
||||
elog(ERROR,
|
||||
"nocachegetiattr2: attribute %d has len %d",
|
||||
"nocachegetiattr2: attribute %d has len %d",
|
||||
i, att[i]->attlen);
|
||||
if (att[i]->attalign == 'd')
|
||||
off = DOUBLEALIGN(off);
|
||||
|
@ -412,7 +413,7 @@ nocache_index_getattr(IndexTuple tup,
|
|||
break;
|
||||
case -1:
|
||||
Assert(!VARLENA_FIXED_SIZE(att[i]) ||
|
||||
att[i]->atttypmod == VARSIZE(tp + off));
|
||||
att[i]->atttypmod == VARSIZE(tp + off));
|
||||
off += VARSIZE(tp + off);
|
||||
if (!VARLENA_FIXED_SIZE(att[i]))
|
||||
usecache = false;
|
||||
|
|
|
@ -8,7 +8,7 @@
|
|||
*
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $Header: /cvsroot/pgsql/src/backend/access/common/printtup.c,v 1.26 1998/02/11 19:09:25 momjian Exp $
|
||||
* $Header: /cvsroot/pgsql/src/backend/access/common/printtup.c,v 1.27 1998/02/26 04:29:20 momjian Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
|
@ -124,7 +124,7 @@ printtup(HeapTuple tuple, TupleDesc typeinfo)
|
|||
{
|
||||
outputstr = fmgr(typoutput, attr,
|
||||
gettypelem(typeinfo->attrs[i]->atttypid),
|
||||
typeinfo->attrs[i]->atttypmod);
|
||||
typeinfo->attrs[i]->atttypmod);
|
||||
pq_putint(strlen(outputstr) + VARHDRSZ, VARHDRSZ);
|
||||
pq_putnchar(outputstr, strlen(outputstr));
|
||||
pfree(outputstr);
|
||||
|
@ -176,8 +176,8 @@ showatts(char *name, TupleDesc tupleDesc)
|
|||
void
|
||||
debugtup(HeapTuple tuple, TupleDesc typeinfo)
|
||||
{
|
||||
int i;
|
||||
Datum attr;
|
||||
int i;
|
||||
Datum attr;
|
||||
char *value;
|
||||
bool isnull;
|
||||
Oid typoutput;
|
||||
|
@ -191,7 +191,7 @@ debugtup(HeapTuple tuple, TupleDesc typeinfo)
|
|||
{
|
||||
value = fmgr(typoutput, attr,
|
||||
gettypelem(typeinfo->attrs[i]->atttypid),
|
||||
typeinfo->attrs[i]->atttypmod);
|
||||
typeinfo->attrs[i]->atttypmod);
|
||||
printatt((unsigned) i + 1, typeinfo->attrs[i], value);
|
||||
pfree(value);
|
||||
}
|
||||
|
@ -313,7 +313,7 @@ printtup_internal(HeapTuple tuple, TupleDesc typeinfo)
|
|||
pq_putnchar(DatumGetPointer(attr), len);
|
||||
#ifdef IPORTAL_DEBUG
|
||||
fprintf(stderr, "byref length %d data %x\n", len,
|
||||
DatumGetPointer(attr));
|
||||
DatumGetPointer(attr));
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
*
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $Header: /cvsroot/pgsql/src/backend/access/common/tupdesc.c,v 1.35 1998/02/10 16:02:46 momjian Exp $
|
||||
* $Header: /cvsroot/pgsql/src/backend/access/common/tupdesc.c,v 1.36 1998/02/26 04:29:22 momjian Exp $
|
||||
*
|
||||
* NOTES
|
||||
* some of the executor utility code such as "ExecTypeFromTL" should be
|
||||
|
@ -306,7 +306,7 @@ TupleDescInitEntry(TupleDesc desc,
|
|||
att->attnum = attributeNumber;
|
||||
att->attnelems = attdim;
|
||||
att->attisset = attisset;
|
||||
|
||||
|
||||
att->attnotnull = false;
|
||||
att->atthasdef = false;
|
||||
|
||||
|
@ -487,7 +487,7 @@ BuildDescForRelation(List *schema, char *relname)
|
|||
if (arry != NIL)
|
||||
{
|
||||
/* array of XXX is _XXX */
|
||||
sprintf(typename, "_%.*s", NAMEDATALEN-2,entry->typename->name);
|
||||
sprintf(typename, "_%.*s", NAMEDATALEN - 2, entry->typename->name);
|
||||
attdim = length(arry);
|
||||
}
|
||||
else
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
*
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $Header: /cvsroot/pgsql/src/backend/access/hash/hash.c,v 1.17 1997/11/20 23:19:50 momjian Exp $
|
||||
* $Header: /cvsroot/pgsql/src/backend/access/hash/hash.c,v 1.18 1998/02/26 04:29:28 momjian Exp $
|
||||
*
|
||||
* NOTES
|
||||
* This file contains only the public interface routines.
|
||||
|
@ -306,7 +306,7 @@ hashinsert(Relation rel, Datum *datum, char *nulls, ItemPointer ht_ctid, Relatio
|
|||
/*
|
||||
* hashgettuple() -- Get the next tuple in the scan.
|
||||
*/
|
||||
char *
|
||||
char *
|
||||
hashgettuple(IndexScanDesc scan, ScanDirection dir)
|
||||
{
|
||||
RetrieveIndexResult res;
|
||||
|
@ -329,7 +329,7 @@ hashgettuple(IndexScanDesc scan, ScanDirection dir)
|
|||
/*
|
||||
* hashbeginscan() -- start a scan on a hash index
|
||||
*/
|
||||
char *
|
||||
char *
|
||||
hashbeginscan(Relation rel,
|
||||
bool fromEnd,
|
||||
uint16 keysz,
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
*
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $Header: /cvsroot/pgsql/src/backend/access/heap/heapam.c,v 1.26 1998/02/11 19:09:30 momjian Exp $
|
||||
* $Header: /cvsroot/pgsql/src/backend/access/heap/heapam.c,v 1.27 1998/02/26 04:29:31 momjian Exp $
|
||||
*
|
||||
*
|
||||
* INTERFACE ROUTINES
|
||||
|
@ -654,6 +654,7 @@ heap_beginscan(Relation relation,
|
|||
sdesc->rs_rd = relation;
|
||||
|
||||
if (nkeys)
|
||||
|
||||
/*
|
||||
* we do this here instead of in initsdesc() because heap_rescan
|
||||
* also calls initsdesc() and we don't want to allocate memory
|
||||
|
@ -1303,7 +1304,7 @@ heap_replace(Relation relation, ItemPointer otid, HeapTuple tup)
|
|||
Page dp;
|
||||
Buffer buffer;
|
||||
HeapTuple tuple;
|
||||
|
||||
|
||||
/* ----------------
|
||||
* increment access statistics
|
||||
* ----------------
|
||||
|
@ -1375,13 +1376,13 @@ heap_replace(Relation relation, ItemPointer otid, HeapTuple tup)
|
|||
* ----------------
|
||||
*/
|
||||
HeapTupleSatisfies(lp,
|
||||
relation,
|
||||
buffer,
|
||||
(PageHeader) dp,
|
||||
false,
|
||||
0,
|
||||
(ScanKey) NULL,
|
||||
tuple);
|
||||
relation,
|
||||
buffer,
|
||||
(PageHeader) dp,
|
||||
false,
|
||||
0,
|
||||
(ScanKey) NULL,
|
||||
tuple);
|
||||
if (!tuple)
|
||||
{
|
||||
ReleaseBuffer(buffer);
|
||||
|
|
|
@ -8,7 +8,7 @@
|
|||
*
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $Header: /cvsroot/pgsql/src/backend/access/index/Attic/istrat.c,v 1.16 1998/01/15 19:42:02 pgsql Exp $
|
||||
* $Header: /cvsroot/pgsql/src/backend/access/index/Attic/istrat.c,v 1.17 1998/02/26 04:29:36 momjian Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
|
@ -242,17 +242,17 @@ StrategyTermEvaluate(StrategyTerm term,
|
|||
switch (operator->flags ^ entry->sk_flags)
|
||||
{
|
||||
case 0x0:
|
||||
tmpres = (long) FMGR_PTR2(&entry->sk_func,
|
||||
tmpres = (long) FMGR_PTR2(&entry->sk_func,
|
||||
left, right);
|
||||
break;
|
||||
|
||||
case SK_NEGATE:
|
||||
tmpres = (long) !FMGR_PTR2(&entry->sk_func,
|
||||
tmpres = (long) !FMGR_PTR2(&entry->sk_func,
|
||||
left, right);
|
||||
break;
|
||||
|
||||
case SK_COMMUTE:
|
||||
tmpres = (long) FMGR_PTR2(&entry->sk_func,
|
||||
tmpres = (long) FMGR_PTR2(&entry->sk_func,
|
||||
right, left);
|
||||
break;
|
||||
|
||||
|
|
|
@ -8,7 +8,7 @@
|
|||
*
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $Header: /cvsroot/pgsql/src/backend/access/nbtree/nbtree.c,v 1.24 1997/11/20 23:20:21 momjian Exp $
|
||||
* $Header: /cvsroot/pgsql/src/backend/access/nbtree/nbtree.c,v 1.25 1998/02/26 04:29:44 momjian Exp $
|
||||
*
|
||||
* NOTES
|
||||
* This file contains only the public interface routines.
|
||||
|
@ -389,7 +389,7 @@ btinsert(Relation rel, Datum *datum, char *nulls, ItemPointer ht_ctid, Relation
|
|||
/*
|
||||
* btgettuple() -- Get the next tuple in the scan.
|
||||
*/
|
||||
char *
|
||||
char *
|
||||
btgettuple(IndexScanDesc scan, ScanDirection dir)
|
||||
{
|
||||
RetrieveIndexResult res;
|
||||
|
@ -411,7 +411,7 @@ btgettuple(IndexScanDesc scan, ScanDirection dir)
|
|||
/*
|
||||
* btbeginscan() -- start a scan on a btree index
|
||||
*/
|
||||
char *
|
||||
char *
|
||||
btbeginscan(Relation rel, bool fromEnd, uint16 keysz, ScanKey scankey)
|
||||
{
|
||||
IndexScanDesc scan;
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
*
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $Header: /cvsroot/pgsql/src/backend/access/nbtree/nbtsearch.c,v 1.30 1998/01/15 19:42:13 pgsql Exp $
|
||||
* $Header: /cvsroot/pgsql/src/backend/access/nbtree/nbtsearch.c,v 1.31 1998/02/26 04:29:50 momjian Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
|
@ -197,12 +197,11 @@ _bt_moveright(Relation rel,
|
|||
* if number of attrs > keysize. Example: (2,0) - last items
|
||||
* on this page, (2,1) - first item on next page (hikey), our
|
||||
* scankey is x = 2. Scankey == (2,1) because of we compare
|
||||
* first attrs only, but we shouldn't to move right of here.
|
||||
* - vadim 04/15/97
|
||||
*
|
||||
* first attrs only, but we shouldn't to move right of here. -
|
||||
* vadim 04/15/97
|
||||
*
|
||||
* Also, if this page is not LEAF one (and # of attrs > keysize)
|
||||
* then we can't move too.
|
||||
* - vadim 10/22/97
|
||||
* then we can't move too. - vadim 10/22/97
|
||||
*/
|
||||
|
||||
if (_bt_skeycmp(rel, keysz, scankey, page, hikey,
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
*
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $Id: nbtsort.c,v 1.28 1998/02/21 19:23:14 scrappy Exp $
|
||||
* $Id: nbtsort.c,v 1.29 1998/02/26 04:29:54 momjian Exp $
|
||||
*
|
||||
* NOTES
|
||||
*
|
||||
|
@ -553,7 +553,7 @@ _bt_tapeadd(BTTapeBlock *tape, BTItem item, int itemsz)
|
|||
* create and initialize a spool structure, including the underlying
|
||||
* files.
|
||||
*/
|
||||
void *
|
||||
void *
|
||||
_bt_spoolinit(Relation index, int ntapes, bool isunique)
|
||||
{
|
||||
BTSpool *btspool = (BTSpool *) palloc(sizeof(BTSpool));
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
*
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $Header: /cvsroot/pgsql/src/backend/access/rtree/Attic/rtproc.c,v 1.15 1998/01/07 21:02:05 momjian Exp $
|
||||
* $Header: /cvsroot/pgsql/src/backend/access/rtree/Attic/rtproc.c,v 1.16 1998/02/26 04:30:06 momjian Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
|
@ -39,7 +39,7 @@ rt_box_union(BOX *a, BOX *b)
|
|||
return (n);
|
||||
}
|
||||
|
||||
BOX *
|
||||
BOX *
|
||||
rt_box_inter(BOX *a, BOX *b)
|
||||
{
|
||||
BOX *n;
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
*
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $Header: /cvsroot/pgsql/src/backend/access/rtree/Attic/rtree.c,v 1.22 1998/01/15 19:42:19 pgsql Exp $
|
||||
* $Header: /cvsroot/pgsql/src/backend/access/rtree/Attic/rtree.c,v 1.23 1998/02/26 04:30:15 momjian Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
|
@ -956,7 +956,7 @@ freestack(RTSTACK *s)
|
|||
}
|
||||
}
|
||||
|
||||
char *
|
||||
char *
|
||||
rtdelete(Relation r, ItemPointer tid)
|
||||
{
|
||||
BlockNumber blkno;
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
*
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $Header: /cvsroot/pgsql/src/backend/access/transam/transam.c,v 1.16 1998/01/07 21:02:17 momjian Exp $
|
||||
* $Header: /cvsroot/pgsql/src/backend/access/transam/transam.c,v 1.17 1998/02/26 04:30:18 momjian Exp $
|
||||
*
|
||||
* NOTES
|
||||
* This file contains the high level access-method interface to the
|
||||
|
@ -47,8 +47,8 @@ Relation VariableRelation = (Relation) NULL;
|
|||
* global variables holding cached transaction id's and statuses.
|
||||
* ----------------
|
||||
*/
|
||||
TransactionId cachedTestXid;
|
||||
XidStatus cachedTestXidStatus;
|
||||
TransactionId cachedTestXid;
|
||||
XidStatus cachedTestXidStatus;
|
||||
|
||||
/* ----------------
|
||||
* transaction system constants
|
||||
|
@ -416,14 +416,14 @@ InitializeTransactionLog(void)
|
|||
VariableRelation = heap_openr(VariableRelationName);
|
||||
/* ----------------
|
||||
* XXX TransactionLogUpdate requires that LogRelation
|
||||
* is valid so we temporarily set it so we can initialize
|
||||
* is valid so we temporarily set it so we can initialize
|
||||
* things properly. This could be done cleaner.
|
||||
* ----------------
|
||||
*/
|
||||
LogRelation = logRelation;
|
||||
|
||||
/* ----------------
|
||||
* if we have a virgin database, we initialize the log
|
||||
* if we have a virgin database, we initialize the log
|
||||
* relation by committing the AmiTransactionId (id 512) and we
|
||||
* initialize the variable relation by setting the next available
|
||||
* transaction id to FirstTransactionId (id 514). OID initialization
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
*
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $Header: /cvsroot/pgsql/src/backend/access/transam/Attic/xid.c,v 1.11 1997/11/02 15:24:47 vadim Exp $
|
||||
* $Header: /cvsroot/pgsql/src/backend/access/transam/Attic/xid.c,v 1.12 1998/02/26 04:30:19 momjian Exp $
|
||||
*
|
||||
* OLD COMMENTS
|
||||
* XXX WARNING
|
||||
|
@ -38,7 +38,7 @@ xidin(char *representation)
|
|||
}
|
||||
|
||||
/* XXX char16 name for catalogs */
|
||||
char *
|
||||
char *
|
||||
xidout(TransactionId transactionId)
|
||||
{
|
||||
/* return(TransactionIdFormString(transactionId)); */
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
* Copyright (c) 1994, Regents of the University of California
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $Header: /cvsroot/pgsql/src/backend/bootstrap/bootstrap.c,v 1.36 1998/02/11 19:09:34 momjian Exp $
|
||||
* $Header: /cvsroot/pgsql/src/backend/bootstrap/bootstrap.c,v 1.37 1998/02/26 04:30:22 momjian Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
|
@ -200,19 +200,21 @@ int numattr; /* number of attributes for cur. rel */
|
|||
extern int fsyncOff; /* do not fsync the database */
|
||||
|
||||
/* The test for HAVE_SIGSETJMP fails on Linux 2.0.x because the test
|
||||
* explicitly disallows sigsetjmp being a #define, which is how it
|
||||
* is declared in Linux. So, to avoid compiler warnings about
|
||||
* sigsetjmp() being redefined, let's not redefine unless necessary.
|
||||
* explicitly disallows sigsetjmp being a #define, which is how it
|
||||
* is declared in Linux. So, to avoid compiler warnings about
|
||||
* sigsetjmp() being redefined, let's not redefine unless necessary.
|
||||
* - thomas 1997-12-27
|
||||
*/
|
||||
|
||||
#if !defined(HAVE_SIGSETJMP) && !defined(sigsetjmp)
|
||||
static jmp_buf Warn_restart;
|
||||
|
||||
#define sigsetjmp(x,y) setjmp(x)
|
||||
#define siglongjmp longjmp
|
||||
|
||||
#else
|
||||
static sigjmp_buf Warn_restart;
|
||||
|
||||
#endif
|
||||
|
||||
int DebugMode;
|
||||
|
@ -472,8 +474,8 @@ boot_openrel(char *relname)
|
|||
HeapScanDesc sdesc;
|
||||
HeapTuple tup;
|
||||
|
||||
if (strlen(relname) >= NAMEDATALEN-1)
|
||||
relname[NAMEDATALEN-1] = '\0';
|
||||
if (strlen(relname) >= NAMEDATALEN - 1)
|
||||
relname[NAMEDATALEN - 1] = '\0';
|
||||
|
||||
if (Typ == (struct typmap **) NULL)
|
||||
{
|
||||
|
@ -907,7 +909,7 @@ AllocateAttribute()
|
|||
* be freed by the CALLER.
|
||||
* ----------------
|
||||
*/
|
||||
char *
|
||||
char *
|
||||
MapArrayTypeName(char *s)
|
||||
{
|
||||
int i,
|
||||
|
@ -960,7 +962,7 @@ EnterString(char *str)
|
|||
* associated with the idnum
|
||||
* ----------------
|
||||
*/
|
||||
char *
|
||||
char *
|
||||
LexIDStr(int ident_num)
|
||||
{
|
||||
return (strtable[ident_num]);
|
||||
|
@ -979,7 +981,7 @@ LexIDStr(int ident_num)
|
|||
static int
|
||||
CompHash(char *str, int len)
|
||||
{
|
||||
int result;
|
||||
int result;
|
||||
|
||||
result = (NUM * str[0] + NUMSQR * str[len - 1] + NUMCUBE * str[(len - 1) / 2]);
|
||||
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
*
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $Header: /cvsroot/pgsql/src/backend/catalog/aclchk.c,v 1.7 1998/02/25 13:05:57 scrappy Exp $
|
||||
* $Header: /cvsroot/pgsql/src/backend/catalog/aclchk.c,v 1.8 1998/02/26 04:30:26 momjian Exp $
|
||||
*
|
||||
* NOTES
|
||||
* See acl.h.
|
||||
|
@ -74,7 +74,7 @@ char *aclcheck_error_strings[] = {
|
|||
static
|
||||
dumpacl(Acl *acl)
|
||||
{
|
||||
unsigned i;
|
||||
unsigned i;
|
||||
AclItem *aip;
|
||||
|
||||
elog(DEBUG, "acl size = %d, # acls = %d",
|
||||
|
@ -94,7 +94,7 @@ ChangeAcl(char *relname,
|
|||
AclItem *mod_aip,
|
||||
unsigned modechg)
|
||||
{
|
||||
unsigned i;
|
||||
unsigned i;
|
||||
Acl *old_acl = (Acl *) NULL,
|
||||
*new_acl;
|
||||
Relation relation;
|
||||
|
@ -211,7 +211,7 @@ get_grosysid(char *groname)
|
|||
return (id);
|
||||
}
|
||||
|
||||
char *
|
||||
char *
|
||||
get_groname(AclId grosysid)
|
||||
{
|
||||
HeapTuple htp;
|
||||
|
@ -283,8 +283,8 @@ in_group(AclId uid, AclId gid)
|
|||
static int32
|
||||
aclcheck(char *relname, Acl *acl, AclId id, AclIdType idtype, AclMode mode)
|
||||
{
|
||||
unsigned i;
|
||||
AclItem *aip,
|
||||
unsigned i;
|
||||
AclItem *aip,
|
||||
*aidat;
|
||||
unsigned num,
|
||||
found_group;
|
||||
|
@ -417,7 +417,7 @@ pg_aclcheck(char *relname, char *usename, AclMode mode)
|
|||
|
||||
/*
|
||||
* Deny anyone permission to update a system catalog unless
|
||||
* pg_shadow.usecatupd is set. (This is to let superusers protect
|
||||
* pg_shadow.usecatupd is set. (This is to let superusers protect
|
||||
* themselves from themselves.)
|
||||
*/
|
||||
if (((mode & ACL_WR) || (mode & ACL_AP)) &&
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
*
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $Header: /cvsroot/pgsql/src/backend/catalog/catalog.c,v 1.14 1998/02/11 19:09:47 momjian Exp $
|
||||
* $Header: /cvsroot/pgsql/src/backend/catalog/catalog.c,v 1.15 1998/02/26 04:30:31 momjian Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
|
@ -26,7 +26,7 @@
|
|||
* relpath - path to the relation
|
||||
* Perhaps this should be in-line code in relopen().
|
||||
*/
|
||||
char *
|
||||
char *
|
||||
relpath(char relname[])
|
||||
{
|
||||
char *path;
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
*
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $Header: /cvsroot/pgsql/src/backend/catalog/heap.c,v 1.46 1998/02/11 19:09:54 momjian Exp $
|
||||
* $Header: /cvsroot/pgsql/src/backend/catalog/heap.c,v 1.47 1998/02/26 04:30:35 momjian Exp $
|
||||
*
|
||||
* INTERFACE ROUTINES
|
||||
* heap_create() - Create an uncataloged heap relation
|
||||
|
@ -63,8 +63,9 @@
|
|||
#include <string.h>
|
||||
#endif
|
||||
|
||||
static void AddPgRelationTuple(Relation pg_class_desc,
|
||||
Relation new_rel_desc, Oid new_rel_oid, unsigned natts);
|
||||
static void
|
||||
AddPgRelationTuple(Relation pg_class_desc,
|
||||
Relation new_rel_desc, Oid new_rel_oid, unsigned natts);
|
||||
static void AddToTempRelList(Relation r);
|
||||
static void DeletePgAttributeTuples(Relation rdesc);
|
||||
static void DeletePgRelationTuple(Relation rdesc);
|
||||
|
@ -164,14 +165,14 @@ static TempRelList *tempRels = NULL;
|
|||
*
|
||||
*
|
||||
* if heap_create is called with "" as the name, then heap_create will create
|
||||
* a temporary name "temp_$RELOID" for the relation
|
||||
* a temporary name "temp_$RELOID" for the relation
|
||||
* ----------------------------------------------------------------
|
||||
*/
|
||||
Relation
|
||||
heap_create(char *name,
|
||||
TupleDesc tupDesc)
|
||||
{
|
||||
unsigned i;
|
||||
unsigned i;
|
||||
Oid relid;
|
||||
Relation rdesc;
|
||||
int len;
|
||||
|
@ -378,7 +379,7 @@ heap_create(char *name,
|
|||
* create new relation
|
||||
* insert new relation into attribute catalog
|
||||
*
|
||||
* Should coordinate with heap_create_with_catalogr(). Either
|
||||
* Should coordinate with heap_create_with_catalogr(). Either
|
||||
* it should not be called or there should be a way to prevent
|
||||
* the relation from being removed at the end of the
|
||||
* transaction if it is successful ('u'/'r' may be enough).
|
||||
|
@ -726,14 +727,14 @@ addNewRelationType(char *typeName, Oid new_rel_oid)
|
|||
*/
|
||||
new_type_oid = TypeCreate(typeName, /* type name */
|
||||
new_rel_oid, /* relation oid */
|
||||
typeLen(typeidType(OIDOID)), /* internal size */
|
||||
typeLen(typeidType(OIDOID)), /* external size */
|
||||
typeLen(typeidType(OIDOID)), /* internal size */
|
||||
typeLen(typeidType(OIDOID)), /* external size */
|
||||
'c', /* type-type (catalog) */
|
||||
',', /* default array delimiter */
|
||||
"int4in", /* input procedure */
|
||||
"int4out",/* output procedure */
|
||||
"int4in", /* receive procedure */
|
||||
"int4out",/* send procedure */
|
||||
"int4out", /* output procedure */
|
||||
"int4in", /* receive procedure */
|
||||
"int4out", /* send procedure */
|
||||
NULL, /* array element type - irrelevent */
|
||||
"-", /* default type value */
|
||||
(bool) 1, /* passed by value */
|
||||
|
@ -748,7 +749,7 @@ addNewRelationType(char *typeName, Oid new_rel_oid)
|
|||
*/
|
||||
Oid
|
||||
heap_create_with_catalog(char relname[],
|
||||
TupleDesc tupdesc)
|
||||
TupleDesc tupdesc)
|
||||
{
|
||||
Relation pg_class_desc;
|
||||
Relation new_rel_desc;
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
*
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $Header: /cvsroot/pgsql/src/backend/catalog/index.c,v 1.38 1998/02/07 21:41:48 momjian Exp $
|
||||
* $Header: /cvsroot/pgsql/src/backend/catalog/index.c,v 1.39 1998/02/26 04:30:38 momjian Exp $
|
||||
*
|
||||
*
|
||||
* INTERFACE ROUTINES
|
||||
|
@ -119,7 +119,7 @@ DefaultBuild(Relation heapRelation, Relation indexRelation,
|
|||
*/
|
||||
static FormData_pg_attribute sysatts[] = {
|
||||
{0l, {"ctid"}, 27l, 0l, 6, -1, 0, -1, -1, '\0', '\0', 'i', '\0', '\0'},
|
||||
{0l, {"oid"}, 26l, 0l, 4, -2, 0, -1, -1, '\001', '\0', 'i', '\0', '\0'},
|
||||
{0l, {"oid"}, 26l, 0l, 4, -2, 0, -1, -1, '\001', '\0', 'i', '\0', '\0'},
|
||||
{0l, {"xmin"}, 28l, 0l, 4, -3, 0, -1, -1, '\0', '\0', 'i', '\0', '\0'},
|
||||
{0l, {"cmin"}, 29l, 0l, 4, -4, 0, -1, -1, '\001', '\0', 'i', '\0', '\0'},
|
||||
{0l, {"xmax"}, 28l, 0l, 4, -5, 0, -1, -1, '\0', '\0', 'i', '\0', '\0'},
|
||||
|
@ -460,7 +460,7 @@ ConstructTupleDescriptor(Oid heapoid,
|
|||
((TypeTupleForm) ((char *) tup + tup->t_hoff))->typbyval;
|
||||
|
||||
((AttributeTupleForm) to)->attlen =
|
||||
((TypeTupleForm) ((char *) tup + tup->t_hoff))->typlen;
|
||||
((TypeTupleForm) ((char *) tup + tup->t_hoff))->typlen;
|
||||
|
||||
((AttributeTupleForm) to)->atttypmod = IndexKeyType->typmod;
|
||||
}
|
||||
|
@ -1100,7 +1100,7 @@ index_create(char *heapRelationName,
|
|||
* write lock heap to guarantee exclusive access
|
||||
* ----------------
|
||||
RelationSetLockForWrite(heapRelation);
|
||||
* ^^^^^
|
||||
* ^^^^^
|
||||
* Does it have any sense ? - vadim 10/27/97
|
||||
*/
|
||||
|
||||
|
@ -1611,7 +1611,7 @@ DefaultBuild(Relation heapRelation,
|
|||
*/
|
||||
scan = heap_beginscan(heapRelation, /* relation */
|
||||
0, /* start at end */
|
||||
false, /* seeself */
|
||||
false,/* seeself */
|
||||
0, /* number of keys */
|
||||
(ScanKey) NULL); /* scan key */
|
||||
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
*
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $Header: /cvsroot/pgsql/src/backend/catalog/pg_aggregate.c,v 1.12 1998/02/11 19:10:03 momjian Exp $
|
||||
* $Header: /cvsroot/pgsql/src/backend/catalog/pg_aggregate.c,v 1.13 1998/02/26 04:30:40 momjian Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
|
@ -267,7 +267,7 @@ AggregateCreate(char *aggName,
|
|||
|
||||
}
|
||||
|
||||
char *
|
||||
char *
|
||||
AggNameGetInitVal(char *aggName, Oid basetype, int xfuncno, bool *isNull)
|
||||
{
|
||||
HeapTuple tup;
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
*
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $Header: /cvsroot/pgsql/src/backend/catalog/pg_operator.c,v 1.21 1998/02/11 19:10:11 momjian Exp $
|
||||
* $Header: /cvsroot/pgsql/src/backend/catalog/pg_operator.c,v 1.22 1998/02/26 04:30:41 momjian Exp $
|
||||
*
|
||||
* NOTES
|
||||
* these routines moved here from commands/define.c and somewhat cleaned up.
|
||||
|
@ -224,7 +224,7 @@ OperatorShellMakeWithOpenRelation(Relation pg_operator_desc,
|
|||
Oid leftObjectId,
|
||||
Oid rightObjectId)
|
||||
{
|
||||
int i;
|
||||
int i;
|
||||
HeapTuple tup;
|
||||
Datum values[Natts_pg_operator];
|
||||
char nulls[Natts_pg_operator];
|
||||
|
@ -782,7 +782,7 @@ OperatorUpd(Oid baseId, Oid commId, Oid negId)
|
|||
};
|
||||
|
||||
fmgr_info(ObjectIdEqualRegProcedure, &opKey[0].sk_func);
|
||||
opKey[0].sk_nargs = opKey[0].sk_func.fn_nargs;
|
||||
opKey[0].sk_nargs = opKey[0].sk_func.fn_nargs;
|
||||
|
||||
for (i = 0; i < Natts_pg_operator; ++i)
|
||||
{
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
*
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $Header: /cvsroot/pgsql/src/backend/catalog/pg_proc.c,v 1.14 1998/02/11 19:10:16 momjian Exp $
|
||||
* $Header: /cvsroot/pgsql/src/backend/catalog/pg_proc.c,v 1.15 1998/02/26 04:30:43 momjian Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
|
@ -216,7 +216,7 @@ ProcedureCreate(char *procedureName,
|
|||
if (strcmp(languageName, "sql") == 0)
|
||||
{
|
||||
plan_list = pg_parse_and_plan(prosrc, typev, parameterCount,
|
||||
&querytree_list, dest);
|
||||
&querytree_list, dest);
|
||||
|
||||
/* typecheck return value */
|
||||
pg_checkretval(typeObjectId, querytree_list);
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
*
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $Header: /cvsroot/pgsql/src/backend/catalog/pg_type.c,v 1.19 1998/02/11 19:10:18 momjian Exp $
|
||||
* $Header: /cvsroot/pgsql/src/backend/catalog/pg_type.c,v 1.20 1998/02/26 04:30:45 momjian Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
|
@ -155,7 +155,7 @@ TypeGet(char *typeName, /* name of type to be fetched */
|
|||
static Oid
|
||||
TypeShellMakeWithOpenRelation(Relation pg_type_desc, char *typeName)
|
||||
{
|
||||
int i;
|
||||
int i;
|
||||
HeapTuple tup;
|
||||
Datum values[Natts_pg_type];
|
||||
char nulls[Natts_pg_type];
|
||||
|
@ -605,7 +605,7 @@ TypeRename(char *oldTypeName, char *newTypeName)
|
|||
* the CALLER is responsible for pfreeing the
|
||||
*/
|
||||
|
||||
char *
|
||||
char *
|
||||
makeArrayTypeName(char *typeName)
|
||||
{
|
||||
char *arr;
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
*
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $Header: /cvsroot/pgsql/src/backend/commands/async.c,v 1.28 1998/01/31 04:38:17 momjian Exp $
|
||||
* $Header: /cvsroot/pgsql/src/backend/commands/async.c,v 1.29 1998/02/26 04:30:47 momjian Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
|
@ -84,7 +84,7 @@
|
|||
#include <libpq/libpq.h>
|
||||
|
||||
#ifndef HAVE_STRDUP
|
||||
# include <port-protos.h> /* for strdup() */
|
||||
#include <port-protos.h> /* for strdup() */
|
||||
#endif
|
||||
|
||||
#include <storage/lmgr.h>
|
||||
|
@ -97,7 +97,7 @@ static Dllist *pendingNotifies = NULL;
|
|||
static int AsyncExistsPendingNotify(char *);
|
||||
static void ClearPendingNotify(void);
|
||||
static void Async_NotifyFrontEnd(void);
|
||||
void Async_Unlisten(char *relname, int pid);
|
||||
void Async_Unlisten(char *relname, int pid);
|
||||
static void Async_UnlistenOnExit(int code, char *relname);
|
||||
|
||||
/*
|
||||
|
@ -617,7 +617,7 @@ Async_NotifyFrontEnd()
|
|||
if (whereToSendOutput == Remote)
|
||||
{
|
||||
pq_putnchar("A", 1);
|
||||
pq_putint((int32)MyProcPid, sizeof(int32));
|
||||
pq_putint((int32) MyProcPid, sizeof(int32));
|
||||
pq_putstr(DatumGetName(d)->data);
|
||||
pq_flush();
|
||||
}
|
||||
|
|
|
@ -14,7 +14,7 @@
|
|||
*
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $Header: /cvsroot/pgsql/src/backend/commands/cluster.c,v 1.22 1998/01/10 05:19:03 momjian Exp $
|
||||
* $Header: /cvsroot/pgsql/src/backend/commands/cluster.c,v 1.23 1998/02/26 04:30:49 momjian Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
|
@ -212,8 +212,8 @@ copy_heap(Oid OIDOldHeap)
|
|||
OldHeapDesc = RelationGetTupleDescriptor(OldHeap);
|
||||
|
||||
/*
|
||||
* Need to make a copy of the tuple descriptor, heap_create_with_catalog
|
||||
* modifies it.
|
||||
* Need to make a copy of the tuple descriptor,
|
||||
* heap_create_with_catalog modifies it.
|
||||
*/
|
||||
|
||||
tupdesc = CreateTupleDescCopy(OldHeapDesc);
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
*
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $Header: /cvsroot/pgsql/src/backend/commands/Attic/command.c,v 1.25 1998/02/07 21:41:52 momjian Exp $
|
||||
* $Header: /cvsroot/pgsql/src/backend/commands/Attic/command.c,v 1.26 1998/02/26 04:30:49 momjian Exp $
|
||||
*
|
||||
* NOTES
|
||||
* The PortalExecutorHeapMemory crap needs to be eliminated
|
||||
|
@ -97,10 +97,10 @@ PerformPortalFetch(char *name,
|
|||
char *tag,
|
||||
CommandDest dest)
|
||||
{
|
||||
Portal portal;
|
||||
int feature;
|
||||
QueryDesc *queryDesc;
|
||||
MemoryContext context;
|
||||
Portal portal;
|
||||
int feature;
|
||||
QueryDesc *queryDesc;
|
||||
MemoryContext context;
|
||||
|
||||
/* ----------------
|
||||
* sanity checks
|
||||
|
@ -148,16 +148,16 @@ PerformPortalFetch(char *name,
|
|||
* ----------------
|
||||
*/
|
||||
queryDesc = PortalGetQueryDesc(portal);
|
||||
|
||||
if ( dest == None ) /* MOVE */
|
||||
|
||||
if (dest == None) /* MOVE */
|
||||
{
|
||||
QueryDesc *qdesc = (QueryDesc *) palloc (sizeof (QueryDesc));
|
||||
|
||||
memcpy (qdesc, queryDesc, sizeof (QueryDesc));
|
||||
QueryDesc *qdesc = (QueryDesc *) palloc(sizeof(QueryDesc));
|
||||
|
||||
memcpy(qdesc, queryDesc, sizeof(QueryDesc));
|
||||
qdesc->dest = dest;
|
||||
queryDesc = qdesc;
|
||||
}
|
||||
|
||||
|
||||
BeginCommand(name,
|
||||
queryDesc->operation,
|
||||
portal->attinfo, /* QueryDescGetTypeInfo(queryDesc),
|
||||
|
@ -178,9 +178,9 @@ PerformPortalFetch(char *name,
|
|||
|
||||
ExecutorRun(queryDesc, PortalGetState(portal), feature, count);
|
||||
|
||||
if ( dest == None ) /* MOVE */
|
||||
pfree (queryDesc);
|
||||
|
||||
if (dest == None) /* MOVE */
|
||||
pfree(queryDesc);
|
||||
|
||||
/* ----------------
|
||||
* Note: the "end-of-command" tag is returned by higher-level
|
||||
* utility code
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
*
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $Header: /cvsroot/pgsql/src/backend/commands/copy.c,v 1.43 1998/02/25 13:06:08 scrappy Exp $
|
||||
* $Header: /cvsroot/pgsql/src/backend/commands/copy.c,v 1.44 1998/02/26 04:30:52 momjian Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
|
@ -48,7 +48,8 @@ static Oid GetOutputFunction(Oid type);
|
|||
static Oid GetTypeElement(Oid type);
|
||||
static Oid GetInputFunction(Oid type);
|
||||
static Oid IsTypeByVal(Oid type);
|
||||
static void GetIndexRelations(Oid main_relation_oid,
|
||||
static void
|
||||
GetIndexRelations(Oid main_relation_oid,
|
||||
int *n_indices,
|
||||
Relation **index_rels);
|
||||
|
||||
|
@ -64,7 +65,7 @@ static void CopyAttributeOut(FILE *fp, char *string, char *delim);
|
|||
static int CountTuples(Relation relation);
|
||||
|
||||
extern FILE *Pfout,
|
||||
*Pfin;
|
||||
*Pfin;
|
||||
|
||||
static int lineno;
|
||||
|
||||
|
@ -275,7 +276,7 @@ CopyTo(Relation rel, bool binary, bool oids, FILE *fp, char *delim)
|
|||
if (!isnull)
|
||||
{
|
||||
string = (char *) (*fmgr_faddr(&out_functions[i]))
|
||||
(value, elements[i], typmod[i]);
|
||||
(value, elements[i], typmod[i]);
|
||||
CopyAttributeOut(fp, string, delim);
|
||||
pfree(string);
|
||||
}
|
||||
|
@ -582,8 +583,8 @@ CopyFrom(Relation rel, bool binary, bool oids, FILE *fp, char *delim)
|
|||
{
|
||||
values[i] =
|
||||
(Datum) (*fmgr_faddr(&in_functions[i])) (string,
|
||||
elements[i],
|
||||
typmod[i]);
|
||||
elements[i],
|
||||
typmod[i]);
|
||||
|
||||
/*
|
||||
* Sanity check - by reference attributes cannot
|
||||
|
@ -592,7 +593,7 @@ CopyFrom(Relation rel, bool binary, bool oids, FILE *fp, char *delim)
|
|||
if (!PointerIsValid(values[i]) &&
|
||||
!(rel->rd_att->attrs[i]->attbyval))
|
||||
{
|
||||
elog(ERROR, "copy from line %d: Bad file format",lineno);
|
||||
elog(ERROR, "copy from line %d: Bad file format", lineno);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
*
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $Header: /cvsroot/pgsql/src/backend/commands/Attic/creatinh.c,v 1.25 1998/02/10 04:00:18 momjian Exp $
|
||||
* $Header: /cvsroot/pgsql/src/backend/commands/Attic/creatinh.c,v 1.26 1998/02/26 04:30:55 momjian Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
|
@ -58,7 +58,7 @@ DefineRelation(CreateStmt *stmt)
|
|||
if (strlen(stmt->relname) >= NAMEDATALEN)
|
||||
elog(ERROR, "the relation name %s is >= %d characters long", stmt->relname,
|
||||
NAMEDATALEN);
|
||||
StrNCpy(relname, stmt->relname, NAMEDATALEN); /* make full length for
|
||||
StrNCpy(relname, stmt->relname, NAMEDATALEN); /* make full length for
|
||||
* copy */
|
||||
|
||||
/* ----------------
|
||||
|
@ -253,7 +253,7 @@ MergeAttributes(List *schema, List *supers, List **supconstr)
|
|||
if (relation == NULL)
|
||||
{
|
||||
elog(ERROR,
|
||||
"MergeAttr: Can't inherit from non-existent superclass '%s'", name);
|
||||
"MergeAttr: Can't inherit from non-existent superclass '%s'", name);
|
||||
}
|
||||
if (relation->rd_rel->relkind == 'S')
|
||||
{
|
||||
|
@ -334,7 +334,8 @@ MergeAttributes(List *schema, List *supers, List **supconstr)
|
|||
|
||||
for (i = 0; i < constr->num_check; i++)
|
||||
{
|
||||
Constraint *cdef = (Constraint *) makeNode(Constraint); /* palloc(sizeof(Constraint)); */
|
||||
Constraint *cdef = (Constraint *) makeNode(Constraint); /* palloc(sizeof(Constrai
|
||||
* nt)); */
|
||||
|
||||
cdef->contype = CONSTR_CHECK;
|
||||
if (check[i].ccname[0] == '$')
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
*
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $Header: /cvsroot/pgsql/src/backend/commands/dbcommands.c,v 1.7 1998/02/25 13:06:09 scrappy Exp $
|
||||
* $Header: /cvsroot/pgsql/src/backend/commands/dbcommands.c,v 1.8 1998/02/26 04:30:56 momjian Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
|
@ -61,10 +61,10 @@ createdb(char *dbname, char *dbpath)
|
|||
closeAllVfds();
|
||||
|
||||
/* Now create directory for this new database */
|
||||
if ((dbpath != NULL) && (strcmp(dbpath,dbname) != 0))
|
||||
if ((dbpath != NULL) && (strcmp(dbpath, dbname) != 0))
|
||||
{
|
||||
if (*(dbpath+strlen(dbpath)-1) == SEP_CHAR)
|
||||
*(dbpath+strlen(dbpath)-1) = '\0';
|
||||
if (*(dbpath + strlen(dbpath) - 1) == SEP_CHAR)
|
||||
*(dbpath + strlen(dbpath) - 1) = '\0';
|
||||
sprintf(loc, "%s%c%s", dbpath, SEP_CHAR, dbname);
|
||||
}
|
||||
else
|
||||
|
@ -75,12 +75,12 @@ createdb(char *dbname, char *dbpath)
|
|||
lp = ExpandDatabasePath(loc);
|
||||
|
||||
if (lp == NULL)
|
||||
elog(ERROR,"Unable to locate path '%s'"
|
||||
"\n\tThis may be due to a missing environment variable"
|
||||
" in the server",loc);
|
||||
elog(ERROR, "Unable to locate path '%s'"
|
||||
"\n\tThis may be due to a missing environment variable"
|
||||
" in the server", loc);
|
||||
|
||||
if (mkdir(lp,S_IRWXU) != 0)
|
||||
elog(ERROR,"Unable to create database directory %s",lp);
|
||||
if (mkdir(lp, S_IRWXU) != 0)
|
||||
elog(ERROR, "Unable to create database directory %s", lp);
|
||||
|
||||
sprintf(buf, "%s %s%cbase%ctemplate1%c* %s",
|
||||
COPY_CMD, DataDir, SEP_CHAR, SEP_CHAR, SEP_CHAR, lp);
|
||||
|
@ -93,7 +93,7 @@ createdb(char *dbname, char *dbpath)
|
|||
#endif
|
||||
|
||||
sprintf(buf, "insert into pg_database (datname, datdba, datpath)"
|
||||
" values (\'%s\', \'%d\', \'%s\');", dbname, user_id, loc);
|
||||
" values (\'%s\', \'%d\', \'%s\');", dbname, user_id, loc);
|
||||
|
||||
pg_exec_query(buf, (char **) NULL, (Oid *) NULL, 0);
|
||||
}
|
||||
|
@ -104,7 +104,7 @@ destroydb(char *dbname)
|
|||
Oid user_id,
|
||||
db_id;
|
||||
char *path;
|
||||
char dbpath[MAXPGPATH+1];
|
||||
char dbpath[MAXPGPATH + 1];
|
||||
char buf[512];
|
||||
|
||||
/*
|
||||
|
@ -122,10 +122,10 @@ destroydb(char *dbname)
|
|||
stop_vacuum(dbpath, dbname);
|
||||
|
||||
path = ExpandDatabasePath(dbpath);
|
||||
if (path == NULL)
|
||||
elog(ERROR,"Unable to locate path '%s'"
|
||||
"\n\tThis may be due to a missing environment variable"
|
||||
" in the server",dbpath);
|
||||
if (path == NULL)
|
||||
elog(ERROR, "Unable to locate path '%s'"
|
||||
"\n\tThis may be due to a missing environment variable"
|
||||
" in the server", dbpath);
|
||||
|
||||
/*
|
||||
* remove the pg_database tuple FIRST, this may fail due to
|
||||
|
@ -206,7 +206,7 @@ check_permissions(char *command,
|
|||
bool use_super;
|
||||
char *userName;
|
||||
text *dbtext;
|
||||
char path[MAXPGPATH+1];
|
||||
char path[MAXPGPATH + 1];
|
||||
|
||||
userName = GetPgUserName();
|
||||
utup = SearchSysCacheTuple(USENAME, PointerGetDatum(userName),
|
||||
|
@ -264,12 +264,12 @@ check_permissions(char *command,
|
|||
(char *) NULL);
|
||||
*dbIdP = dbtup->t_oid;
|
||||
dbtext = (text *) heap_getattr(dbtup,
|
||||
Anum_pg_database_datpath,
|
||||
RelationGetTupleDescriptor(dbrel),
|
||||
(char *) NULL);
|
||||
Anum_pg_database_datpath,
|
||||
RelationGetTupleDescriptor(dbrel),
|
||||
(char *) NULL);
|
||||
|
||||
strncpy(path, VARDATA(dbtext), (VARSIZE(dbtext)-VARHDRSZ));
|
||||
*(path+VARSIZE(dbtext)-VARHDRSZ) = '\0';
|
||||
strncpy(path, VARDATA(dbtext), (VARSIZE(dbtext) - VARHDRSZ));
|
||||
*(path + VARSIZE(dbtext) - VARHDRSZ) = '\0';
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -304,7 +304,7 @@ check_permissions(char *command,
|
|||
|
||||
if (dbfound && !strcmp(command, "destroydb"))
|
||||
strcpy(dbpath, path);
|
||||
} /* check_permissions() */
|
||||
} /* check_permissions() */
|
||||
|
||||
/*
|
||||
* stop_vacuum() -- stop the vacuum daemon on the database, if one is running.
|
||||
|
@ -319,7 +319,7 @@ stop_vacuum(char *dbpath, char *dbname)
|
|||
if (strchr(dbpath, SEP_CHAR) != 0)
|
||||
{
|
||||
sprintf(filename, "%s%cbase%c%s%c%s.vacuum", DataDir, SEP_CHAR, SEP_CHAR,
|
||||
dbname, SEP_CHAR, dbname);
|
||||
dbname, SEP_CHAR, dbname);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
|
@ -9,7 +9,7 @@
|
|||
*
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $Header: /cvsroot/pgsql/src/backend/commands/define.c,v 1.23 1998/02/25 13:06:12 scrappy Exp $
|
||||
* $Header: /cvsroot/pgsql/src/backend/commands/define.c,v 1.24 1998/02/26 04:30:57 momjian Exp $
|
||||
*
|
||||
* DESCRIPTION
|
||||
* The "DefineFoo" routines take the parse tree and pick out the
|
||||
|
@ -265,39 +265,42 @@ CreateFunction(ProcedureStmt *stmt, CommandDest dest)
|
|||
}
|
||||
else
|
||||
{
|
||||
HeapTuple languageTuple;
|
||||
Form_pg_language languageStruct;
|
||||
HeapTuple languageTuple;
|
||||
Form_pg_language languageStruct;
|
||||
|
||||
/* Lookup the language in the system cache */
|
||||
/* Lookup the language in the system cache */
|
||||
languageTuple = SearchSysCacheTuple(LANNAME,
|
||||
PointerGetDatum(languageName),
|
||||
0, 0, 0);
|
||||
|
||||
if (!HeapTupleIsValid(languageTuple)) {
|
||||
PointerGetDatum(languageName),
|
||||
0, 0, 0);
|
||||
|
||||
elog(ERROR,
|
||||
"Unrecognized language specified in a CREATE FUNCTION: "
|
||||
"'%s'. Recognized languages are sql, C, internal "
|
||||
"and the created procedural languages.",
|
||||
languageName);
|
||||
if (!HeapTupleIsValid(languageTuple))
|
||||
{
|
||||
|
||||
elog(ERROR,
|
||||
"Unrecognized language specified in a CREATE FUNCTION: "
|
||||
"'%s'. Recognized languages are sql, C, internal "
|
||||
"and the created procedural languages.",
|
||||
languageName);
|
||||
}
|
||||
|
||||
/* Check that this language is a PL */
|
||||
languageStruct = (Form_pg_language) GETSTRUCT(languageTuple);
|
||||
if (!(languageStruct->lanispl)) {
|
||||
elog(ERROR,
|
||||
"Language '%s' isn't defined as PL", languageName);
|
||||
if (!(languageStruct->lanispl))
|
||||
{
|
||||
elog(ERROR,
|
||||
"Language '%s' isn't defined as PL", languageName);
|
||||
}
|
||||
|
||||
/*
|
||||
* Functions in untrusted procedural languages are
|
||||
* restricted to be defined by postgres superusers only
|
||||
* Functions in untrusted procedural languages are restricted to
|
||||
* be defined by postgres superusers only
|
||||
*/
|
||||
if (languageStruct->lanpltrusted == false && !superuser()) {
|
||||
elog(ERROR, "Only users with Postgres superuser privilege "
|
||||
"are permitted to create a function in the '%s' "
|
||||
"language.",
|
||||
languageName);
|
||||
if (languageStruct->lanpltrusted == false && !superuser())
|
||||
{
|
||||
elog(ERROR, "Only users with Postgres superuser privilege "
|
||||
"are permitted to create a function in the '%s' "
|
||||
"language.",
|
||||
languageName);
|
||||
}
|
||||
|
||||
lanisPL = true;
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
*
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $Header: /cvsroot/pgsql/src/backend/commands/explain.c,v 1.17 1998/02/13 03:21:30 vadim Exp $
|
||||
* $Header: /cvsroot/pgsql/src/backend/commands/explain.c,v 1.18 1998/02/26 04:30:58 momjian Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
|
@ -204,23 +204,23 @@ explain_outNode(StringInfo str, Plan *plan, int indent, ExplainState *es)
|
|||
appendStringInfo(str, buf);
|
||||
}
|
||||
appendStringInfo(str, "\n");
|
||||
|
||||
|
||||
/* initPlan-s */
|
||||
if (plan->initPlan)
|
||||
{
|
||||
List *saved_rtable = es->rtable;
|
||||
List *lst;
|
||||
|
||||
List *saved_rtable = es->rtable;
|
||||
List *lst;
|
||||
|
||||
for (i = 0; i < indent; i++)
|
||||
appendStringInfo(str, " ");
|
||||
appendStringInfo(str, " InitPlan\n");
|
||||
foreach (lst, plan->initPlan)
|
||||
foreach(lst, plan->initPlan)
|
||||
{
|
||||
es->rtable = ((SubPlan*) lfirst(lst))->rtable;
|
||||
es->rtable = ((SubPlan *) lfirst(lst))->rtable;
|
||||
for (i = 0; i < indent; i++)
|
||||
appendStringInfo(str, " ");
|
||||
appendStringInfo(str, " -> ");
|
||||
explain_outNode(str, ((SubPlan*) lfirst(lst))->plan, indent + 4, es);
|
||||
explain_outNode(str, ((SubPlan *) lfirst(lst))->plan, indent + 4, es);
|
||||
}
|
||||
es->rtable = saved_rtable;
|
||||
}
|
||||
|
@ -242,23 +242,23 @@ explain_outNode(StringInfo str, Plan *plan, int indent, ExplainState *es)
|
|||
appendStringInfo(str, " -> ");
|
||||
explain_outNode(str, innerPlan(plan), indent + 3, es);
|
||||
}
|
||||
|
||||
|
||||
/* subPlan-s */
|
||||
if (plan->subPlan)
|
||||
{
|
||||
List *saved_rtable = es->rtable;
|
||||
List *lst;
|
||||
|
||||
List *saved_rtable = es->rtable;
|
||||
List *lst;
|
||||
|
||||
for (i = 0; i < indent; i++)
|
||||
appendStringInfo(str, " ");
|
||||
appendStringInfo(str, " SubPlan\n");
|
||||
foreach (lst, plan->subPlan)
|
||||
foreach(lst, plan->subPlan)
|
||||
{
|
||||
es->rtable = ((SubPlan*) lfirst(lst))->rtable;
|
||||
es->rtable = ((SubPlan *) lfirst(lst))->rtable;
|
||||
for (i = 0; i < indent; i++)
|
||||
appendStringInfo(str, " ");
|
||||
appendStringInfo(str, " -> ");
|
||||
explain_outNode(str, ((SubPlan*) lfirst(lst))->plan, indent + 4, es);
|
||||
explain_outNode(str, ((SubPlan *) lfirst(lst))->plan, indent + 4, es);
|
||||
}
|
||||
es->rtable = saved_rtable;
|
||||
}
|
||||
|
|
|
@ -43,7 +43,7 @@ case_translate_language_name(const char *input, char *output)
|
|||
* ---------------------------------------------------------------------
|
||||
*/
|
||||
void
|
||||
CreateProceduralLanguage(CreatePLangStmt * stmt)
|
||||
CreateProceduralLanguage(CreatePLangStmt *stmt)
|
||||
{
|
||||
char languageName[NAMEDATALEN];
|
||||
HeapTuple langTup;
|
||||
|
@ -139,7 +139,7 @@ CreateProceduralLanguage(CreatePLangStmt * stmt)
|
|||
* ---------------------------------------------------------------------
|
||||
*/
|
||||
void
|
||||
DropProceduralLanguage(DropPLangStmt * stmt)
|
||||
DropProceduralLanguage(DropPLangStmt *stmt)
|
||||
{
|
||||
char languageName[NAMEDATALEN];
|
||||
HeapTuple langTup;
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
*
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $Header: /cvsroot/pgsql/src/backend/commands/Attic/recipe.c,v 1.19 1998/02/10 04:00:24 momjian Exp $
|
||||
* $Header: /cvsroot/pgsql/src/backend/commands/Attic/recipe.c,v 1.20 1998/02/26 04:30:59 momjian Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
|
@ -493,9 +493,9 @@ tg_replaceNumberedParam(Node *expression,
|
|||
{
|
||||
newVar = makeVar(rt_ind,
|
||||
0, /* the whole tuple */
|
||||
TypeGet(teeRelName, &defined),
|
||||
TypeGet(teeRelName, &defined),
|
||||
-1,
|
||||
0,
|
||||
0,
|
||||
rt_ind,
|
||||
0);
|
||||
return (Node *) newVar;
|
||||
|
@ -504,9 +504,9 @@ tg_replaceNumberedParam(Node *expression,
|
|||
newVar = makeVar(rt_ind,
|
||||
1, /* just the first field,
|
||||
* which is 'result' */
|
||||
TypeGet(teeRelName, &defined),
|
||||
TypeGet(teeRelName, &defined),
|
||||
-1,
|
||||
0,
|
||||
0,
|
||||
rt_ind,
|
||||
0);
|
||||
return (Node *) newVar;
|
||||
|
@ -1052,7 +1052,7 @@ tg_parseSubQuery(TgRecipe * r, TgNode * n, TeeInfo * teeInfo)
|
|||
tupdesc = rel->rd_att;
|
||||
|
||||
relid = heap_create_with_catalog(
|
||||
child->nodeElem->outTypes->val[0], tupdesc);
|
||||
child->nodeElem->outTypes->val[0], tupdesc);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -1077,7 +1077,7 @@ tg_parseSubQuery(TgRecipe * r, TgNode * n, TeeInfo * teeInfo)
|
|||
else
|
||||
{
|
||||
relid = heap_create_with_catalog(
|
||||
child->nodeElem->outTypes->val[0], tupdesc);
|
||||
child->nodeElem->outTypes->val[0], tupdesc);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -38,7 +38,7 @@ TriggerData *CurrentTriggerData = NULL;
|
|||
void RelationBuildTriggers(Relation relation);
|
||||
void FreeTriggerDesc(Relation relation);
|
||||
|
||||
static void DescribeTrigger(TriggerDesc * trigdesc, Trigger * trigger);
|
||||
static void DescribeTrigger(TriggerDesc *trigdesc, Trigger *trigger);
|
||||
static HeapTuple
|
||||
GetTupleForTrigger(Relation relation, ItemPointer tid,
|
||||
bool before);
|
||||
|
@ -46,7 +46,7 @@ GetTupleForTrigger(Relation relation, ItemPointer tid,
|
|||
extern GlobalMemory CacheCxt;
|
||||
|
||||
void
|
||||
CreateTrigger(CreateTrigStmt * stmt)
|
||||
CreateTrigger(CreateTrigStmt *stmt)
|
||||
{
|
||||
int16 tgtype;
|
||||
int16 tgattr[8] = {0};
|
||||
|
@ -249,7 +249,7 @@ CreateTrigger(CreateTrigStmt * stmt)
|
|||
}
|
||||
|
||||
void
|
||||
DropTrigger(DropTrigStmt * stmt)
|
||||
DropTrigger(DropTrigStmt *stmt)
|
||||
{
|
||||
Relation rel;
|
||||
Relation tgrel;
|
||||
|
@ -519,7 +519,7 @@ FreeTriggerDesc(Relation relation)
|
|||
}
|
||||
|
||||
static void
|
||||
DescribeTrigger(TriggerDesc * trigdesc, Trigger * trigger)
|
||||
DescribeTrigger(TriggerDesc *trigdesc, Trigger *trigger)
|
||||
{
|
||||
uint16 *n;
|
||||
Trigger ***t,
|
||||
|
@ -593,7 +593,7 @@ DescribeTrigger(TriggerDesc * trigdesc, Trigger * trigger)
|
|||
}
|
||||
|
||||
static HeapTuple
|
||||
ExecCallTriggerFunc(Trigger * trigger)
|
||||
ExecCallTriggerFunc(Trigger *trigger)
|
||||
{
|
||||
|
||||
if (trigger->tgfunc.fn_addr == NULL)
|
||||
|
@ -601,9 +601,10 @@ ExecCallTriggerFunc(Trigger * trigger)
|
|||
fmgr_info(trigger->tgfoid, &trigger->tgfunc);
|
||||
}
|
||||
|
||||
if (trigger->tgfunc.fn_plhandler != NULL) {
|
||||
if (trigger->tgfunc.fn_plhandler != NULL)
|
||||
{
|
||||
return (HeapTuple) (*(trigger->tgfunc.fn_plhandler))
|
||||
(&trigger->tgfunc);
|
||||
(&trigger->tgfunc);
|
||||
}
|
||||
|
||||
return (HeapTuple) ((*fmgr_faddr(&trigger->tgfunc)) ());
|
||||
|
|
|
@ -43,34 +43,39 @@ static void CheckPgUserAclNotNull(void);
|
|||
*---------------------------------------------------------------------
|
||||
*/
|
||||
static
|
||||
void UpdatePgPwdFile(char* sql) {
|
||||
void
|
||||
UpdatePgPwdFile(char *sql)
|
||||
{
|
||||
|
||||
char* filename;
|
||||
char* tempname;
|
||||
char *filename;
|
||||
char *tempname;
|
||||
|
||||
/* Create a temporary filename to be renamed later. This prevents the
|
||||
* backend from clobbering the pg_pwd file while the postmaster might be
|
||||
* reading from it.
|
||||
*/
|
||||
filename = crypt_getpwdfilename();
|
||||
tempname = (char*)malloc(strlen(filename) + 12);
|
||||
sprintf(tempname, "%s.%d", filename, MyProcPid);
|
||||
/*
|
||||
* Create a temporary filename to be renamed later. This prevents the
|
||||
* backend from clobbering the pg_pwd file while the postmaster might
|
||||
* be reading from it.
|
||||
*/
|
||||
filename = crypt_getpwdfilename();
|
||||
tempname = (char *) malloc(strlen(filename) + 12);
|
||||
sprintf(tempname, "%s.%d", filename, MyProcPid);
|
||||
|
||||
/* Copy the contents of pg_shadow to the pg_pwd ASCII file using a the SEPCHAR
|
||||
* character as the delimiter between fields. Then rename the file to its
|
||||
* final name.
|
||||
*/
|
||||
sprintf(sql, "copy %s to '%s' using delimiters %s", ShadowRelationName, tempname, CRYPT_PWD_FILE_SEPCHAR);
|
||||
pg_exec_query(sql, (char**)NULL, (Oid*)NULL, 0);
|
||||
rename(tempname, filename);
|
||||
free((void*)tempname);
|
||||
/*
|
||||
* Copy the contents of pg_shadow to the pg_pwd ASCII file using a the
|
||||
* SEPCHAR character as the delimiter between fields. Then rename the
|
||||
* file to its final name.
|
||||
*/
|
||||
sprintf(sql, "copy %s to '%s' using delimiters %s", ShadowRelationName, tempname, CRYPT_PWD_FILE_SEPCHAR);
|
||||
pg_exec_query(sql, (char **) NULL, (Oid *) NULL, 0);
|
||||
rename(tempname, filename);
|
||||
free((void *) tempname);
|
||||
|
||||
/* Create a flag file the postmaster will detect the next time it tries to
|
||||
* authenticate a user. The postmaster will know to reload the pg_pwd file
|
||||
* contents.
|
||||
*/
|
||||
filename = crypt_getpwdreloadfilename();
|
||||
creat(filename, S_IRUSR | S_IWUSR);
|
||||
/*
|
||||
* Create a flag file the postmaster will detect the next time it
|
||||
* tries to authenticate a user. The postmaster will know to reload
|
||||
* the pg_pwd file contents.
|
||||
*/
|
||||
filename = crypt_getpwdreloadfilename();
|
||||
creat(filename, S_IRUSR | S_IWUSR);
|
||||
}
|
||||
|
||||
/*---------------------------------------------------------------------
|
||||
|
@ -80,352 +85,407 @@ void UpdatePgPwdFile(char* sql) {
|
|||
* user is specified in the desired groups of defined in pg_group.
|
||||
*---------------------------------------------------------------------
|
||||
*/
|
||||
void DefineUser(CreateUserStmt *stmt) {
|
||||
void
|
||||
DefineUser(CreateUserStmt *stmt)
|
||||
{
|
||||
|
||||
char* pg_user;
|
||||
Relation pg_shadow_rel;
|
||||
TupleDesc pg_shadow_dsc;
|
||||
HeapScanDesc scan;
|
||||
HeapTuple tuple;
|
||||
Datum datum;
|
||||
Buffer buffer;
|
||||
char sql[512];
|
||||
char* sql_end;
|
||||
bool exists = false,
|
||||
n,
|
||||
inblock;
|
||||
int max_id = -1;
|
||||
char *pg_user;
|
||||
Relation pg_shadow_rel;
|
||||
TupleDesc pg_shadow_dsc;
|
||||
HeapScanDesc scan;
|
||||
HeapTuple tuple;
|
||||
Datum datum;
|
||||
Buffer buffer;
|
||||
char sql[512];
|
||||
char *sql_end;
|
||||
bool exists = false,
|
||||
n,
|
||||
inblock;
|
||||
int max_id = -1;
|
||||
|
||||
if (stmt->password)
|
||||
CheckPgUserAclNotNull();
|
||||
if (!(inblock = IsTransactionBlock()))
|
||||
BeginTransactionBlock();
|
||||
if (stmt->password)
|
||||
CheckPgUserAclNotNull();
|
||||
if (!(inblock = IsTransactionBlock()))
|
||||
BeginTransactionBlock();
|
||||
|
||||
/* Make sure the user attempting to create a user can insert into the pg_shadow
|
||||
* relation.
|
||||
*/
|
||||
pg_user = GetPgUserName();
|
||||
if (pg_aclcheck(ShadowRelationName, pg_user, ACL_RD | ACL_WR | ACL_AP) != ACLCHECK_OK) {
|
||||
UserAbortTransactionBlock();
|
||||
elog(ERROR, "defineUser: user \"%s\" does not have SELECT and INSERT privilege for \"%s\"",
|
||||
pg_user, ShadowRelationName);
|
||||
return;
|
||||
}
|
||||
/*
|
||||
* Make sure the user attempting to create a user can insert into the
|
||||
* pg_shadow relation.
|
||||
*/
|
||||
pg_user = GetPgUserName();
|
||||
if (pg_aclcheck(ShadowRelationName, pg_user, ACL_RD | ACL_WR | ACL_AP) != ACLCHECK_OK)
|
||||
{
|
||||
UserAbortTransactionBlock();
|
||||
elog(ERROR, "defineUser: user \"%s\" does not have SELECT and INSERT privilege for \"%s\"",
|
||||
pg_user, ShadowRelationName);
|
||||
return;
|
||||
}
|
||||
|
||||
/* Scan the pg_shadow relation to be certain the user doesn't already exist.
|
||||
*/
|
||||
pg_shadow_rel = heap_openr(ShadowRelationName);
|
||||
pg_shadow_dsc = RelationGetTupleDescriptor(pg_shadow_rel);
|
||||
/* Secure a write lock on pg_shadow so we can be sure of what the next usesysid
|
||||
* should be.
|
||||
*/
|
||||
RelationSetLockForWrite(pg_shadow_rel);
|
||||
/*
|
||||
* Scan the pg_shadow relation to be certain the user doesn't already
|
||||
* exist.
|
||||
*/
|
||||
pg_shadow_rel = heap_openr(ShadowRelationName);
|
||||
pg_shadow_dsc = RelationGetTupleDescriptor(pg_shadow_rel);
|
||||
|
||||
scan = heap_beginscan(pg_shadow_rel, false, false, 0, NULL);
|
||||
while (HeapTupleIsValid(tuple = heap_getnext(scan, 0, &buffer))) {
|
||||
datum = heap_getattr(tuple, Anum_pg_shadow_usename, pg_shadow_dsc, &n);
|
||||
/*
|
||||
* Secure a write lock on pg_shadow so we can be sure of what the next
|
||||
* usesysid should be.
|
||||
*/
|
||||
RelationSetLockForWrite(pg_shadow_rel);
|
||||
|
||||
if (!exists && !strncmp((char*)datum, stmt->user, strlen(stmt->user)))
|
||||
exists = true;
|
||||
scan = heap_beginscan(pg_shadow_rel, false, false, 0, NULL);
|
||||
while (HeapTupleIsValid(tuple = heap_getnext(scan, 0, &buffer)))
|
||||
{
|
||||
datum = heap_getattr(tuple, Anum_pg_shadow_usename, pg_shadow_dsc, &n);
|
||||
|
||||
datum = heap_getattr(tuple, Anum_pg_shadow_usesysid, pg_shadow_dsc, &n);
|
||||
if ((int)datum > max_id)
|
||||
max_id = (int)datum;
|
||||
if (!exists && !strncmp((char *) datum, stmt->user, strlen(stmt->user)))
|
||||
exists = true;
|
||||
|
||||
ReleaseBuffer(buffer);
|
||||
}
|
||||
heap_endscan(scan);
|
||||
datum = heap_getattr(tuple, Anum_pg_shadow_usesysid, pg_shadow_dsc, &n);
|
||||
if ((int) datum > max_id)
|
||||
max_id = (int) datum;
|
||||
|
||||
if (exists) {
|
||||
RelationUnsetLockForWrite(pg_shadow_rel);
|
||||
heap_close(pg_shadow_rel);
|
||||
UserAbortTransactionBlock();
|
||||
elog(ERROR, "defineUser: user \"%s\" has already been created", stmt->user);
|
||||
return;
|
||||
}
|
||||
ReleaseBuffer(buffer);
|
||||
}
|
||||
heap_endscan(scan);
|
||||
|
||||
/* Build the insert statment to be executed.
|
||||
*/
|
||||
sprintf(sql, "insert into %s(usename,usesysid,usecreatedb,usetrace,usesuper,usecatupd,passwd", ShadowRelationName);
|
||||
/* if (stmt->password)
|
||||
strcat(sql, ",passwd"); -- removed so that insert empty string when no password */
|
||||
if (stmt->validUntil)
|
||||
strcat(sql, ",valuntil");
|
||||
if (exists)
|
||||
{
|
||||
RelationUnsetLockForWrite(pg_shadow_rel);
|
||||
heap_close(pg_shadow_rel);
|
||||
UserAbortTransactionBlock();
|
||||
elog(ERROR, "defineUser: user \"%s\" has already been created", stmt->user);
|
||||
return;
|
||||
}
|
||||
|
||||
sql_end = sql + strlen(sql);
|
||||
sprintf(sql_end, ") values('%s',%d", stmt->user, max_id + 1);
|
||||
if (stmt->createdb && *stmt->createdb)
|
||||
strcat(sql_end, ",'t','t'");
|
||||
else
|
||||
strcat(sql_end, ",'f','t'");
|
||||
if (stmt->createuser && *stmt->createuser)
|
||||
strcat(sql_end, ",'t','t'");
|
||||
else
|
||||
strcat(sql_end, ",'f','t'");
|
||||
sql_end += strlen(sql_end);
|
||||
if (stmt->password) {
|
||||
sprintf(sql_end, ",'%s'", stmt->password);
|
||||
sql_end += strlen(sql_end);
|
||||
} else {
|
||||
strcpy(sql_end, ",''");
|
||||
sql_end += strlen(sql_end);
|
||||
}
|
||||
if (stmt->validUntil) {
|
||||
sprintf(sql_end, ",'%s'", stmt->validUntil);
|
||||
sql_end += strlen(sql_end);
|
||||
}
|
||||
strcat(sql_end, ")");
|
||||
/*
|
||||
* Build the insert statment to be executed.
|
||||
*/
|
||||
sprintf(sql, "insert into %s(usename,usesysid,usecreatedb,usetrace,usesuper,usecatupd,passwd", ShadowRelationName);
|
||||
/* if (stmt->password)
|
||||
strcat(sql, ",passwd"); -- removed so that insert empty string when no password */
|
||||
if (stmt->validUntil)
|
||||
strcat(sql, ",valuntil");
|
||||
|
||||
pg_exec_query(sql, (char**)NULL, (Oid*)NULL, 0);
|
||||
sql_end = sql + strlen(sql);
|
||||
sprintf(sql_end, ") values('%s',%d", stmt->user, max_id + 1);
|
||||
if (stmt->createdb && *stmt->createdb)
|
||||
strcat(sql_end, ",'t','t'");
|
||||
else
|
||||
strcat(sql_end, ",'f','t'");
|
||||
if (stmt->createuser && *stmt->createuser)
|
||||
strcat(sql_end, ",'t','t'");
|
||||
else
|
||||
strcat(sql_end, ",'f','t'");
|
||||
sql_end += strlen(sql_end);
|
||||
if (stmt->password)
|
||||
{
|
||||
sprintf(sql_end, ",'%s'", stmt->password);
|
||||
sql_end += strlen(sql_end);
|
||||
}
|
||||
else
|
||||
{
|
||||
strcpy(sql_end, ",''");
|
||||
sql_end += strlen(sql_end);
|
||||
}
|
||||
if (stmt->validUntil)
|
||||
{
|
||||
sprintf(sql_end, ",'%s'", stmt->validUntil);
|
||||
sql_end += strlen(sql_end);
|
||||
}
|
||||
strcat(sql_end, ")");
|
||||
|
||||
/* Add the stuff here for groups.
|
||||
*/
|
||||
pg_exec_query(sql, (char **) NULL, (Oid *) NULL, 0);
|
||||
|
||||
UpdatePgPwdFile(sql);
|
||||
/*
|
||||
* Add the stuff here for groups.
|
||||
*/
|
||||
|
||||
/* This goes after the UpdatePgPwdFile to be certain that two backends to not
|
||||
* attempt to write to the pg_pwd file at the same time.
|
||||
*/
|
||||
RelationUnsetLockForWrite(pg_shadow_rel);
|
||||
heap_close(pg_shadow_rel);
|
||||
UpdatePgPwdFile(sql);
|
||||
|
||||
if (IsTransactionBlock() && !inblock)
|
||||
EndTransactionBlock();
|
||||
/*
|
||||
* This goes after the UpdatePgPwdFile to be certain that two backends
|
||||
* to not attempt to write to the pg_pwd file at the same time.
|
||||
*/
|
||||
RelationUnsetLockForWrite(pg_shadow_rel);
|
||||
heap_close(pg_shadow_rel);
|
||||
|
||||
if (IsTransactionBlock() && !inblock)
|
||||
EndTransactionBlock();
|
||||
}
|
||||
|
||||
|
||||
extern void AlterUser(AlterUserStmt *stmt) {
|
||||
extern void
|
||||
AlterUser(AlterUserStmt *stmt)
|
||||
{
|
||||
|
||||
char* pg_user;
|
||||
Relation pg_shadow_rel;
|
||||
TupleDesc pg_shadow_dsc;
|
||||
HeapScanDesc scan;
|
||||
HeapTuple tuple;
|
||||
Datum datum;
|
||||
Buffer buffer;
|
||||
char sql[512];
|
||||
char* sql_end;
|
||||
bool exists = false,
|
||||
n,
|
||||
inblock;
|
||||
char *pg_user;
|
||||
Relation pg_shadow_rel;
|
||||
TupleDesc pg_shadow_dsc;
|
||||
HeapScanDesc scan;
|
||||
HeapTuple tuple;
|
||||
Datum datum;
|
||||
Buffer buffer;
|
||||
char sql[512];
|
||||
char *sql_end;
|
||||
bool exists = false,
|
||||
n,
|
||||
inblock;
|
||||
|
||||
if (stmt->password)
|
||||
CheckPgUserAclNotNull();
|
||||
if (!(inblock = IsTransactionBlock()))
|
||||
BeginTransactionBlock();
|
||||
if (stmt->password)
|
||||
CheckPgUserAclNotNull();
|
||||
if (!(inblock = IsTransactionBlock()))
|
||||
BeginTransactionBlock();
|
||||
|
||||
/* Make sure the user attempting to create a user can insert into the pg_shadow
|
||||
* relation.
|
||||
*/
|
||||
pg_user = GetPgUserName();
|
||||
if (pg_aclcheck(ShadowRelationName, pg_user, ACL_RD | ACL_WR) != ACLCHECK_OK) {
|
||||
UserAbortTransactionBlock();
|
||||
elog(ERROR, "alterUser: user \"%s\" does not have SELECT and UPDATE privilege for \"%s\"",
|
||||
pg_user, ShadowRelationName);
|
||||
return;
|
||||
}
|
||||
/*
|
||||
* Make sure the user attempting to create a user can insert into the
|
||||
* pg_shadow relation.
|
||||
*/
|
||||
pg_user = GetPgUserName();
|
||||
if (pg_aclcheck(ShadowRelationName, pg_user, ACL_RD | ACL_WR) != ACLCHECK_OK)
|
||||
{
|
||||
UserAbortTransactionBlock();
|
||||
elog(ERROR, "alterUser: user \"%s\" does not have SELECT and UPDATE privilege for \"%s\"",
|
||||
pg_user, ShadowRelationName);
|
||||
return;
|
||||
}
|
||||
|
||||
/* Scan the pg_shadow relation to be certain the user exists.
|
||||
*/
|
||||
pg_shadow_rel = heap_openr(ShadowRelationName);
|
||||
pg_shadow_dsc = RelationGetTupleDescriptor(pg_shadow_rel);
|
||||
/* Secure a write lock on pg_shadow so we can be sure that when the dump of
|
||||
* the pg_pwd file is done, there is not another backend doing the same.
|
||||
*/
|
||||
RelationSetLockForWrite(pg_shadow_rel);
|
||||
/*
|
||||
* Scan the pg_shadow relation to be certain the user exists.
|
||||
*/
|
||||
pg_shadow_rel = heap_openr(ShadowRelationName);
|
||||
pg_shadow_dsc = RelationGetTupleDescriptor(pg_shadow_rel);
|
||||
|
||||
scan = heap_beginscan(pg_shadow_rel, false, false, 0, NULL);
|
||||
while (HeapTupleIsValid(tuple = heap_getnext(scan, 0, &buffer))) {
|
||||
datum = heap_getattr(tuple, Anum_pg_shadow_usename, pg_shadow_dsc, &n);
|
||||
/*
|
||||
* Secure a write lock on pg_shadow so we can be sure that when the
|
||||
* dump of the pg_pwd file is done, there is not another backend doing
|
||||
* the same.
|
||||
*/
|
||||
RelationSetLockForWrite(pg_shadow_rel);
|
||||
|
||||
if (!strncmp((char*)datum, stmt->user, strlen(stmt->user))) {
|
||||
exists = true;
|
||||
ReleaseBuffer(buffer);
|
||||
break;
|
||||
}
|
||||
}
|
||||
heap_endscan(scan);
|
||||
scan = heap_beginscan(pg_shadow_rel, false, false, 0, NULL);
|
||||
while (HeapTupleIsValid(tuple = heap_getnext(scan, 0, &buffer)))
|
||||
{
|
||||
datum = heap_getattr(tuple, Anum_pg_shadow_usename, pg_shadow_dsc, &n);
|
||||
|
||||
if (!exists) {
|
||||
RelationUnsetLockForWrite(pg_shadow_rel);
|
||||
heap_close(pg_shadow_rel);
|
||||
UserAbortTransactionBlock();
|
||||
elog(ERROR, "alterUser: user \"%s\" does not exist", stmt->user);
|
||||
return;
|
||||
}
|
||||
if (!strncmp((char *) datum, stmt->user, strlen(stmt->user)))
|
||||
{
|
||||
exists = true;
|
||||
ReleaseBuffer(buffer);
|
||||
break;
|
||||
}
|
||||
}
|
||||
heap_endscan(scan);
|
||||
|
||||
/* Create the update statement to modify the user.
|
||||
*/
|
||||
sprintf(sql, "update %s set", ShadowRelationName);
|
||||
sql_end = sql;
|
||||
if (stmt->password) {
|
||||
sql_end += strlen(sql_end);
|
||||
sprintf(sql_end, " passwd = '%s'", stmt->password);
|
||||
}
|
||||
if (stmt->createdb) {
|
||||
if (sql_end != sql)
|
||||
strcat(sql_end, ",");
|
||||
sql_end += strlen(sql_end);
|
||||
if (*stmt->createdb)
|
||||
strcat(sql_end, " usecreatedb = 't'");
|
||||
else
|
||||
strcat(sql_end, " usecreatedb = 'f'");
|
||||
}
|
||||
if (stmt->createuser) {
|
||||
if (sql_end != sql)
|
||||
strcat(sql_end, ",");
|
||||
sql_end += strlen(sql_end);
|
||||
if (*stmt->createuser)
|
||||
strcat(sql_end, " usesuper = 't'");
|
||||
else
|
||||
strcat(sql_end, " usesuper = 'f'");
|
||||
}
|
||||
if (stmt->validUntil) {
|
||||
if (sql_end != sql)
|
||||
strcat(sql_end, ",");
|
||||
sql_end += strlen(sql_end);
|
||||
sprintf(sql_end, " valuntil = '%s'", stmt->validUntil);
|
||||
}
|
||||
if (sql_end != sql) {
|
||||
sql_end += strlen(sql_end);
|
||||
sprintf(sql_end, " where usename = '%s'", stmt->user);
|
||||
pg_exec_query(sql, (char**)NULL, (Oid*)NULL, 0);
|
||||
}
|
||||
if (!exists)
|
||||
{
|
||||
RelationUnsetLockForWrite(pg_shadow_rel);
|
||||
heap_close(pg_shadow_rel);
|
||||
UserAbortTransactionBlock();
|
||||
elog(ERROR, "alterUser: user \"%s\" does not exist", stmt->user);
|
||||
return;
|
||||
}
|
||||
|
||||
/* do the pg_group stuff here */
|
||||
/*
|
||||
* Create the update statement to modify the user.
|
||||
*/
|
||||
sprintf(sql, "update %s set", ShadowRelationName);
|
||||
sql_end = sql;
|
||||
if (stmt->password)
|
||||
{
|
||||
sql_end += strlen(sql_end);
|
||||
sprintf(sql_end, " passwd = '%s'", stmt->password);
|
||||
}
|
||||
if (stmt->createdb)
|
||||
{
|
||||
if (sql_end != sql)
|
||||
strcat(sql_end, ",");
|
||||
sql_end += strlen(sql_end);
|
||||
if (*stmt->createdb)
|
||||
strcat(sql_end, " usecreatedb = 't'");
|
||||
else
|
||||
strcat(sql_end, " usecreatedb = 'f'");
|
||||
}
|
||||
if (stmt->createuser)
|
||||
{
|
||||
if (sql_end != sql)
|
||||
strcat(sql_end, ",");
|
||||
sql_end += strlen(sql_end);
|
||||
if (*stmt->createuser)
|
||||
strcat(sql_end, " usesuper = 't'");
|
||||
else
|
||||
strcat(sql_end, " usesuper = 'f'");
|
||||
}
|
||||
if (stmt->validUntil)
|
||||
{
|
||||
if (sql_end != sql)
|
||||
strcat(sql_end, ",");
|
||||
sql_end += strlen(sql_end);
|
||||
sprintf(sql_end, " valuntil = '%s'", stmt->validUntil);
|
||||
}
|
||||
if (sql_end != sql)
|
||||
{
|
||||
sql_end += strlen(sql_end);
|
||||
sprintf(sql_end, " where usename = '%s'", stmt->user);
|
||||
pg_exec_query(sql, (char **) NULL, (Oid *) NULL, 0);
|
||||
}
|
||||
|
||||
UpdatePgPwdFile(sql);
|
||||
/* do the pg_group stuff here */
|
||||
|
||||
RelationUnsetLockForWrite(pg_shadow_rel);
|
||||
heap_close(pg_shadow_rel);
|
||||
UpdatePgPwdFile(sql);
|
||||
|
||||
if (IsTransactionBlock() && !inblock)
|
||||
EndTransactionBlock();
|
||||
RelationUnsetLockForWrite(pg_shadow_rel);
|
||||
heap_close(pg_shadow_rel);
|
||||
|
||||
if (IsTransactionBlock() && !inblock)
|
||||
EndTransactionBlock();
|
||||
}
|
||||
|
||||
|
||||
extern void RemoveUser(char* user) {
|
||||
extern void
|
||||
RemoveUser(char *user)
|
||||
{
|
||||
|
||||
char* pg_user;
|
||||
Relation pg_shadow_rel,
|
||||
pg_rel;
|
||||
TupleDesc pg_dsc;
|
||||
HeapScanDesc scan;
|
||||
HeapTuple tuple;
|
||||
Datum datum;
|
||||
Buffer buffer;
|
||||
char sql[512];
|
||||
bool n,
|
||||
inblock;
|
||||
int usesysid = -1,
|
||||
ndbase = 0;
|
||||
char** dbase = NULL;
|
||||
char *pg_user;
|
||||
Relation pg_shadow_rel,
|
||||
pg_rel;
|
||||
TupleDesc pg_dsc;
|
||||
HeapScanDesc scan;
|
||||
HeapTuple tuple;
|
||||
Datum datum;
|
||||
Buffer buffer;
|
||||
char sql[512];
|
||||
bool n,
|
||||
inblock;
|
||||
int usesysid = -1,
|
||||
ndbase = 0;
|
||||
char **dbase = NULL;
|
||||
|
||||
if (!(inblock = IsTransactionBlock()))
|
||||
BeginTransactionBlock();
|
||||
if (!(inblock = IsTransactionBlock()))
|
||||
BeginTransactionBlock();
|
||||
|
||||
/* Make sure the user attempting to create a user can delete from the pg_shadow
|
||||
* relation.
|
||||
*/
|
||||
pg_user = GetPgUserName();
|
||||
if (pg_aclcheck(ShadowRelationName, pg_user, ACL_RD | ACL_WR) != ACLCHECK_OK) {
|
||||
UserAbortTransactionBlock();
|
||||
elog(ERROR, "removeUser: user \"%s\" does not have SELECT and DELETE privilege for \"%s\"",
|
||||
pg_user, ShadowRelationName);
|
||||
return;
|
||||
}
|
||||
/*
|
||||
* Make sure the user attempting to create a user can delete from the
|
||||
* pg_shadow relation.
|
||||
*/
|
||||
pg_user = GetPgUserName();
|
||||
if (pg_aclcheck(ShadowRelationName, pg_user, ACL_RD | ACL_WR) != ACLCHECK_OK)
|
||||
{
|
||||
UserAbortTransactionBlock();
|
||||
elog(ERROR, "removeUser: user \"%s\" does not have SELECT and DELETE privilege for \"%s\"",
|
||||
pg_user, ShadowRelationName);
|
||||
return;
|
||||
}
|
||||
|
||||
/* Perform a scan of the pg_shadow relation to find the usesysid of the user to
|
||||
* be deleted. If it is not found, then return a warning message.
|
||||
*/
|
||||
pg_shadow_rel = heap_openr(ShadowRelationName);
|
||||
pg_dsc = RelationGetTupleDescriptor(pg_shadow_rel);
|
||||
/* Secure a write lock on pg_shadow so we can be sure that when the dump of
|
||||
* the pg_pwd file is done, there is not another backend doing the same.
|
||||
*/
|
||||
RelationSetLockForWrite(pg_shadow_rel);
|
||||
/*
|
||||
* Perform a scan of the pg_shadow relation to find the usesysid of
|
||||
* the user to be deleted. If it is not found, then return a warning
|
||||
* message.
|
||||
*/
|
||||
pg_shadow_rel = heap_openr(ShadowRelationName);
|
||||
pg_dsc = RelationGetTupleDescriptor(pg_shadow_rel);
|
||||
|
||||
scan = heap_beginscan(pg_shadow_rel, false, false, 0, NULL);
|
||||
while (HeapTupleIsValid(tuple = heap_getnext(scan, 0, &buffer))) {
|
||||
datum = heap_getattr(tuple, Anum_pg_shadow_usename, pg_dsc, &n);
|
||||
/*
|
||||
* Secure a write lock on pg_shadow so we can be sure that when the
|
||||
* dump of the pg_pwd file is done, there is not another backend doing
|
||||
* the same.
|
||||
*/
|
||||
RelationSetLockForWrite(pg_shadow_rel);
|
||||
|
||||
if (!strncmp((char*)datum, user, strlen(user))) {
|
||||
usesysid = (int)heap_getattr(tuple, Anum_pg_shadow_usesysid, pg_dsc, &n);
|
||||
ReleaseBuffer(buffer);
|
||||
break;
|
||||
}
|
||||
ReleaseBuffer(buffer);
|
||||
}
|
||||
heap_endscan(scan);
|
||||
scan = heap_beginscan(pg_shadow_rel, false, false, 0, NULL);
|
||||
while (HeapTupleIsValid(tuple = heap_getnext(scan, 0, &buffer)))
|
||||
{
|
||||
datum = heap_getattr(tuple, Anum_pg_shadow_usename, pg_dsc, &n);
|
||||
|
||||
if (usesysid == -1) {
|
||||
RelationUnsetLockForWrite(pg_shadow_rel);
|
||||
heap_close(pg_shadow_rel);
|
||||
UserAbortTransactionBlock();
|
||||
elog(ERROR, "removeUser: user \"%s\" does not exist", user);
|
||||
return;
|
||||
}
|
||||
if (!strncmp((char *) datum, user, strlen(user)))
|
||||
{
|
||||
usesysid = (int) heap_getattr(tuple, Anum_pg_shadow_usesysid, pg_dsc, &n);
|
||||
ReleaseBuffer(buffer);
|
||||
break;
|
||||
}
|
||||
ReleaseBuffer(buffer);
|
||||
}
|
||||
heap_endscan(scan);
|
||||
|
||||
/* Perform a scan of the pg_database relation to find the databases owned by
|
||||
* usesysid. Then drop them.
|
||||
*/
|
||||
pg_rel = heap_openr(DatabaseRelationName);
|
||||
pg_dsc = RelationGetTupleDescriptor(pg_rel);
|
||||
if (usesysid == -1)
|
||||
{
|
||||
RelationUnsetLockForWrite(pg_shadow_rel);
|
||||
heap_close(pg_shadow_rel);
|
||||
UserAbortTransactionBlock();
|
||||
elog(ERROR, "removeUser: user \"%s\" does not exist", user);
|
||||
return;
|
||||
}
|
||||
|
||||
scan = heap_beginscan(pg_rel, false, false, 0, NULL);
|
||||
while (HeapTupleIsValid(tuple = heap_getnext(scan, 0, &buffer))) {
|
||||
datum = heap_getattr(tuple, Anum_pg_database_datdba, pg_dsc, &n);
|
||||
/*
|
||||
* Perform a scan of the pg_database relation to find the databases
|
||||
* owned by usesysid. Then drop them.
|
||||
*/
|
||||
pg_rel = heap_openr(DatabaseRelationName);
|
||||
pg_dsc = RelationGetTupleDescriptor(pg_rel);
|
||||
|
||||
if ((int)datum == usesysid) {
|
||||
datum = heap_getattr(tuple, Anum_pg_database_datname, pg_dsc, &n);
|
||||
if (memcmp((void*)datum, "template1", 9)) {
|
||||
dbase = (char**)realloc((void*)dbase, sizeof(char*) * (ndbase + 1));
|
||||
dbase[ndbase] = (char*)malloc(NAMEDATALEN + 1);
|
||||
memcpy((void*)dbase[ndbase], (void*)datum, NAMEDATALEN);
|
||||
dbase[ndbase++][NAMEDATALEN] = '\0';
|
||||
}
|
||||
}
|
||||
ReleaseBuffer(buffer);
|
||||
}
|
||||
heap_endscan(scan);
|
||||
heap_close(pg_rel);
|
||||
scan = heap_beginscan(pg_rel, false, false, 0, NULL);
|
||||
while (HeapTupleIsValid(tuple = heap_getnext(scan, 0, &buffer)))
|
||||
{
|
||||
datum = heap_getattr(tuple, Anum_pg_database_datdba, pg_dsc, &n);
|
||||
|
||||
while (ndbase--) {
|
||||
elog(NOTICE, "Dropping database %s", dbase[ndbase]);
|
||||
sprintf(sql, "drop database %s", dbase[ndbase]);
|
||||
free((void*)dbase[ndbase]);
|
||||
pg_exec_query(sql, (char**)NULL, (Oid*)NULL, 0);
|
||||
}
|
||||
if (dbase)
|
||||
free((void*)dbase);
|
||||
if ((int) datum == usesysid)
|
||||
{
|
||||
datum = heap_getattr(tuple, Anum_pg_database_datname, pg_dsc, &n);
|
||||
if (memcmp((void *) datum, "template1", 9))
|
||||
{
|
||||
dbase = (char **) realloc((void *) dbase, sizeof(char *) * (ndbase + 1));
|
||||
dbase[ndbase] = (char *) malloc(NAMEDATALEN + 1);
|
||||
memcpy((void *) dbase[ndbase], (void *) datum, NAMEDATALEN);
|
||||
dbase[ndbase++][NAMEDATALEN] = '\0';
|
||||
}
|
||||
}
|
||||
ReleaseBuffer(buffer);
|
||||
}
|
||||
heap_endscan(scan);
|
||||
heap_close(pg_rel);
|
||||
|
||||
/* Since pg_shadow is global over all databases, one of two things must be done
|
||||
* to insure complete consistency. First, pg_shadow could be made non-global.
|
||||
* This would elminate the code above for deleting database and would require
|
||||
* the addition of code to delete tables, views, etc owned by the user.
|
||||
*
|
||||
* The second option would be to create a means of deleting tables, view,
|
||||
* etc. owned by the user from other databases. Pg_user is global and so
|
||||
* this must be done at some point.
|
||||
*
|
||||
* Let us not forget that the user should be removed from the pg_groups also.
|
||||
*
|
||||
* Todd A. Brandys 11/18/1997
|
||||
*
|
||||
*/
|
||||
while (ndbase--)
|
||||
{
|
||||
elog(NOTICE, "Dropping database %s", dbase[ndbase]);
|
||||
sprintf(sql, "drop database %s", dbase[ndbase]);
|
||||
free((void *) dbase[ndbase]);
|
||||
pg_exec_query(sql, (char **) NULL, (Oid *) NULL, 0);
|
||||
}
|
||||
if (dbase)
|
||||
free((void *) dbase);
|
||||
|
||||
/* Remove the user from the pg_shadow table
|
||||
*/
|
||||
sprintf(sql, "delete from %s where usename = '%s'", ShadowRelationName, user);
|
||||
pg_exec_query(sql, (char**)NULL, (Oid*)NULL, 0);
|
||||
/*
|
||||
* Since pg_shadow is global over all databases, one of two things
|
||||
* must be done to insure complete consistency. First, pg_shadow
|
||||
* could be made non-global. This would elminate the code above for
|
||||
* deleting database and would require the addition of code to delete
|
||||
* tables, views, etc owned by the user.
|
||||
*
|
||||
* The second option would be to create a means of deleting tables, view,
|
||||
* etc. owned by the user from other databases. Pg_user is global and
|
||||
* so this must be done at some point.
|
||||
*
|
||||
* Let us not forget that the user should be removed from the pg_groups
|
||||
* also.
|
||||
*
|
||||
* Todd A. Brandys 11/18/1997
|
||||
*
|
||||
*/
|
||||
|
||||
UpdatePgPwdFile(sql);
|
||||
/*
|
||||
* Remove the user from the pg_shadow table
|
||||
*/
|
||||
sprintf(sql, "delete from %s where usename = '%s'", ShadowRelationName, user);
|
||||
pg_exec_query(sql, (char **) NULL, (Oid *) NULL, 0);
|
||||
|
||||
RelationUnsetLockForWrite(pg_shadow_rel);
|
||||
heap_close(pg_shadow_rel);
|
||||
UpdatePgPwdFile(sql);
|
||||
|
||||
if (IsTransactionBlock() && !inblock)
|
||||
EndTransactionBlock();
|
||||
RelationUnsetLockForWrite(pg_shadow_rel);
|
||||
heap_close(pg_shadow_rel);
|
||||
|
||||
if (IsTransactionBlock() && !inblock)
|
||||
EndTransactionBlock();
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -433,9 +493,10 @@ extern void RemoveUser(char* user) {
|
|||
*
|
||||
* check to see if there is an ACL on pg_shadow
|
||||
*/
|
||||
static void CheckPgUserAclNotNull()
|
||||
static void
|
||||
CheckPgUserAclNotNull()
|
||||
{
|
||||
HeapTuple htp;
|
||||
HeapTuple htp;
|
||||
|
||||
htp = SearchSysCacheTuple(RELNAME, PointerGetDatum(ShadowRelationName),
|
||||
0, 0, 0);
|
||||
|
@ -451,6 +512,6 @@ HeapTuple htp;
|
|||
elog(NOTICE, "so normal users can not read the passwords.");
|
||||
elog(ERROR, "Try 'REVOKE ALL ON pg_shadow FROM PUBLIC'");
|
||||
}
|
||||
|
||||
|
||||
return;
|
||||
}
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
*
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $Header: /cvsroot/pgsql/src/backend/commands/vacuum.c,v 1.62 1998/02/25 23:40:32 vadim Exp $
|
||||
* $Header: /cvsroot/pgsql/src/backend/commands/vacuum.c,v 1.63 1998/02/26 04:31:03 momjian Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
|
@ -54,9 +54,9 @@
|
|||
#include <sys/resource.h>
|
||||
#endif
|
||||
|
||||
/* #include <port-protos.h> */ /* Why? */
|
||||
/* #include <port-protos.h> *//* Why? */
|
||||
|
||||
extern int BlowawayRelationBuffers(Relation rdesc, BlockNumber block);
|
||||
extern int BlowawayRelationBuffers(Relation rdesc, BlockNumber block);
|
||||
|
||||
bool VacuumRunning = false;
|
||||
|
||||
|
@ -136,7 +136,7 @@ vacuum(char *vacrel, bool verbose, bool analyze, List *va_spec)
|
|||
old = MemoryContextSwitchTo((MemoryContext) pmem);
|
||||
|
||||
if (va_spec != NIL && !analyze)
|
||||
elog(ERROR,"Can't vacuum columns, only tables. You can 'vacuum analyze' columns.");
|
||||
elog(ERROR, "Can't vacuum columns, only tables. You can 'vacuum analyze' columns.");
|
||||
|
||||
foreach(le, va_spec)
|
||||
{
|
||||
|
@ -725,8 +725,9 @@ vc_scanheap(VRelStats *vacrelstats, Relation onerel,
|
|||
}
|
||||
else if (!TransactionIdIsInProgress(htup->t_xmin))
|
||||
{
|
||||
|
||||
/*
|
||||
* Not Aborted, Not Committed, Not in Progress -
|
||||
* Not Aborted, Not Committed, Not in Progress -
|
||||
* so it's from crashed process. - vadim 11/26/96
|
||||
*/
|
||||
ncrash++;
|
||||
|
@ -741,11 +742,11 @@ vc_scanheap(VRelStats *vacrelstats, Relation onerel,
|
|||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* here we are concerned about tuples with xmin committed
|
||||
* and xmax unknown or committed
|
||||
/*
|
||||
* here we are concerned about tuples with xmin committed and
|
||||
* xmax unknown or committed
|
||||
*/
|
||||
if (htup->t_infomask & HEAP_XMIN_COMMITTED &&
|
||||
if (htup->t_infomask & HEAP_XMIN_COMMITTED &&
|
||||
!(htup->t_infomask & HEAP_XMAX_INVALID))
|
||||
{
|
||||
if (htup->t_infomask & HEAP_XMAX_COMMITTED)
|
||||
|
@ -759,6 +760,7 @@ vc_scanheap(VRelStats *vacrelstats, Relation onerel,
|
|||
tupgone = true;
|
||||
else if (!TransactionIdIsInProgress(htup->t_xmax))
|
||||
{
|
||||
|
||||
/*
|
||||
* Not Aborted, Not Committed, Not in Progress - so it
|
||||
* from crashed process. - vadim 06/02/97
|
||||
|
@ -916,7 +918,7 @@ Tup %u: Vac %u, Crash %u, UnUsed %u, MinLen %u, MaxLen %u; Re-using: Free/Avail.
|
|||
ru1.ru_stime.tv_sec - ru0.ru_stime.tv_sec,
|
||||
ru1.ru_utime.tv_sec - ru0.ru_utime.tv_sec);
|
||||
|
||||
} /* vc_scanheap */
|
||||
} /* vc_scanheap */
|
||||
|
||||
|
||||
/*
|
||||
|
@ -1087,15 +1089,15 @@ vc_rpfheap(VRelStats *vacrelstats, Relation onerel,
|
|||
* But we can't remove last page - this is our
|
||||
* "show-stopper" !!! - vadim 02/25/98
|
||||
*/
|
||||
if (ToVpd != Fvplast &&
|
||||
if (ToVpd != Fvplast &&
|
||||
!vc_enough_space(ToVpd, vacrelstats->min_tlen))
|
||||
{
|
||||
Assert(Fnpages > ToVpI + 1);
|
||||
memmove(Fvpl->vpl_pgdesc + ToVpI,
|
||||
Fvpl->vpl_pgdesc + ToVpI + 1,
|
||||
sizeof(VPageDescr *) * (Fnpages - ToVpI - 1));
|
||||
sizeof(VPageDescr *) * (Fnpages - ToVpI - 1));
|
||||
Fnpages--;
|
||||
Assert (Fvplast == Fvpl->vpl_pgdesc[Fnpages - 1]);
|
||||
Assert(Fvplast == Fvpl->vpl_pgdesc[Fnpages - 1]);
|
||||
}
|
||||
}
|
||||
for (i = 0; i < Fnpages; i++)
|
||||
|
@ -1333,7 +1335,7 @@ Elapsed %u/%u sec.",
|
|||
{
|
||||
i = BlowawayRelationBuffers(onerel, blkno);
|
||||
if (i < 0)
|
||||
elog (FATAL, "VACUUM (vc_rpfheap): BlowawayRelationBuffers returned %d", i);
|
||||
elog(FATAL, "VACUUM (vc_rpfheap): BlowawayRelationBuffers returned %d", i);
|
||||
blkno = smgrtruncate(DEFAULT_SMGR, onerel, blkno);
|
||||
Assert(blkno >= 0);
|
||||
vacrelstats->npages = blkno; /* set new number of blocks */
|
||||
|
@ -1349,7 +1351,7 @@ Elapsed %u/%u sec.",
|
|||
|
||||
pfree(vpc);
|
||||
|
||||
} /* vc_rpfheap */
|
||||
} /* vc_rpfheap */
|
||||
|
||||
/*
|
||||
* vc_vacheap() -- free dead tuples
|
||||
|
@ -1367,7 +1369,7 @@ vc_vacheap(VRelStats *vacrelstats, Relation onerel, VPageList Vvpl)
|
|||
int i;
|
||||
|
||||
nblocks = Vvpl->vpl_npages;
|
||||
nblocks -= Vvpl->vpl_nemend; /* nothing to do with them */
|
||||
nblocks -= Vvpl->vpl_nemend;/* nothing to do with them */
|
||||
|
||||
for (i = 0, vpp = Vvpl->vpl_pgdesc; i < nblocks; i++, vpp++)
|
||||
{
|
||||
|
@ -1394,17 +1396,17 @@ vc_vacheap(VRelStats *vacrelstats, Relation onerel, VPageList Vvpl)
|
|||
* it) before truncation
|
||||
*/
|
||||
FlushBufferPool(!TransactionFlushEnabled());
|
||||
|
||||
|
||||
i = BlowawayRelationBuffers(onerel, nblocks);
|
||||
if (i < 0)
|
||||
elog (FATAL, "VACUUM (vc_vacheap): BlowawayRelationBuffers returned %d", i);
|
||||
elog(FATAL, "VACUUM (vc_vacheap): BlowawayRelationBuffers returned %d", i);
|
||||
|
||||
nblocks = smgrtruncate(DEFAULT_SMGR, onerel, nblocks);
|
||||
Assert(nblocks >= 0);
|
||||
vacrelstats->npages = nblocks; /* set new number of blocks */
|
||||
}
|
||||
|
||||
} /* vc_vacheap */
|
||||
} /* vc_vacheap */
|
||||
|
||||
/*
|
||||
* vc_vacpage() -- free dead tuples on a page
|
||||
|
@ -1424,7 +1426,7 @@ vc_vacpage(Page page, VPageDescr vpd)
|
|||
}
|
||||
PageRepairFragmentation(page);
|
||||
|
||||
} /* vc_vacpage */
|
||||
} /* vc_vacpage */
|
||||
|
||||
/*
|
||||
* _vc_scanoneind() -- scan one index relation to update statistic.
|
||||
|
@ -1470,7 +1472,7 @@ vc_scanoneind(Relation indrel, int nhtups)
|
|||
elog(NOTICE, "Ind %s: NUMBER OF INDEX' TUPLES (%u) IS NOT THE SAME AS HEAP' (%u)",
|
||||
indrel->rd_rel->relname.data, nitups, nhtups);
|
||||
|
||||
} /* vc_scanoneind */
|
||||
} /* vc_scanoneind */
|
||||
|
||||
/*
|
||||
* vc_vaconeind() -- vacuum one index relation.
|
||||
|
@ -1553,7 +1555,7 @@ vc_vaconeind(VPageList vpl, Relation indrel, int nhtups)
|
|||
elog(NOTICE, "Ind %s: NUMBER OF INDEX' TUPLES (%u) IS NOT THE SAME AS HEAP' (%u)",
|
||||
indrel->rd_rel->relname.data, nitups, nhtups);
|
||||
|
||||
} /* vc_vaconeind */
|
||||
} /* vc_vaconeind */
|
||||
|
||||
/*
|
||||
* vc_tidreapped() -- is a particular tid reapped?
|
||||
|
@ -1597,7 +1599,7 @@ vc_tidreapped(ItemPointer itemptr, VPageList vpl)
|
|||
|
||||
return (vp);
|
||||
|
||||
} /* vc_tidreapped */
|
||||
} /* vc_tidreapped */
|
||||
|
||||
/*
|
||||
* vc_attrstats() -- compute column statistics used by the optimzer
|
||||
|
@ -2011,7 +2013,7 @@ vc_reappage(VPageList vpl, VPageDescr vpc)
|
|||
/* insert this page into vpl list */
|
||||
vc_vpinsert(vpl, newvpd);
|
||||
|
||||
} /* vc_reappage */
|
||||
} /* vc_reappage */
|
||||
|
||||
static void
|
||||
vc_vpinsert(VPageList vpl, VPageDescr vpnew)
|
||||
|
@ -2101,7 +2103,7 @@ vc_find_eq(char *bot, int nelem, int size, char *elm, int (*compar) (char *, cha
|
|||
first_move = true;
|
||||
}
|
||||
|
||||
} /* vc_find_eq */
|
||||
} /* vc_find_eq */
|
||||
|
||||
static int
|
||||
vc_cmp_blk(char *left, char *right)
|
||||
|
@ -2118,7 +2120,7 @@ vc_cmp_blk(char *left, char *right)
|
|||
return (0);
|
||||
return (1);
|
||||
|
||||
} /* vc_cmp_blk */
|
||||
} /* vc_cmp_blk */
|
||||
|
||||
static int
|
||||
vc_cmp_offno(char *left, char *right)
|
||||
|
@ -2130,7 +2132,7 @@ vc_cmp_offno(char *left, char *right)
|
|||
return (0);
|
||||
return (1);
|
||||
|
||||
} /* vc_cmp_offno */
|
||||
} /* vc_cmp_offno */
|
||||
|
||||
|
||||
static void
|
||||
|
@ -2207,7 +2209,7 @@ vc_getindices(Oid relid, int *nindices, Relation **Irel)
|
|||
*Irel = (Relation *) NULL;
|
||||
}
|
||||
|
||||
} /* vc_getindices */
|
||||
} /* vc_getindices */
|
||||
|
||||
|
||||
static void
|
||||
|
@ -2223,7 +2225,7 @@ vc_clsindices(int nindices, Relation *Irel)
|
|||
}
|
||||
pfree(Irel);
|
||||
|
||||
} /* vc_clsindices */
|
||||
} /* vc_clsindices */
|
||||
|
||||
|
||||
static void
|
||||
|
@ -2262,7 +2264,7 @@ vc_mkindesc(Relation onerel, int nindices, Relation *Irel, IndDesc **Idesc)
|
|||
idcur->natts = natts;
|
||||
}
|
||||
|
||||
} /* vc_mkindesc */
|
||||
} /* vc_mkindesc */
|
||||
|
||||
|
||||
static bool
|
||||
|
@ -2283,4 +2285,4 @@ vc_enough_space(VPageDescr vpd, Size len)
|
|||
|
||||
return (false);
|
||||
|
||||
} /* vc_enough_space */
|
||||
} /* vc_enough_space */
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
/*
|
||||
* Routines for handling of 'SET var TO',
|
||||
* 'SHOW var' and 'RESET var' statements.
|
||||
* 'SHOW var' and 'RESET var' statements.
|
||||
*
|
||||
* $Id: variable.c,v 1.3 1998/02/03 16:06:49 thomas Exp $
|
||||
* $Id: variable.c,v 1.4 1998/02/26 04:31:05 momjian Exp $
|
||||
*
|
||||
*/
|
||||
|
||||
|
@ -61,7 +61,7 @@ get_token(char **tok, char **val, const char *str)
|
|||
}
|
||||
|
||||
*tok = (char *) palloc(len + 1);
|
||||
StrNCpy(*tok, start, len+1);
|
||||
StrNCpy(*tok, start, len + 1);
|
||||
|
||||
/* skip white spaces */
|
||||
while (isspace(*str))
|
||||
|
@ -107,7 +107,7 @@ get_token(char **tok, char **val, const char *str)
|
|||
}
|
||||
|
||||
*val = (char *) palloc(len + 1);
|
||||
StrNCpy(*val, start, len+1);
|
||||
StrNCpy(*val, start, len + 1);
|
||||
|
||||
/* skip white spaces */
|
||||
while (isspace(*str))
|
||||
|
@ -342,18 +342,21 @@ parse_date(const char *value)
|
|||
DateStyle = USE_GERMAN_DATES;
|
||||
dcnt++;
|
||||
EuroDates = TRUE;
|
||||
if ((ecnt > 0) && (! EuroDates)) ecnt++;
|
||||
if ((ecnt > 0) && (!EuroDates))
|
||||
ecnt++;
|
||||
}
|
||||
else if (!strncasecmp(tok, "EURO", 4))
|
||||
{
|
||||
EuroDates = TRUE;
|
||||
if ((dcnt <= 0) || (DateStyle != USE_GERMAN_DATES)) ecnt++;
|
||||
if ((dcnt <= 0) || (DateStyle != USE_GERMAN_DATES))
|
||||
ecnt++;
|
||||
}
|
||||
else if ((!strcasecmp(tok, "US"))
|
||||
|| (!strncasecmp(tok, "NONEURO", 7)))
|
||||
{
|
||||
EuroDates = FALSE;
|
||||
if ((dcnt <= 0) || (DateStyle == USE_GERMAN_DATES)) ecnt++;
|
||||
if ((dcnt <= 0) || (DateStyle == USE_GERMAN_DATES))
|
||||
ecnt++;
|
||||
}
|
||||
else if (!strcasecmp(tok, "DEFAULT"))
|
||||
{
|
||||
|
@ -445,7 +448,7 @@ parse_timezone(const char *value)
|
|||
if ((defaultTZ = getenv("TZ")) != NULL)
|
||||
strcpy(TZvalue, defaultTZ);
|
||||
|
||||
/* found nothing so mark with an invalid pointer */
|
||||
/* found nothing so mark with an invalid pointer */
|
||||
else
|
||||
defaultTZ = (char *) -1;
|
||||
|
||||
|
@ -459,7 +462,7 @@ parse_timezone(const char *value)
|
|||
}
|
||||
|
||||
return TRUE;
|
||||
} /* parse_timezone() */
|
||||
} /* parse_timezone() */
|
||||
|
||||
bool
|
||||
show_timezone()
|
||||
|
@ -468,10 +471,10 @@ show_timezone()
|
|||
|
||||
tz = getenv("TZ");
|
||||
|
||||
elog(NOTICE, "Time zone is %s", ((tz != NULL)? tz: "unknown"));
|
||||
elog(NOTICE, "Time zone is %s", ((tz != NULL) ? tz : "unknown"));
|
||||
|
||||
return TRUE;
|
||||
} /* show_timezone() */
|
||||
} /* show_timezone() */
|
||||
|
||||
/* reset_timezone()
|
||||
* Set TZ environment variable to original value.
|
||||
|
@ -501,7 +504,10 @@ reset_timezone()
|
|||
tzset();
|
||||
}
|
||||
|
||||
/* otherwise, time zone was set but no original explicit time zone available */
|
||||
/*
|
||||
* otherwise, time zone was set but no original explicit time zone
|
||||
* available
|
||||
*/
|
||||
else
|
||||
{
|
||||
strcpy(tzbuf, "=");
|
||||
|
@ -511,7 +517,7 @@ reset_timezone()
|
|||
}
|
||||
|
||||
return TRUE;
|
||||
} /* reset_timezone() */
|
||||
} /* reset_timezone() */
|
||||
|
||||
/*-----------------------------------------------------------------------*/
|
||||
struct VariableParsers
|
||||
|
@ -523,13 +529,27 @@ struct VariableParsers
|
|||
} VariableParsers[] =
|
||||
|
||||
{
|
||||
{ "datestyle", parse_date, show_date, reset_date },
|
||||
{ "timezone", parse_timezone, show_timezone, reset_timezone },
|
||||
{ "cost_heap", parse_cost_heap, show_cost_heap, reset_cost_heap },
|
||||
{ "cost_index", parse_cost_index, show_cost_index, reset_cost_index },
|
||||
{ "geqo", parse_geqo, show_geqo, reset_geqo },
|
||||
{ "r_plans", parse_r_plans, show_r_plans, reset_r_plans },
|
||||
{ NULL, NULL, NULL, NULL }
|
||||
{
|
||||
"datestyle", parse_date, show_date, reset_date
|
||||
},
|
||||
{
|
||||
"timezone", parse_timezone, show_timezone, reset_timezone
|
||||
},
|
||||
{
|
||||
"cost_heap", parse_cost_heap, show_cost_heap, reset_cost_heap
|
||||
},
|
||||
{
|
||||
"cost_index", parse_cost_index, show_cost_index, reset_cost_index
|
||||
},
|
||||
{
|
||||
"geqo", parse_geqo, show_geqo, reset_geqo
|
||||
},
|
||||
{
|
||||
"r_plans", parse_r_plans, show_r_plans, reset_r_plans
|
||||
},
|
||||
{
|
||||
NULL, NULL, NULL, NULL
|
||||
}
|
||||
};
|
||||
|
||||
/*-----------------------------------------------------------------------*/
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
*
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $Header: /cvsroot/pgsql/src/backend/commands/view.c,v 1.20 1998/02/10 04:00:32 momjian Exp $
|
||||
* $Header: /cvsroot/pgsql/src/backend/commands/view.c,v 1.21 1998/02/26 04:31:06 momjian Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
|
@ -118,7 +118,7 @@ DefineVirtualRelation(char *relname, List *tlist)
|
|||
* This routine is called when defining/removing a view.
|
||||
*------------------------------------------------------------------
|
||||
*/
|
||||
char *
|
||||
char *
|
||||
MakeRetrieveViewRuleName(char *viewName)
|
||||
{
|
||||
char *buf;
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
*
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $Header: /cvsroot/pgsql/src/backend/executor/execAmi.c,v 1.18 1998/02/23 06:26:53 vadim Exp $
|
||||
* $Header: /cvsroot/pgsql/src/backend/executor/execAmi.c,v 1.19 1998/02/26 04:31:08 momjian Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
|
@ -296,29 +296,32 @@ void
|
|||
ExecReScan(Plan *node, ExprContext *exprCtxt, Plan *parent)
|
||||
{
|
||||
|
||||
if ( node->chgParam != NULL ) /* Wow! */
|
||||
if (node->chgParam != NULL) /* Wow! */
|
||||
{
|
||||
List *lst;
|
||||
|
||||
foreach (lst, node->initPlan)
|
||||
List *lst;
|
||||
|
||||
foreach(lst, node->initPlan)
|
||||
{
|
||||
Plan *splan = ((SubPlan*) lfirst (lst))->plan;
|
||||
if ( splan->extParam != NULL ) /* don't care about child locParam */
|
||||
SetChangedParamList (splan, node->chgParam);
|
||||
if ( splan->chgParam != NULL )
|
||||
ExecReScanSetParamPlan ((SubPlan*) lfirst (lst), node);
|
||||
Plan *splan = ((SubPlan *) lfirst(lst))->plan;
|
||||
|
||||
if (splan->extParam != NULL) /* don't care about child
|
||||
* locParam */
|
||||
SetChangedParamList(splan, node->chgParam);
|
||||
if (splan->chgParam != NULL)
|
||||
ExecReScanSetParamPlan((SubPlan *) lfirst(lst), node);
|
||||
}
|
||||
foreach (lst, node->subPlan)
|
||||
foreach(lst, node->subPlan)
|
||||
{
|
||||
Plan *splan = ((SubPlan*) lfirst (lst))->plan;
|
||||
if ( splan->extParam != NULL )
|
||||
SetChangedParamList (splan, node->chgParam);
|
||||
Plan *splan = ((SubPlan *) lfirst(lst))->plan;
|
||||
|
||||
if (splan->extParam != NULL)
|
||||
SetChangedParamList(splan, node->chgParam);
|
||||
}
|
||||
/* Well. Now set chgParam for left/right trees. */
|
||||
if ( node->lefttree != NULL )
|
||||
SetChangedParamList (node->lefttree, node->chgParam);
|
||||
if ( node->righttree != NULL )
|
||||
SetChangedParamList (node->righttree, node->chgParam);
|
||||
if (node->lefttree != NULL)
|
||||
SetChangedParamList(node->lefttree, node->chgParam);
|
||||
if (node->righttree != NULL)
|
||||
SetChangedParamList(node->righttree, node->chgParam);
|
||||
}
|
||||
|
||||
switch (nodeTag(node))
|
||||
|
@ -332,38 +335,38 @@ ExecReScan(Plan *node, ExprContext *exprCtxt, Plan *parent)
|
|||
break;
|
||||
|
||||
case T_Material:
|
||||
ExecMaterialReScan((Material*) node, exprCtxt, parent);
|
||||
ExecMaterialReScan((Material *) node, exprCtxt, parent);
|
||||
break;
|
||||
|
||||
case T_NestLoop:
|
||||
ExecReScanNestLoop((NestLoop*) node, exprCtxt, parent);
|
||||
ExecReScanNestLoop((NestLoop *) node, exprCtxt, parent);
|
||||
break;
|
||||
|
||||
case T_HashJoin:
|
||||
ExecReScanHashJoin((HashJoin*) node, exprCtxt, parent);
|
||||
ExecReScanHashJoin((HashJoin *) node, exprCtxt, parent);
|
||||
break;
|
||||
|
||||
case T_Hash:
|
||||
ExecReScanHash((Hash*) node, exprCtxt, parent);
|
||||
ExecReScanHash((Hash *) node, exprCtxt, parent);
|
||||
break;
|
||||
|
||||
case T_Agg:
|
||||
ExecReScanAgg((Agg*) node, exprCtxt, parent);
|
||||
ExecReScanAgg((Agg *) node, exprCtxt, parent);
|
||||
break;
|
||||
|
||||
case T_Result:
|
||||
ExecReScanResult((Result*) node, exprCtxt, parent);
|
||||
ExecReScanResult((Result *) node, exprCtxt, parent);
|
||||
break;
|
||||
|
||||
case T_Unique:
|
||||
ExecReScanUnique((Unique*) node, exprCtxt, parent);
|
||||
ExecReScanUnique((Unique *) node, exprCtxt, parent);
|
||||
break;
|
||||
|
||||
case T_Sort:
|
||||
ExecReScanSort((Sort*) node, exprCtxt, parent);
|
||||
ExecReScanSort((Sort *) node, exprCtxt, parent);
|
||||
break;
|
||||
|
||||
/*
|
||||
/*
|
||||
* Tee is never used
|
||||
case T_Tee:
|
||||
ExecTeeReScan((Tee *) node, exprCtxt, parent);
|
||||
|
@ -373,10 +376,10 @@ ExecReScan(Plan *node, ExprContext *exprCtxt, Plan *parent)
|
|||
elog(ERROR, "ExecReScan: node type %u not supported", nodeTag(node));
|
||||
return;
|
||||
}
|
||||
|
||||
if ( node->chgParam != NULL )
|
||||
|
||||
if (node->chgParam != NULL)
|
||||
{
|
||||
freeList (node->chgParam);
|
||||
freeList(node->chgParam);
|
||||
node->chgParam = NULL;
|
||||
}
|
||||
}
|
||||
|
@ -415,7 +418,7 @@ ExecMarkPos(Plan *node)
|
|||
{
|
||||
switch (nodeTag(node))
|
||||
{
|
||||
case T_SeqScan:
|
||||
case T_SeqScan:
|
||||
ExecSeqMarkPos((SeqScan *) node);
|
||||
break;
|
||||
|
||||
|
@ -445,7 +448,7 @@ ExecRestrPos(Plan *node)
|
|||
{
|
||||
switch (nodeTag(node))
|
||||
{
|
||||
case T_SeqScan:
|
||||
case T_SeqScan:
|
||||
ExecSeqRestrPos((SeqScan *) node);
|
||||
return;
|
||||
|
||||
|
@ -510,7 +513,7 @@ ExecCreatR(TupleDesc tupType,
|
|||
* '\0 '
|
||||
*/
|
||||
relDesc = heap_create("", tupType);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* ----------------
|
||||
|
|
|
@ -26,7 +26,7 @@
|
|||
*
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $Header: /cvsroot/pgsql/src/backend/executor/execMain.c,v 1.43 1998/02/21 06:31:37 scrappy Exp $
|
||||
* $Header: /cvsroot/pgsql/src/backend/executor/execMain.c,v 1.44 1998/02/26 04:31:09 momjian Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
|
@ -57,22 +57,28 @@
|
|||
|
||||
|
||||
/* decls for local routines only used within this module */
|
||||
static void ExecCheckPerms(CmdType operation, int resultRelation, List *rangeTable,
|
||||
static void
|
||||
ExecCheckPerms(CmdType operation, int resultRelation, List *rangeTable,
|
||||
Query *parseTree);
|
||||
static TupleDesc InitPlan(CmdType operation, Query *parseTree,
|
||||
static TupleDesc
|
||||
InitPlan(CmdType operation, Query *parseTree,
|
||||
Plan *plan, EState *estate);
|
||||
static void EndPlan(Plan *plan, EState *estate);
|
||||
static TupleTableSlot * ExecutePlan(EState *estate, Plan *plan,
|
||||
static TupleTableSlot *
|
||||
ExecutePlan(EState *estate, Plan *plan,
|
||||
Query *parseTree, CmdType operation,
|
||||
int numberTuples, ScanDirection direction,
|
||||
void (*printfunc) ());
|
||||
static void ExecRetrieve(TupleTableSlot *slot, void (*printfunc) (),
|
||||
EState *estate);
|
||||
static void ExecAppend(TupleTableSlot *slot, ItemPointer tupleid,
|
||||
static void
|
||||
ExecAppend(TupleTableSlot *slot, ItemPointer tupleid,
|
||||
EState *estate);
|
||||
static void ExecDelete(TupleTableSlot *slot, ItemPointer tupleid,
|
||||
static void
|
||||
ExecDelete(TupleTableSlot *slot, ItemPointer tupleid,
|
||||
EState *estate);
|
||||
static void ExecReplace(TupleTableSlot *slot, ItemPointer tupleid,
|
||||
static void
|
||||
ExecReplace(TupleTableSlot *slot, ItemPointer tupleid,
|
||||
EState *estate, Query *parseTree);
|
||||
|
||||
/* end of local decls */
|
||||
|
@ -83,13 +89,14 @@ static int queryLimit = ALL_TUPLES;
|
|||
#undef ALL_TUPLES
|
||||
#define ALL_TUPLES queryLimit
|
||||
|
||||
int ExecutorLimit(int limit);
|
||||
int ExecutorLimit(int limit);
|
||||
|
||||
int
|
||||
ExecutorLimit(int limit)
|
||||
{
|
||||
return queryLimit = limit;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
/* ----------------------------------------------------------------
|
||||
|
@ -110,14 +117,14 @@ ExecutorStart(QueryDesc *queryDesc, EState *estate)
|
|||
|
||||
/* sanity checks */
|
||||
Assert(queryDesc != NULL);
|
||||
|
||||
|
||||
if (queryDesc->plantree->nParamExec > 0)
|
||||
{
|
||||
estate->es_param_exec_vals = (ParamExecData*)
|
||||
palloc (queryDesc->plantree->nParamExec * sizeof (ParamExecData));
|
||||
memset (estate->es_param_exec_vals, 0 , queryDesc->plantree->nParamExec * sizeof (ParamExecData));
|
||||
estate->es_param_exec_vals = (ParamExecData *)
|
||||
palloc(queryDesc->plantree->nParamExec * sizeof(ParamExecData));
|
||||
memset(estate->es_param_exec_vals, 0, queryDesc->plantree->nParamExec * sizeof(ParamExecData));
|
||||
}
|
||||
|
||||
|
||||
result = InitPlan(queryDesc->operation,
|
||||
queryDesc->parsetree,
|
||||
queryDesc->plantree,
|
||||
|
@ -301,11 +308,12 @@ ExecCheckPerms(CmdType operation,
|
|||
|
||||
if (rte->skipAcl)
|
||||
{
|
||||
|
||||
/*
|
||||
* This happens if the access to this table is due
|
||||
* to a view query rewriting - the rewrite handler
|
||||
* checked the permissions against the view owner,
|
||||
* so we just skip this entry.
|
||||
* This happens if the access to this table is due to a view
|
||||
* query rewriting - the rewrite handler checked the
|
||||
* permissions against the view owner, so we just skip this
|
||||
* entry.
|
||||
*/
|
||||
continue;
|
||||
}
|
||||
|
@ -1239,8 +1247,8 @@ ExecAttrDefault(Relation rel, HeapTuple tuple)
|
|||
econtext->ecxt_outertuple = NULL; /* outer tuple slot */
|
||||
econtext->ecxt_relation = NULL; /* relation */
|
||||
econtext->ecxt_relid = 0; /* relid */
|
||||
econtext->ecxt_param_list_info = NULL; /* param list info */
|
||||
econtext->ecxt_param_exec_vals = NULL; /* exec param values */
|
||||
econtext->ecxt_param_list_info = NULL; /* param list info */
|
||||
econtext->ecxt_param_exec_vals = NULL; /* exec param values */
|
||||
econtext->ecxt_range_table = NULL; /* range table */
|
||||
for (i = 0; i < ndef; i++)
|
||||
{
|
||||
|
@ -1283,6 +1291,7 @@ ExecAttrDefault(Relation rel, HeapTuple tuple)
|
|||
return (newtuple);
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
static char *
|
||||
|
|
|
@ -11,7 +11,7 @@
|
|||
*
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $Header: /cvsroot/pgsql/src/backend/executor/execProcnode.c,v 1.8 1998/02/13 03:26:40 vadim Exp $
|
||||
* $Header: /cvsroot/pgsql/src/backend/executor/execProcnode.c,v 1.9 1998/02/26 04:31:11 momjian Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
|
@ -116,14 +116,14 @@ ExecInitNode(Plan *node, EState *estate, Plan *parent)
|
|||
*/
|
||||
if (node == NULL)
|
||||
return FALSE;
|
||||
|
||||
foreach (subp, node->initPlan)
|
||||
|
||||
foreach(subp, node->initPlan)
|
||||
{
|
||||
result = ExecInitSubPlan ((SubPlan*) lfirst (subp), estate, node);
|
||||
if ( result == FALSE )
|
||||
result = ExecInitSubPlan((SubPlan *) lfirst(subp), estate, node);
|
||||
if (result == FALSE)
|
||||
return (FALSE);
|
||||
}
|
||||
|
||||
|
||||
switch (nodeTag(node))
|
||||
{
|
||||
/* ----------------
|
||||
|
@ -202,13 +202,13 @@ ExecInitNode(Plan *node, EState *estate, Plan *parent)
|
|||
elog(ERROR, "ExecInitNode: node %d unsupported", nodeTag(node));
|
||||
result = FALSE;
|
||||
}
|
||||
|
||||
if ( result != FALSE )
|
||||
|
||||
if (result != FALSE)
|
||||
{
|
||||
foreach (subp, node->subPlan)
|
||||
foreach(subp, node->subPlan)
|
||||
{
|
||||
result = ExecInitSubPlan ((SubPlan*) lfirst (subp), estate, node);
|
||||
if ( result == FALSE )
|
||||
result = ExecInitSubPlan((SubPlan *) lfirst(subp), estate, node);
|
||||
if (result == FALSE)
|
||||
return (FALSE);
|
||||
}
|
||||
}
|
||||
|
@ -235,10 +235,10 @@ ExecProcNode(Plan *node, Plan *parent)
|
|||
*/
|
||||
if (node == NULL)
|
||||
return NULL;
|
||||
|
||||
if ( node->chgParam != NULL ) /* something changed */
|
||||
ExecReScan (node, NULL, parent); /* let ReScan handle this */
|
||||
|
||||
|
||||
if (node->chgParam != NULL) /* something changed */
|
||||
ExecReScan(node, NULL, parent); /* let ReScan handle this */
|
||||
|
||||
switch (nodeTag(node))
|
||||
{
|
||||
/* ----------------
|
||||
|
@ -410,7 +410,7 @@ void
|
|||
ExecEndNode(Plan *node, Plan *parent)
|
||||
{
|
||||
List *subp;
|
||||
|
||||
|
||||
/* ----------------
|
||||
* do nothing when we get to the end
|
||||
* of a leaf on tree.
|
||||
|
@ -418,18 +418,18 @@ ExecEndNode(Plan *node, Plan *parent)
|
|||
*/
|
||||
if (node == NULL)
|
||||
return;
|
||||
|
||||
foreach (subp, node->initPlan)
|
||||
|
||||
foreach(subp, node->initPlan)
|
||||
{
|
||||
ExecEndSubPlan ((SubPlan*) lfirst (subp));
|
||||
ExecEndSubPlan((SubPlan *) lfirst(subp));
|
||||
}
|
||||
foreach (subp, node->subPlan)
|
||||
foreach(subp, node->subPlan)
|
||||
{
|
||||
ExecEndSubPlan ((SubPlan*) lfirst (subp));
|
||||
ExecEndSubPlan((SubPlan *) lfirst(subp));
|
||||
}
|
||||
if ( node->chgParam != NULL )
|
||||
if (node->chgParam != NULL)
|
||||
{
|
||||
freeList (node->chgParam);
|
||||
freeList(node->chgParam);
|
||||
node->chgParam = NULL;
|
||||
}
|
||||
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
*
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $Header: /cvsroot/pgsql/src/backend/executor/execQual.c,v 1.25 1998/02/13 03:26:42 vadim Exp $
|
||||
* $Header: /cvsroot/pgsql/src/backend/executor/execQual.c,v 1.26 1998/02/26 04:31:13 momjian Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
|
@ -71,19 +71,24 @@ int execConstLen;
|
|||
|
||||
/* static functions decls */
|
||||
static Datum ExecEvalAggreg(Aggreg *agg, ExprContext *econtext, bool *isNull);
|
||||
static Datum ExecEvalArrayRef(ArrayRef *arrayRef, ExprContext *econtext,
|
||||
static Datum
|
||||
ExecEvalArrayRef(ArrayRef *arrayRef, ExprContext *econtext,
|
||||
bool *isNull, bool *isDone);
|
||||
static Datum ExecEvalAnd(Expr *andExpr, ExprContext *econtext, bool *isNull);
|
||||
static Datum ExecEvalFunc(Expr *funcClause, ExprContext *econtext,
|
||||
static Datum
|
||||
ExecEvalFunc(Expr *funcClause, ExprContext *econtext,
|
||||
bool *isNull, bool *isDone);
|
||||
static void ExecEvalFuncArgs(FunctionCachePtr fcache, ExprContext *econtext,
|
||||
static void
|
||||
ExecEvalFuncArgs(FunctionCachePtr fcache, ExprContext *econtext,
|
||||
List *argList, Datum argV[], bool *argIsDone);
|
||||
static Datum ExecEvalNot(Expr *notclause, ExprContext *econtext, bool *isNull);
|
||||
static Datum ExecEvalOper(Expr *opClause, ExprContext *econtext,
|
||||
static Datum
|
||||
ExecEvalOper(Expr *opClause, ExprContext *econtext,
|
||||
bool *isNull);
|
||||
static Datum ExecEvalOr(Expr *orExpr, ExprContext *econtext, bool *isNull);
|
||||
static Datum ExecEvalVar(Var *variable, ExprContext *econtext, bool *isNull);
|
||||
static Datum ExecMakeFunctionResult(Node *node, List *arguments,
|
||||
static Datum
|
||||
ExecMakeFunctionResult(Node *node, List *arguments,
|
||||
ExprContext *econtext, bool *isNull, bool *isDone);
|
||||
static bool ExecQualClause(Node *clause, ExprContext *econtext);
|
||||
|
||||
|
@ -301,10 +306,11 @@ ExecEvalVar(Var *variable, ExprContext *econtext, bool *isNull)
|
|||
return (Datum) tempSlot;
|
||||
}
|
||||
|
||||
result = heap_getattr(heapTuple, /* tuple containing attribute */
|
||||
attnum, /* attribute number of desired attribute */
|
||||
tuple_type,/* tuple descriptor of tuple */
|
||||
isNull); /* return: is attribute null? */
|
||||
result = heap_getattr(heapTuple, /* tuple containing attribute */
|
||||
attnum, /* attribute number of desired
|
||||
* attribute */
|
||||
tuple_type, /* tuple descriptor of tuple */
|
||||
isNull); /* return: is attribute null? */
|
||||
|
||||
/* ----------------
|
||||
* return null if att is null
|
||||
|
@ -379,18 +385,18 @@ ExecEvalParam(Param *expression, ExprContext *econtext, bool *isNull)
|
|||
AttrNumber thisParameterId = expression->paramid;
|
||||
int matchFound;
|
||||
ParamListInfo paramList;
|
||||
|
||||
if ( thisParameterKind == PARAM_EXEC )
|
||||
|
||||
if (thisParameterKind == PARAM_EXEC)
|
||||
{
|
||||
ParamExecData *prm = &(econtext->ecxt_param_exec_vals[thisParameterId]);
|
||||
|
||||
if ( prm->execPlan != NULL )
|
||||
ExecSetParamPlan (prm->execPlan);
|
||||
Assert (prm->execPlan == NULL);
|
||||
ParamExecData *prm = &(econtext->ecxt_param_exec_vals[thisParameterId]);
|
||||
|
||||
if (prm->execPlan != NULL)
|
||||
ExecSetParamPlan(prm->execPlan);
|
||||
Assert(prm->execPlan == NULL);
|
||||
*isNull = prm->isnull;
|
||||
return (prm->value);
|
||||
}
|
||||
|
||||
|
||||
thisParameterName = expression->paramname;
|
||||
paramList = econtext->ecxt_param_list_info;
|
||||
|
||||
|
@ -544,7 +550,7 @@ GetAttributeByNum(TupleTableSlot *slot,
|
|||
|
||||
/* XXX char16 name for catalogs */
|
||||
#ifdef NOT_USED
|
||||
char *
|
||||
char *
|
||||
att_by_num(TupleTableSlot *slot,
|
||||
AttrNumber attrno,
|
||||
bool *isNull)
|
||||
|
@ -554,7 +560,7 @@ att_by_num(TupleTableSlot *slot,
|
|||
|
||||
#endif
|
||||
|
||||
char *
|
||||
char *
|
||||
GetAttributeByName(TupleTableSlot *slot, char *attname, bool *isNull)
|
||||
{
|
||||
AttrNumber attrno;
|
||||
|
@ -605,7 +611,7 @@ GetAttributeByName(TupleTableSlot *slot, char *attname, bool *isNull)
|
|||
|
||||
/* XXX char16 name for catalogs */
|
||||
#ifdef NOT_USED
|
||||
char *
|
||||
char *
|
||||
att_by_name(TupleTableSlot *slot, char *attname, bool *isNull)
|
||||
{
|
||||
return (GetAttributeByName(slot, attname, isNull));
|
||||
|
@ -1045,19 +1051,21 @@ ExecEvalOr(Expr *orExpr, ExprContext *econtext, bool *isNull)
|
|||
if (*isNull)
|
||||
{
|
||||
IsNull = *isNull;
|
||||
|
||||
/*
|
||||
* Many functions don't (or can't!) check is an argument
|
||||
* NULL or NOT_NULL and may return TRUE (1) with *isNull TRUE
|
||||
* (an_int4_column <> 1: int4ne returns TRUE for NULLs).
|
||||
* Not having time to fix function manager I want to fix
|
||||
* OR: if we had 'x <> 1 OR x isnull' then TRUE, TRUE were
|
||||
* returned by 'x <> 1' for NULL ... but ExecQualClause say
|
||||
* that qualification *fails* if isnull is TRUE for all values
|
||||
* returned by ExecEvalExpr. So, force this rule here: if isnull
|
||||
* is TRUE then clause failed. Note: nullvalue() & nonnullvalue()
|
||||
* always set isnull to FALSE for NULLs. - vadim 09/22/97
|
||||
* Many functions don't (or can't!) check is an argument NULL
|
||||
* or NOT_NULL and may return TRUE (1) with *isNull TRUE
|
||||
* (an_int4_column <> 1: int4ne returns TRUE for NULLs). Not
|
||||
* having time to fix function manager I want to fix OR: if we
|
||||
* had 'x <> 1 OR x isnull' then TRUE, TRUE were returned by
|
||||
* 'x <> 1' for NULL ... but ExecQualClause say that
|
||||
* qualification *fails* if isnull is TRUE for all values
|
||||
* returned by ExecEvalExpr. So, force this rule here: if
|
||||
* isnull is TRUE then clause failed. Note: nullvalue() &
|
||||
* nonnullvalue() always set isnull to FALSE for NULLs. -
|
||||
* vadim 09/22/97
|
||||
*/
|
||||
const_value = 0;
|
||||
const_value = 0;
|
||||
}
|
||||
|
||||
/* ----------------
|
||||
|
@ -1238,7 +1246,7 @@ ExecEvalExpr(Node *expression,
|
|||
retDatum = (Datum) ExecEvalNot(expr, econtext, isNull);
|
||||
break;
|
||||
case SUBPLAN_EXPR:
|
||||
retDatum = (Datum) ExecSubPlan((SubPlan*) expr->oper, expr->args, econtext);
|
||||
retDatum = (Datum) ExecSubPlan((SubPlan *) expr->oper, expr->args, econtext);
|
||||
break;
|
||||
default:
|
||||
elog(ERROR, "ExecEvalExpr: unknown expression type %d", expr->opType);
|
||||
|
|
|
@ -14,7 +14,7 @@
|
|||
*
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $Header: /cvsroot/pgsql/src/backend/executor/execTuples.c,v 1.16 1998/02/10 04:00:50 momjian Exp $
|
||||
* $Header: /cvsroot/pgsql/src/backend/executor/execTuples.c,v 1.17 1998/02/26 04:31:14 momjian Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
|
@ -986,8 +986,8 @@ ExecTypeFromTL(List *targetList)
|
|||
resdom->resno,
|
||||
resdom->resname,
|
||||
/* fix for SELECT NULL ... */
|
||||
(restype ? restype : UNKNOWNOID),
|
||||
resdom->restypmod,
|
||||
(restype ? restype : UNKNOWNOID),
|
||||
resdom->restypmod,
|
||||
0,
|
||||
false);
|
||||
|
||||
|
@ -1021,7 +1021,7 @@ ExecTypeFromTL(List *targetList)
|
|||
fjRes->resno,
|
||||
fjRes->resname,
|
||||
restype,
|
||||
fjRes->restypmod,
|
||||
fjRes->restypmod,
|
||||
0,
|
||||
false);
|
||||
/*
|
||||
|
@ -1045,7 +1045,7 @@ ExecTypeFromTL(List *targetList)
|
|||
fjRes->resno,
|
||||
fjRes->resname,
|
||||
restype,
|
||||
fjRes->restypmod,
|
||||
fjRes->restypmod,
|
||||
0,
|
||||
false);
|
||||
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
*
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $Header: /cvsroot/pgsql/src/backend/executor/execUtils.c,v 1.29 1998/02/13 03:26:43 vadim Exp $
|
||||
* $Header: /cvsroot/pgsql/src/backend/executor/execUtils.c,v 1.30 1998/02/26 04:31:15 momjian Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
|
@ -189,7 +189,7 @@ ExecAssignExprContext(EState *estate, CommonState *commonstate)
|
|||
econtext->ecxt_relid = 0; /* relid */
|
||||
econtext->ecxt_param_list_info = estate->es_param_list_info;
|
||||
econtext->ecxt_param_exec_vals = estate->es_param_exec_vals;
|
||||
econtext->ecxt_range_table = estate->es_range_table; /* range table */
|
||||
econtext->ecxt_range_table = estate->es_range_table; /* range table */
|
||||
|
||||
commonstate->cs_ExprContext = econtext;
|
||||
}
|
||||
|
@ -1176,24 +1176,24 @@ ExecInsertIndexTuples(TupleTableSlot *slot,
|
|||
pfree(econtext);
|
||||
}
|
||||
|
||||
void
|
||||
SetChangedParamList (Plan *node, List *newchg)
|
||||
void
|
||||
SetChangedParamList(Plan *node, List *newchg)
|
||||
{
|
||||
List *nl;
|
||||
|
||||
foreach (nl, newchg)
|
||||
List *nl;
|
||||
|
||||
foreach(nl, newchg)
|
||||
{
|
||||
int paramId = lfirsti(nl);
|
||||
|
||||
int paramId = lfirsti(nl);
|
||||
|
||||
/* if this node doesn't depend on a param ... */
|
||||
if ( !intMember (paramId, node->extParam) &&
|
||||
!intMember (paramId, node->locParam) )
|
||||
if (!intMember(paramId, node->extParam) &&
|
||||
!intMember(paramId, node->locParam))
|
||||
continue;
|
||||
/* if this param is already in list of changed ones ... */
|
||||
if ( intMember (paramId, node->chgParam) )
|
||||
if (intMember(paramId, node->chgParam))
|
||||
continue;
|
||||
/* else - add this param to the list */
|
||||
node->chgParam = lappendi (node->chgParam, paramId);
|
||||
node->chgParam = lappendi(node->chgParam, paramId);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -121,7 +121,7 @@ ExecAgg(Agg *node)
|
|||
econtext = aggstate->csstate.cstate.cs_ExprContext;
|
||||
nagg = length(node->aggs);
|
||||
|
||||
aggregates = (Aggreg **)palloc(sizeof(Aggreg *) * nagg);
|
||||
aggregates = (Aggreg **) palloc(sizeof(Aggreg *) * nagg);
|
||||
|
||||
/* take List* and make it an array that can be quickly indexed */
|
||||
alist = node->aggs;
|
||||
|
@ -333,18 +333,18 @@ ExecAgg(Agg *node)
|
|||
|
||||
break;
|
||||
case T_Expr:
|
||||
{
|
||||
FunctionCachePtr fcache_ptr;
|
||||
|
||||
if (nodeTag(tagnode) == T_Func)
|
||||
fcache_ptr = ((Func *) tagnode)->func_fcache;
|
||||
else
|
||||
fcache_ptr = ((Oper *) tagnode)->op_fcache;
|
||||
attlen = fcache_ptr->typlen;
|
||||
byVal = fcache_ptr->typbyval;
|
||||
{
|
||||
FunctionCachePtr fcache_ptr;
|
||||
|
||||
break;
|
||||
}
|
||||
if (nodeTag(tagnode) == T_Func)
|
||||
fcache_ptr = ((Func *) tagnode)->func_fcache;
|
||||
else
|
||||
fcache_ptr = ((Oper *) tagnode)->op_fcache;
|
||||
attlen = fcache_ptr->typlen;
|
||||
byVal = fcache_ptr->typbyval;
|
||||
|
||||
break;
|
||||
}
|
||||
case T_Const:
|
||||
attlen = ((Const *) aggregates[i]->target)->constlen;
|
||||
byVal = ((Const *) aggregates[i]->target)->constbyval;
|
||||
|
@ -375,8 +375,8 @@ ExecAgg(Agg *node)
|
|||
args[0] = value1[i];
|
||||
args[1] = newVal;
|
||||
value1[i] =
|
||||
(Datum) fmgr_c(&aggfns->xfn1,
|
||||
(FmgrValues *) args,
|
||||
(Datum) fmgr_c(&aggfns->xfn1,
|
||||
(FmgrValues *) args,
|
||||
&isNull1);
|
||||
Assert(!isNull1);
|
||||
}
|
||||
|
@ -440,7 +440,7 @@ ExecAgg(Agg *node)
|
|||
else
|
||||
elog(NOTICE, "ExecAgg: no valid transition functions??");
|
||||
value1[i] = (Datum) fmgr_c(&aggfns->finalfn,
|
||||
(FmgrValues *) args, &(nulls[i]));
|
||||
(FmgrValues *) args, &(nulls[i]));
|
||||
}
|
||||
else if (aggfns->xfn1.fn_addr != NULL)
|
||||
{
|
||||
|
@ -545,15 +545,15 @@ ExecInitAgg(Agg *node, EState *estate, Plan *parent)
|
|||
ExecInitNode(outerPlan, estate, (Plan *) node);
|
||||
|
||||
/*
|
||||
* Result runs in its own context, but make it use our aggregates
|
||||
* fix for 'select sum(2+2)'
|
||||
* Result runs in its own context, but make it use our aggregates fix
|
||||
* for 'select sum(2+2)'
|
||||
*/
|
||||
if (nodeTag(outerPlan) == T_Result)
|
||||
{
|
||||
((Result *)outerPlan)->resstate->cstate.cs_ProjInfo->pi_exprContext->ecxt_values =
|
||||
econtext->ecxt_values;
|
||||
((Result *)outerPlan)->resstate->cstate.cs_ProjInfo->pi_exprContext->ecxt_nulls =
|
||||
econtext->ecxt_nulls;
|
||||
((Result *) outerPlan)->resstate->cstate.cs_ProjInfo->pi_exprContext->ecxt_values =
|
||||
econtext->ecxt_values;
|
||||
((Result *) outerPlan)->resstate->cstate.cs_ProjInfo->pi_exprContext->ecxt_nulls =
|
||||
econtext->ecxt_nulls;
|
||||
}
|
||||
|
||||
|
||||
|
@ -661,7 +661,7 @@ aggGetAttr(TupleTableSlot *slot,
|
|||
return (Datum) tempSlot;
|
||||
}
|
||||
|
||||
result =
|
||||
result =
|
||||
heap_getattr(heapTuple, /* tuple containing attribute */
|
||||
attnum, /* attribute number of desired attribute */
|
||||
tuple_type,/* tuple descriptor of tuple */
|
||||
|
@ -680,17 +680,18 @@ aggGetAttr(TupleTableSlot *slot,
|
|||
void
|
||||
ExecReScanAgg(Agg *node, ExprContext *exprCtxt, Plan *parent)
|
||||
{
|
||||
AggState *aggstate = node->aggstate;
|
||||
ExprContext *econtext = aggstate->csstate.cstate.cs_ExprContext;
|
||||
AggState *aggstate = node->aggstate;
|
||||
ExprContext *econtext = aggstate->csstate.cstate.cs_ExprContext;
|
||||
|
||||
aggstate->agg_done = FALSE;
|
||||
MemSet(econtext->ecxt_values, 0, sizeof(Datum) * length(node->aggs));
|
||||
MemSet(econtext->ecxt_nulls, 0, length(node->aggs));
|
||||
/*
|
||||
* if chgParam of subnode is not null then plan
|
||||
* will be re-scanned by first ExecProcNode.
|
||||
|
||||
/*
|
||||
* if chgParam of subnode is not null then plan will be re-scanned by
|
||||
* first ExecProcNode.
|
||||
*/
|
||||
if (((Plan*) node)->lefttree->chgParam == NULL)
|
||||
ExecReScan (((Plan*) node)->lefttree, exprCtxt, (Plan *) node);
|
||||
|
||||
if (((Plan *) node)->lefttree->chgParam == NULL)
|
||||
ExecReScan(((Plan *) node)->lefttree, exprCtxt, (Plan *) node);
|
||||
|
||||
}
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
*
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $Header: /cvsroot/pgsql/src/backend/executor/nodeAppend.c,v 1.10 1997/12/27 06:40:50 momjian Exp $
|
||||
* $Header: /cvsroot/pgsql/src/backend/executor/nodeAppend.c,v 1.11 1998/02/26 04:31:21 momjian Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
|
@ -150,7 +150,7 @@ exec_append_initialize_next(Append *node)
|
|||
}
|
||||
else
|
||||
estate->es_range_table = nth(whichplan, rts);
|
||||
|
||||
|
||||
if (unionstate->as_junkFilter_list)
|
||||
{
|
||||
estate->es_junkFilter =
|
||||
|
@ -161,7 +161,7 @@ exec_append_initialize_next(Append *node)
|
|||
{
|
||||
estate->es_result_relation_info =
|
||||
(RelationInfo *) nth(whichplan,
|
||||
unionstate->as_result_relation_info_list);
|
||||
unionstate->as_result_relation_info_list);
|
||||
}
|
||||
result_slot->ttc_whichplan = whichplan;
|
||||
|
||||
|
|
|
@ -13,7 +13,7 @@
|
|||
* columns. (ie. tuples from the same group are consecutive)
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $Header: /cvsroot/pgsql/src/backend/executor/nodeGroup.c,v 1.17 1998/02/18 12:40:43 vadim Exp $
|
||||
* $Header: /cvsroot/pgsql/src/backend/executor/nodeGroup.c,v 1.18 1998/02/26 04:31:24 momjian Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
|
@ -113,24 +113,25 @@ ExecGroupEveryTuple(Group *node)
|
|||
|
||||
firsttuple = grpstate->grp_firstTuple;
|
||||
/* this should occur on the first call only */
|
||||
if (firsttuple == NULL)
|
||||
if (firsttuple == NULL)
|
||||
{
|
||||
grpstate->grp_firstTuple = heap_copytuple (outerTuple);
|
||||
grpstate->grp_firstTuple = heap_copytuple(outerTuple);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
/*
|
||||
* Compare with first tuple and see if this tuple is of
|
||||
* the same group.
|
||||
* Compare with first tuple and see if this tuple is of the
|
||||
* same group.
|
||||
*/
|
||||
if (!sameGroup(firsttuple, outerslot->val,
|
||||
node->numCols, node->grpColIdx,
|
||||
ExecGetScanType(&grpstate->csstate)))
|
||||
node->numCols, node->grpColIdx,
|
||||
ExecGetScanType(&grpstate->csstate)))
|
||||
{
|
||||
grpstate->grp_useFirstTuple = TRUE;
|
||||
pfree (firsttuple);
|
||||
grpstate->grp_firstTuple = heap_copytuple (outerTuple);
|
||||
|
||||
pfree(firsttuple);
|
||||
grpstate->grp_firstTuple = heap_copytuple(outerTuple);
|
||||
|
||||
return NULL; /* signifies the end of the group */
|
||||
}
|
||||
}
|
||||
|
@ -188,7 +189,7 @@ ExecGroupOneTuple(Group *node)
|
|||
|
||||
firsttuple = grpstate->grp_firstTuple;
|
||||
/* this should occur on the first call only */
|
||||
if (firsttuple == NULL)
|
||||
if (firsttuple == NULL)
|
||||
{
|
||||
outerslot = ExecProcNode(outerPlan(node), (Plan *) node);
|
||||
if (outerslot)
|
||||
|
@ -198,7 +199,7 @@ ExecGroupOneTuple(Group *node)
|
|||
grpstate->grp_done = TRUE;
|
||||
return NULL;
|
||||
}
|
||||
grpstate->grp_firstTuple = firsttuple = heap_copytuple (outerTuple);
|
||||
grpstate->grp_firstTuple = firsttuple = heap_copytuple(outerTuple);
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -238,12 +239,12 @@ ExecGroupOneTuple(Group *node)
|
|||
false);
|
||||
econtext->ecxt_scantuple = grpstate->csstate.css_ScanTupleSlot;
|
||||
resultSlot = ExecProject(projInfo, &isDone);
|
||||
|
||||
|
||||
/* save outerTuple if we are not done yet */
|
||||
if (!grpstate->grp_done)
|
||||
{
|
||||
pfree (firsttuple);
|
||||
grpstate->grp_firstTuple = heap_copytuple (outerTuple);
|
||||
pfree(firsttuple);
|
||||
grpstate->grp_firstTuple = heap_copytuple(outerTuple);
|
||||
}
|
||||
|
||||
return resultSlot;
|
||||
|
@ -340,7 +341,7 @@ ExecEndGroup(Group *node)
|
|||
ExecClearTuple(grpstate->csstate.css_ScanTupleSlot);
|
||||
if (grpstate->grp_firstTuple != NULL)
|
||||
{
|
||||
pfree (grpstate->grp_firstTuple);
|
||||
pfree(grpstate->grp_firstTuple);
|
||||
grpstate->grp_firstTuple = NULL;
|
||||
}
|
||||
}
|
||||
|
@ -362,7 +363,7 @@ sameGroup(HeapTuple oldtuple,
|
|||
bool isNull1,
|
||||
isNull2;
|
||||
Datum attr1,
|
||||
attr2;
|
||||
attr2;
|
||||
char *val1,
|
||||
*val2;
|
||||
int i;
|
||||
|
@ -391,10 +392,10 @@ sameGroup(HeapTuple oldtuple,
|
|||
|
||||
val1 = fmgr(typoutput, attr1,
|
||||
gettypelem(tupdesc->attrs[att - 1]->atttypid),
|
||||
tupdesc->attrs[att - 1]->atttypmod);
|
||||
tupdesc->attrs[att - 1]->atttypmod);
|
||||
val2 = fmgr(typoutput, attr2,
|
||||
gettypelem(tupdesc->attrs[att - 1]->atttypid),
|
||||
tupdesc->attrs[att - 1]->atttypmod);
|
||||
tupdesc->attrs[att - 1]->atttypmod);
|
||||
|
||||
/*
|
||||
* now, val1 and val2 are ascii representations so we can use
|
||||
|
@ -402,12 +403,12 @@ sameGroup(HeapTuple oldtuple,
|
|||
*/
|
||||
if (strcmp(val1, val2) != 0)
|
||||
{
|
||||
pfree (val1);
|
||||
pfree (val2);
|
||||
pfree(val1);
|
||||
pfree(val2);
|
||||
return FALSE;
|
||||
}
|
||||
pfree (val1);
|
||||
pfree (val2);
|
||||
pfree(val1);
|
||||
pfree(val2);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
*
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $Header: /cvsroot/pgsql/src/backend/executor/nodeHash.c,v 1.19 1998/02/13 03:26:46 vadim Exp $
|
||||
* $Header: /cvsroot/pgsql/src/backend/executor/nodeHash.c,v 1.20 1998/02/26 04:31:25 momjian Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
|
@ -781,7 +781,7 @@ static int
|
|||
hashFunc(char *key, int len)
|
||||
{
|
||||
unsigned int h;
|
||||
int l;
|
||||
int l;
|
||||
unsigned char *k;
|
||||
|
||||
/*
|
||||
|
@ -901,12 +901,12 @@ ExecReScanHash(Hash *node, ExprContext *exprCtxt, Plan *parent)
|
|||
pfree(hashstate->hashBatches);
|
||||
hashstate->hashBatches = NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
* if chgParam of subnode is not null then plan
|
||||
* will be re-scanned by first ExecProcNode.
|
||||
|
||||
/*
|
||||
* if chgParam of subnode is not null then plan will be re-scanned by
|
||||
* first ExecProcNode.
|
||||
*/
|
||||
if (((Plan*) node)->lefttree->chgParam == NULL)
|
||||
ExecReScan (((Plan*) node)->lefttree, exprCtxt, (Plan *) node);
|
||||
|
||||
if (((Plan *) node)->lefttree->chgParam == NULL)
|
||||
ExecReScan(((Plan *) node)->lefttree, exprCtxt, (Plan *) node);
|
||||
|
||||
}
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
*
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $Header: /cvsroot/pgsql/src/backend/executor/nodeHashjoin.c,v 1.10 1998/02/13 03:26:47 vadim Exp $
|
||||
* $Header: /cvsroot/pgsql/src/backend/executor/nodeHashjoin.c,v 1.11 1998/02/26 04:31:26 momjian Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
|
@ -156,7 +156,7 @@ ExecHashJoin(HashJoin *node)
|
|||
}
|
||||
else if (hashtable == NULL)
|
||||
return (NULL);
|
||||
|
||||
|
||||
nbatch = hashtable->nbatch;
|
||||
outerbatches = hjstate->hj_OuterBatches;
|
||||
if (nbatch > 0 && outerbatches == NULL)
|
||||
|
@ -212,12 +212,14 @@ ExecHashJoin(HashJoin *node)
|
|||
|
||||
while (curbatch <= nbatch && TupIsNull(outerTupleSlot))
|
||||
{
|
||||
|
||||
/*
|
||||
* if the current batch runs out, switch to new batch
|
||||
*/
|
||||
curbatch = ExecHashJoinNewBatch(hjstate);
|
||||
if (curbatch > nbatch)
|
||||
{
|
||||
|
||||
/*
|
||||
* when the last batch runs out, clean up
|
||||
*/
|
||||
|
@ -350,6 +352,7 @@ ExecHashJoin(HashJoin *node)
|
|||
curbatch = ExecHashJoinNewBatch(hjstate);
|
||||
if (curbatch > nbatch)
|
||||
{
|
||||
|
||||
/*
|
||||
* when the last batch runs out, clean up
|
||||
*/
|
||||
|
@ -806,7 +809,7 @@ ExecHashJoinGetBatch(int bucketno, HashJoinTable hashtable, int nbatch)
|
|||
* ----------------------------------------------------------------
|
||||
*/
|
||||
|
||||
char *
|
||||
char *
|
||||
ExecHashJoinSaveTuple(HeapTuple heapTuple,
|
||||
char *buffer,
|
||||
File file,
|
||||
|
@ -845,16 +848,16 @@ ExecHashJoinSaveTuple(HeapTuple heapTuple,
|
|||
void
|
||||
ExecReScanHashJoin(HashJoin *node, ExprContext *exprCtxt, Plan *parent)
|
||||
{
|
||||
HashJoinState *hjstate = node->hashjoinstate;
|
||||
HashJoinState *hjstate = node->hashjoinstate;
|
||||
|
||||
if (!node->hashdone)
|
||||
return;
|
||||
|
||||
|
||||
node->hashdone = false;
|
||||
|
||||
/*
|
||||
* Unfortunately, currently we have to destroy hashtable
|
||||
* in all cases...
|
||||
|
||||
/*
|
||||
* Unfortunately, currently we have to destroy hashtable in all
|
||||
* cases...
|
||||
*/
|
||||
if (hjstate->hj_HashTable)
|
||||
{
|
||||
|
@ -872,14 +875,14 @@ ExecReScanHashJoin(HashJoin *node, ExprContext *exprCtxt, Plan *parent)
|
|||
|
||||
hjstate->jstate.cs_OuterTupleSlot = (TupleTableSlot *) NULL;
|
||||
hjstate->jstate.cs_TupFromTlist = (bool) false;
|
||||
|
||||
/*
|
||||
* if chgParam of subnodes is not null then plans
|
||||
* will be re-scanned by first ExecProcNode.
|
||||
|
||||
/*
|
||||
* if chgParam of subnodes is not null then plans will be re-scanned
|
||||
* by first ExecProcNode.
|
||||
*/
|
||||
if (((Plan*) node)->lefttree->chgParam == NULL)
|
||||
ExecReScan (((Plan*) node)->lefttree, exprCtxt, (Plan *) node);
|
||||
if (((Plan*) node)->righttree->chgParam == NULL)
|
||||
ExecReScan (((Plan*) node)->righttree, exprCtxt, (Plan *) node);
|
||||
|
||||
if (((Plan *) node)->lefttree->chgParam == NULL)
|
||||
ExecReScan(((Plan *) node)->lefttree, exprCtxt, (Plan *) node);
|
||||
if (((Plan *) node)->righttree->chgParam == NULL)
|
||||
ExecReScan(((Plan *) node)->righttree, exprCtxt, (Plan *) node);
|
||||
|
||||
}
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
*
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $Header: /cvsroot/pgsql/src/backend/executor/nodeIndexscan.c,v 1.14 1998/02/13 03:26:49 vadim Exp $
|
||||
* $Header: /cvsroot/pgsql/src/backend/executor/nodeIndexscan.c,v 1.15 1998/02/26 04:31:26 momjian Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
|
@ -267,11 +267,11 @@ ExecIndexReScan(IndexScan *node, ExprContext *exprCtxt, Plan *parent)
|
|||
n_keys = numScanKeys[indexPtr];
|
||||
run_keys = (int *) runtimeKeyInfo[indexPtr];
|
||||
scan_keys = (ScanKey) scanKeys[indexPtr];
|
||||
|
||||
|
||||
/* it's possible in subselects */
|
||||
if (exprCtxt == NULL)
|
||||
exprCtxt = node->scan.scanstate->cstate.cs_ExprContext;
|
||||
|
||||
|
||||
for (j = 0; j < n_keys; j++)
|
||||
{
|
||||
|
||||
|
@ -488,7 +488,7 @@ ExecInitIndexScan(IndexScan *node, EState *estate, Plan *parent)
|
|||
HeapScanDesc currentScanDesc;
|
||||
ScanDirection direction;
|
||||
int baseid;
|
||||
|
||||
|
||||
List *execParam = NULL;
|
||||
|
||||
/* ----------------
|
||||
|
@ -711,22 +711,22 @@ ExecInitIndexScan(IndexScan *node, EState *estate, Plan *parent)
|
|||
* it identifies the value to place in our scan key.
|
||||
* ----------------
|
||||
*/
|
||||
|
||||
|
||||
/* Life was so easy before ... subselects */
|
||||
if ( ((Param *) leftop)->paramkind == PARAM_EXEC )
|
||||
if (((Param *) leftop)->paramkind == PARAM_EXEC)
|
||||
{
|
||||
have_runtime_keys = true;
|
||||
run_keys[j] = LEFT_OP;
|
||||
execParam = lappendi (execParam, ((Param*) leftop)->paramid);
|
||||
execParam = lappendi(execParam, ((Param *) leftop)->paramid);
|
||||
}
|
||||
else
|
||||
{
|
||||
scanvalue = ExecEvalParam((Param *) leftop,
|
||||
scanstate->cstate.cs_ExprContext,
|
||||
scanstate->cstate.cs_ExprContext,
|
||||
&isnull);
|
||||
if (isnull)
|
||||
flags |= SK_ISNULL;
|
||||
|
||||
|
||||
run_keys[j] = NO_OP;
|
||||
}
|
||||
}
|
||||
|
@ -804,22 +804,22 @@ ExecInitIndexScan(IndexScan *node, EState *estate, Plan *parent)
|
|||
* it identifies the value to place in our scan key.
|
||||
* ----------------
|
||||
*/
|
||||
|
||||
|
||||
/* Life was so easy before ... subselects */
|
||||
if ( ((Param *) rightop)->paramkind == PARAM_EXEC )
|
||||
if (((Param *) rightop)->paramkind == PARAM_EXEC)
|
||||
{
|
||||
have_runtime_keys = true;
|
||||
run_keys[j] = RIGHT_OP;
|
||||
execParam = lappendi (execParam, ((Param*) rightop)->paramid);
|
||||
execParam = lappendi(execParam, ((Param *) rightop)->paramid);
|
||||
}
|
||||
else
|
||||
{
|
||||
scanvalue = ExecEvalParam((Param *) rightop,
|
||||
scanstate->cstate.cs_ExprContext,
|
||||
scanstate->cstate.cs_ExprContext,
|
||||
&isnull);
|
||||
if (isnull)
|
||||
flags |= SK_ISNULL;
|
||||
|
||||
|
||||
run_keys[j] = NO_OP;
|
||||
}
|
||||
}
|
||||
|
@ -989,13 +989,13 @@ ExecInitIndexScan(IndexScan *node, EState *estate, Plan *parent)
|
|||
indexstate->iss_ScanDescs = scanDescs;
|
||||
|
||||
indexstate->cstate.cs_TupFromTlist = false;
|
||||
|
||||
/*
|
||||
* if there are some PARAM_EXEC in skankeys then
|
||||
* force index rescan on first scan.
|
||||
|
||||
/*
|
||||
* if there are some PARAM_EXEC in skankeys then force index rescan on
|
||||
* first scan.
|
||||
*/
|
||||
((Plan*) node)->chgParam = execParam;
|
||||
|
||||
((Plan *) node)->chgParam = execParam;
|
||||
|
||||
/* ----------------
|
||||
* all done.
|
||||
* ----------------
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
*
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $Header: /cvsroot/pgsql/src/backend/executor/nodeMaterial.c,v 1.12 1998/02/13 03:26:50 vadim Exp $
|
||||
* $Header: /cvsroot/pgsql/src/backend/executor/nodeMaterial.c,v 1.13 1998/02/26 04:31:28 momjian Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
|
@ -350,16 +350,16 @@ ExecEndMaterial(Material *node)
|
|||
void
|
||||
ExecMaterialReScan(Material *node, ExprContext *exprCtxt, Plan *parent)
|
||||
{
|
||||
MaterialState *matstate = node->matstate;
|
||||
MaterialState *matstate = node->matstate;
|
||||
|
||||
if (matstate->mat_Flag == false)
|
||||
return;
|
||||
|
||||
matstate->csstate.css_currentScanDesc =
|
||||
ExecReScanR (matstate->csstate.css_currentRelation,
|
||||
matstate->csstate.css_currentScanDesc,
|
||||
node->plan.state->es_direction, 0, NULL);
|
||||
|
||||
|
||||
matstate->csstate.css_currentScanDesc =
|
||||
ExecReScanR(matstate->csstate.css_currentRelation,
|
||||
matstate->csstate.css_currentScanDesc,
|
||||
node->plan.state->es_direction, 0, NULL);
|
||||
|
||||
}
|
||||
|
||||
#ifdef NOT_USED /* not used */
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
*
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $Header: /cvsroot/pgsql/src/backend/executor/nodeMergejoin.c,v 1.12 1997/09/08 21:43:15 momjian Exp $
|
||||
* $Header: /cvsroot/pgsql/src/backend/executor/nodeMergejoin.c,v 1.13 1998/02/26 04:31:30 momjian Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
|
@ -749,7 +749,8 @@ ExecMergeJoin(MergeJoin *node)
|
|||
*
|
||||
* new outer tuple > marked tuple
|
||||
*
|
||||
*****************************
|
||||
****************************
|
||||
*
|
||||
*
|
||||
*
|
||||
*
|
||||
|
@ -831,7 +832,8 @@ ExecMergeJoin(MergeJoin *node)
|
|||
* we have to advance the outer scan until we find the outer
|
||||
* 8.
|
||||
*
|
||||
*****************************
|
||||
****************************
|
||||
*
|
||||
*
|
||||
*
|
||||
*
|
||||
|
@ -935,7 +937,8 @@ ExecMergeJoin(MergeJoin *node)
|
|||
* we have to advance the inner scan until we find the inner
|
||||
* 12.
|
||||
*
|
||||
*****************************
|
||||
****************************
|
||||
*
|
||||
*
|
||||
*
|
||||
*
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
*
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $Header: /cvsroot/pgsql/src/backend/executor/nodeNestloop.c,v 1.8 1998/02/13 03:26:51 vadim Exp $
|
||||
* $Header: /cvsroot/pgsql/src/backend/executor/nodeNestloop.c,v 1.9 1998/02/26 04:31:31 momjian Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
|
@ -380,18 +380,18 @@ ExecEndNestLoop(NestLoop *node)
|
|||
void
|
||||
ExecReScanNestLoop(NestLoop *node, ExprContext *exprCtxt, Plan *parent)
|
||||
{
|
||||
NestLoopState *nlstate = node->nlstate;
|
||||
Plan *outerPlan = outerPlan((Plan*) node);
|
||||
NestLoopState *nlstate = node->nlstate;
|
||||
Plan *outerPlan = outerPlan((Plan *) node);
|
||||
|
||||
/*
|
||||
* If outerPlan->chgParam is not null then plan will be
|
||||
* automatically re-scanned by first ExecProcNode.
|
||||
* innerPlan is re-scanned for each new outer tuple and MUST NOT
|
||||
* be re-scanned from here or you'll get troubles from inner
|
||||
* index scans when outer Vars are used as run-time keys...
|
||||
* If outerPlan->chgParam is not null then plan will be automatically
|
||||
* re-scanned by first ExecProcNode. innerPlan is re-scanned for each
|
||||
* new outer tuple and MUST NOT be re-scanned from here or you'll get
|
||||
* troubles from inner index scans when outer Vars are used as
|
||||
* run-time keys...
|
||||
*/
|
||||
if (outerPlan->chgParam == NULL)
|
||||
ExecReScan (outerPlan, exprCtxt, (Plan *) node);
|
||||
ExecReScan(outerPlan, exprCtxt, (Plan *) node);
|
||||
|
||||
/* let outerPlan to free its result typle ... */
|
||||
nlstate->jstate.cs_OuterTupleSlot = NULL;
|
||||
|
|
|
@ -27,7 +27,7 @@
|
|||
* SeqScan (emp.all)
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $Header: /cvsroot/pgsql/src/backend/executor/nodeResult.c,v 1.7 1998/02/18 07:19:34 thomas Exp $
|
||||
* $Header: /cvsroot/pgsql/src/backend/executor/nodeResult.c,v 1.8 1998/02/26 04:31:31 momjian Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
|
@ -79,8 +79,8 @@ ExecResult(Result *node)
|
|||
*/
|
||||
if (resstate->rs_checkqual)
|
||||
{
|
||||
bool qualResult = ExecQual((List *) node->resconstantqual, econtext);
|
||||
|
||||
bool qualResult = ExecQual((List *) node->resconstantqual, econtext);
|
||||
|
||||
resstate->rs_checkqual = false;
|
||||
if (qualResult == false)
|
||||
{
|
||||
|
@ -195,7 +195,7 @@ ExecInitResult(Result *node, EState *estate, Plan *parent)
|
|||
resstate->rs_done = false;
|
||||
resstate->rs_checkqual = (node->resconstantqual == NULL) ? false : true;
|
||||
node->resstate = resstate;
|
||||
|
||||
|
||||
/* ----------------
|
||||
* Miscellanious initialization
|
||||
*
|
||||
|
@ -281,18 +281,18 @@ ExecEndResult(Result *node)
|
|||
void
|
||||
ExecReScanResult(Result *node, ExprContext *exprCtxt, Plan *parent)
|
||||
{
|
||||
ResultState *resstate = node->resstate;
|
||||
ResultState *resstate = node->resstate;
|
||||
|
||||
resstate->rs_done = false;
|
||||
resstate->cstate.cs_TupFromTlist = false;
|
||||
resstate->rs_checkqual = (node->resconstantqual == NULL) ? false : true;
|
||||
|
||||
/*
|
||||
* if chgParam of subnode is not null then plan
|
||||
* will be re-scanned by first ExecProcNode.
|
||||
|
||||
/*
|
||||
* if chgParam of subnode is not null then plan will be re-scanned by
|
||||
* first ExecProcNode.
|
||||
*/
|
||||
if (((Plan*) node)->lefttree &&
|
||||
((Plan*) node)->lefttree->chgParam == NULL)
|
||||
ExecReScan (((Plan*) node)->lefttree, exprCtxt, (Plan *) node);
|
||||
|
||||
if (((Plan *) node)->lefttree &&
|
||||
((Plan *) node)->lefttree->chgParam == NULL)
|
||||
ExecReScan(((Plan *) node)->lefttree, exprCtxt, (Plan *) node);
|
||||
|
||||
}
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
*
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $Header: /cvsroot/pgsql/src/backend/executor/nodeSort.c,v 1.13 1998/02/23 06:26:56 vadim Exp $
|
||||
* $Header: /cvsroot/pgsql/src/backend/executor/nodeSort.c,v 1.14 1998/02/26 04:31:32 momjian Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
|
@ -112,7 +112,7 @@ ExecSort(Sort *node)
|
|||
ScanKey sortkeys;
|
||||
HeapTuple heapTuple;
|
||||
TupleTableSlot *slot;
|
||||
bool should_free;
|
||||
bool should_free;
|
||||
|
||||
/* ----------------
|
||||
* get state info from node
|
||||
|
@ -395,21 +395,21 @@ ExecReScanSort(Sort *node, ExprContext *exprCtxt, Plan *parent)
|
|||
SortState *sortstate = node->sortstate;
|
||||
|
||||
/*
|
||||
* If we haven't sorted yet, just return. If outerplan'
|
||||
* chgParam is not NULL then it will be re-scanned by
|
||||
* ExecProcNode, else - no reason to re-scan it at all.
|
||||
* If we haven't sorted yet, just return. If outerplan' chgParam is
|
||||
* not NULL then it will be re-scanned by ExecProcNode, else - no
|
||||
* reason to re-scan it at all.
|
||||
*/
|
||||
if (sortstate->sort_Flag == false)
|
||||
return;
|
||||
|
||||
|
||||
ExecClearTuple(sortstate->csstate.cstate.cs_ResultTupleSlot);
|
||||
|
||||
psort_rescan (node);
|
||||
|
||||
|
||||
psort_rescan(node);
|
||||
|
||||
/*
|
||||
* If subnode is to be rescanned then we aren't sorted
|
||||
*/
|
||||
if (((Plan*) node)->lefttree->chgParam != NULL)
|
||||
if (((Plan *) node)->lefttree->chgParam != NULL)
|
||||
sortstate->sort_Flag = false;
|
||||
|
||||
}
|
||||
|
|
|
@ -7,9 +7,9 @@
|
|||
*/
|
||||
/*
|
||||
* INTERFACE ROUTINES
|
||||
* ExecSubPlan - process a subselect
|
||||
* ExecSubPlan - process a subselect
|
||||
* ExecInitSubPlan - initialize a subselect
|
||||
* ExecEndSubPlan - shut down a subselect
|
||||
* ExecEndSubPlan - shut down a subselect
|
||||
*/
|
||||
#include "postgres.h"
|
||||
|
||||
|
@ -27,77 +27,77 @@
|
|||
Datum
|
||||
ExecSubPlan(SubPlan *node, List *pvar, ExprContext *econtext)
|
||||
{
|
||||
Plan *plan = node->plan;
|
||||
SubLink *sublink = node->sublink;
|
||||
Plan *plan = node->plan;
|
||||
SubLink *sublink = node->sublink;
|
||||
TupleTableSlot *slot;
|
||||
List *lst;
|
||||
bool result = false;
|
||||
bool found = false;
|
||||
|
||||
if ( node->setParam != NULL )
|
||||
elog (ERROR, "ExecSubPlan: can't set parent params from subquery");
|
||||
|
||||
List *lst;
|
||||
bool result = false;
|
||||
bool found = false;
|
||||
|
||||
if (node->setParam != NULL)
|
||||
elog(ERROR, "ExecSubPlan: can't set parent params from subquery");
|
||||
|
||||
/*
|
||||
* Set Params of this plan from parent plan correlation Vars
|
||||
*/
|
||||
if ( node->parParam != NULL )
|
||||
if (node->parParam != NULL)
|
||||
{
|
||||
foreach (lst, node->parParam)
|
||||
foreach(lst, node->parParam)
|
||||
{
|
||||
ParamExecData *prm = &(econtext->ecxt_param_exec_vals[lfirsti(lst)]);
|
||||
|
||||
prm->value = ExecEvalExpr ((Node*) lfirst(pvar),
|
||||
econtext,
|
||||
&(prm->isnull), NULL);
|
||||
pvar = lnext (pvar);
|
||||
ParamExecData *prm = &(econtext->ecxt_param_exec_vals[lfirsti(lst)]);
|
||||
|
||||
prm->value = ExecEvalExpr((Node *) lfirst(pvar),
|
||||
econtext,
|
||||
&(prm->isnull), NULL);
|
||||
pvar = lnext(pvar);
|
||||
}
|
||||
plan->chgParam = nconc (plan->chgParam, listCopy(node->parParam));
|
||||
plan->chgParam = nconc(plan->chgParam, listCopy(node->parParam));
|
||||
}
|
||||
|
||||
ExecReScan (plan, (ExprContext*) NULL, plan);
|
||||
|
||||
for (slot = ExecProcNode (plan, plan);
|
||||
!TupIsNull(slot);
|
||||
slot = ExecProcNode (plan, plan))
|
||||
|
||||
ExecReScan(plan, (ExprContext *) NULL, plan);
|
||||
|
||||
for (slot = ExecProcNode(plan, plan);
|
||||
!TupIsNull(slot);
|
||||
slot = ExecProcNode(plan, plan))
|
||||
{
|
||||
HeapTuple tup = slot->val;
|
||||
TupleDesc tdesc = slot->ttc_tupleDescriptor;
|
||||
int i = 1;
|
||||
|
||||
if ( sublink->subLinkType == EXPR_SUBLINK && found )
|
||||
|
||||
if (sublink->subLinkType == EXPR_SUBLINK && found)
|
||||
{
|
||||
elog (ERROR, "ExecSubPlan: more than one tuple returned by expression subselect");
|
||||
elog(ERROR, "ExecSubPlan: more than one tuple returned by expression subselect");
|
||||
return ((Datum) false);
|
||||
}
|
||||
|
||||
if ( sublink->subLinkType == EXISTS_SUBLINK )
|
||||
|
||||
if (sublink->subLinkType == EXISTS_SUBLINK)
|
||||
return ((Datum) true);
|
||||
|
||||
|
||||
found = true;
|
||||
|
||||
foreach (lst, sublink->oper)
|
||||
|
||||
foreach(lst, sublink->oper)
|
||||
{
|
||||
Expr *expr = (Expr*) lfirst(lst);
|
||||
Const *con = lsecond(expr->args);
|
||||
bool isnull;
|
||||
|
||||
con->constvalue = heap_getattr (tup, i, tdesc, &(con->constisnull));
|
||||
result = (bool) ExecEvalExpr ((Node*) expr, econtext, &isnull, (bool*) NULL);
|
||||
if ( isnull )
|
||||
Expr *expr = (Expr *) lfirst(lst);
|
||||
Const *con = lsecond(expr->args);
|
||||
bool isnull;
|
||||
|
||||
con->constvalue = heap_getattr(tup, i, tdesc, &(con->constisnull));
|
||||
result = (bool) ExecEvalExpr((Node *) expr, econtext, &isnull, (bool *) NULL);
|
||||
if (isnull)
|
||||
result = false;
|
||||
if ( (!result && !(sublink->useor)) || (result && sublink->useor) )
|
||||
if ((!result && !(sublink->useor)) || (result && sublink->useor))
|
||||
break;
|
||||
i++;
|
||||
}
|
||||
|
||||
if ( (!result && sublink->subLinkType == ALL_SUBLINK) ||
|
||||
(result && sublink->subLinkType == ANY_SUBLINK) )
|
||||
|
||||
if ((!result && sublink->subLinkType == ALL_SUBLINK) ||
|
||||
(result && sublink->subLinkType == ANY_SUBLINK))
|
||||
break;
|
||||
}
|
||||
|
||||
if ( !found && sublink->subLinkType == ALL_SUBLINK )
|
||||
|
||||
if (!found && sublink->subLinkType == ALL_SUBLINK)
|
||||
return ((Datum) true);
|
||||
|
||||
|
||||
return ((Datum) result);
|
||||
}
|
||||
|
||||
|
@ -109,42 +109,43 @@ ExecSubPlan(SubPlan *node, List *pvar, ExprContext *econtext)
|
|||
bool
|
||||
ExecInitSubPlan(SubPlan *node, EState *estate, Plan *parent)
|
||||
{
|
||||
EState *sp_estate = CreateExecutorState ();
|
||||
|
||||
EState *sp_estate = CreateExecutorState();
|
||||
|
||||
sp_estate->es_range_table = node->rtable;
|
||||
sp_estate->es_param_list_info = estate->es_param_list_info;
|
||||
sp_estate->es_param_exec_vals = estate->es_param_exec_vals;
|
||||
sp_estate->es_tupleTable =
|
||||
ExecCreateTupleTable (ExecCountSlotsNode(node->plan) + 10);
|
||||
pfree (sp_estate->es_refcount);
|
||||
sp_estate->es_tupleTable =
|
||||
ExecCreateTupleTable(ExecCountSlotsNode(node->plan) + 10);
|
||||
pfree(sp_estate->es_refcount);
|
||||
sp_estate->es_refcount = estate->es_refcount;
|
||||
|
||||
if ( !ExecInitNode (node->plan, sp_estate, NULL) )
|
||||
|
||||
if (!ExecInitNode(node->plan, sp_estate, NULL))
|
||||
return (false);
|
||||
|
||||
|
||||
node->shutdown = true;
|
||||
|
||||
|
||||
/*
|
||||
* If this plan is un-correlated or undirect correlated one and
|
||||
* want to set params for parent plan then prepare parameters.
|
||||
* If this plan is un-correlated or undirect correlated one and want
|
||||
* to set params for parent plan then prepare parameters.
|
||||
*/
|
||||
if ( node->setParam != NULL )
|
||||
if (node->setParam != NULL)
|
||||
{
|
||||
List *lst;
|
||||
|
||||
foreach (lst, node->setParam)
|
||||
List *lst;
|
||||
|
||||
foreach(lst, node->setParam)
|
||||
{
|
||||
ParamExecData *prm = &(estate->es_param_exec_vals[lfirsti(lst)]);
|
||||
|
||||
ParamExecData *prm = &(estate->es_param_exec_vals[lfirsti(lst)]);
|
||||
|
||||
prm->execPlan = node;
|
||||
}
|
||||
|
||||
/*
|
||||
* Note that in the case of un-correlated subqueries we don't care
|
||||
* about setting parent->chgParam here: indices take care about it,
|
||||
* for others - it doesn't matter...
|
||||
* about setting parent->chgParam here: indices take care about
|
||||
* it, for others - it doesn't matter...
|
||||
*/
|
||||
}
|
||||
|
||||
|
||||
return (true);
|
||||
}
|
||||
|
||||
|
@ -155,92 +156,92 @@ ExecInitSubPlan(SubPlan *node, EState *estate, Plan *parent)
|
|||
* ----------------------------------------------------------------
|
||||
*/
|
||||
void
|
||||
ExecSetParamPlan (SubPlan *node)
|
||||
ExecSetParamPlan(SubPlan *node)
|
||||
{
|
||||
Plan *plan = node->plan;
|
||||
SubLink *sublink = node->sublink;
|
||||
Plan *plan = node->plan;
|
||||
SubLink *sublink = node->sublink;
|
||||
TupleTableSlot *slot;
|
||||
List *lst;
|
||||
bool found = false;
|
||||
|
||||
if ( sublink->subLinkType == ANY_SUBLINK ||
|
||||
sublink->subLinkType == ALL_SUBLINK )
|
||||
elog (ERROR, "ExecSetParamPlan: ANY/ALL subselect unsupported");
|
||||
|
||||
if ( plan->chgParam != NULL )
|
||||
ExecReScan (plan, (ExprContext*) NULL, plan);
|
||||
|
||||
for (slot = ExecProcNode (plan, plan);
|
||||
!TupIsNull(slot);
|
||||
slot = ExecProcNode (plan, plan))
|
||||
List *lst;
|
||||
bool found = false;
|
||||
|
||||
if (sublink->subLinkType == ANY_SUBLINK ||
|
||||
sublink->subLinkType == ALL_SUBLINK)
|
||||
elog(ERROR, "ExecSetParamPlan: ANY/ALL subselect unsupported");
|
||||
|
||||
if (plan->chgParam != NULL)
|
||||
ExecReScan(plan, (ExprContext *) NULL, plan);
|
||||
|
||||
for (slot = ExecProcNode(plan, plan);
|
||||
!TupIsNull(slot);
|
||||
slot = ExecProcNode(plan, plan))
|
||||
{
|
||||
HeapTuple tup = slot->val;
|
||||
TupleDesc tdesc = slot->ttc_tupleDescriptor;
|
||||
int i = 1;
|
||||
|
||||
if ( sublink->subLinkType == EXPR_SUBLINK && found )
|
||||
|
||||
if (sublink->subLinkType == EXPR_SUBLINK && found)
|
||||
{
|
||||
elog (ERROR, "ExecSetParamPlan: more than one tuple returned by expression subselect");
|
||||
elog(ERROR, "ExecSetParamPlan: more than one tuple returned by expression subselect");
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
found = true;
|
||||
|
||||
if ( sublink->subLinkType == EXISTS_SUBLINK )
|
||||
|
||||
if (sublink->subLinkType == EXISTS_SUBLINK)
|
||||
{
|
||||
ParamExecData *prm = &(plan->state->es_param_exec_vals[lfirsti(node->setParam)]);
|
||||
|
||||
ParamExecData *prm = &(plan->state->es_param_exec_vals[lfirsti(node->setParam)]);
|
||||
|
||||
prm->execPlan = NULL;
|
||||
prm->value = (Datum) true;
|
||||
prm->isnull = false;
|
||||
break;
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
/*
|
||||
* If this is uncorrelated subquery then its plan will be closed
|
||||
* (see below) and this tuple will be free-ed - bad for not byval
|
||||
* types... But is free-ing possible in the next ExecProcNode in
|
||||
* this loop ? Who knows... Someday we'll keep track of saved
|
||||
* this loop ? Who knows... Someday we'll keep track of saved
|
||||
* tuples...
|
||||
*/
|
||||
tup = heap_copytuple (tup);
|
||||
|
||||
foreach (lst, node->setParam)
|
||||
tup = heap_copytuple(tup);
|
||||
|
||||
foreach(lst, node->setParam)
|
||||
{
|
||||
ParamExecData *prm = &(plan->state->es_param_exec_vals[lfirsti(lst)]);
|
||||
|
||||
ParamExecData *prm = &(plan->state->es_param_exec_vals[lfirsti(lst)]);
|
||||
|
||||
prm->execPlan = NULL;
|
||||
prm->value = heap_getattr (tup, i, tdesc, &(prm->isnull));
|
||||
prm->value = heap_getattr(tup, i, tdesc, &(prm->isnull));
|
||||
i++;
|
||||
}
|
||||
}
|
||||
|
||||
if ( !found )
|
||||
|
||||
if (!found)
|
||||
{
|
||||
if ( sublink->subLinkType == EXISTS_SUBLINK )
|
||||
if (sublink->subLinkType == EXISTS_SUBLINK)
|
||||
{
|
||||
ParamExecData *prm = &(plan->state->es_param_exec_vals[lfirsti(node->setParam)]);
|
||||
|
||||
ParamExecData *prm = &(plan->state->es_param_exec_vals[lfirsti(node->setParam)]);
|
||||
|
||||
prm->execPlan = NULL;
|
||||
prm->value = (Datum) false;
|
||||
prm->isnull = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
foreach (lst, node->setParam)
|
||||
foreach(lst, node->setParam)
|
||||
{
|
||||
ParamExecData *prm = &(plan->state->es_param_exec_vals[lfirsti(lst)]);
|
||||
|
||||
ParamExecData *prm = &(plan->state->es_param_exec_vals[lfirsti(lst)]);
|
||||
|
||||
prm->execPlan = NULL;
|
||||
prm->value = (Datum) NULL;
|
||||
prm->isnull = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ( plan->extParam == NULL ) /* un-correlated ... */
|
||||
|
||||
if (plan->extParam == NULL) /* un-correlated ... */
|
||||
{
|
||||
ExecEndNode (plan, plan);
|
||||
ExecEndNode(plan, plan);
|
||||
node->shutdown = false;
|
||||
}
|
||||
}
|
||||
|
@ -252,41 +253,40 @@ ExecSetParamPlan (SubPlan *node)
|
|||
void
|
||||
ExecEndSubPlan(SubPlan *node)
|
||||
{
|
||||
|
||||
if ( node->shutdown )
|
||||
|
||||
if (node->shutdown)
|
||||
{
|
||||
ExecEndNode (node->plan, node->plan);
|
||||
ExecEndNode(node->plan, node->plan);
|
||||
node->shutdown = false;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
void
|
||||
ExecReScanSetParamPlan (SubPlan *node, Plan *parent)
|
||||
void
|
||||
ExecReScanSetParamPlan(SubPlan *node, Plan *parent)
|
||||
{
|
||||
Plan *plan = node->plan;
|
||||
List *lst;
|
||||
|
||||
if ( node->parParam != NULL )
|
||||
elog (ERROR, "ExecReScanSetParamPlan: direct correlated subquery unsupported, yet");
|
||||
if ( node->setParam == NULL )
|
||||
elog (ERROR, "ExecReScanSetParamPlan: setParam list is NULL");
|
||||
if ( plan->extParam == NULL )
|
||||
elog (ERROR, "ExecReScanSetParamPlan: extParam list of plan is NULL");
|
||||
|
||||
/*
|
||||
* Don't actual re-scan: ExecSetParamPlan does re-scan if
|
||||
* node->plan->chgParam is not NULL...
|
||||
ExecReScan (plan, NULL, plan);
|
||||
Plan *plan = node->plan;
|
||||
List *lst;
|
||||
|
||||
if (node->parParam != NULL)
|
||||
elog(ERROR, "ExecReScanSetParamPlan: direct correlated subquery unsupported, yet");
|
||||
if (node->setParam == NULL)
|
||||
elog(ERROR, "ExecReScanSetParamPlan: setParam list is NULL");
|
||||
if (plan->extParam == NULL)
|
||||
elog(ERROR, "ExecReScanSetParamPlan: extParam list of plan is NULL");
|
||||
|
||||
/*
|
||||
* Don't actual re-scan: ExecSetParamPlan does re-scan if
|
||||
* node->plan->chgParam is not NULL... ExecReScan (plan, NULL, plan);
|
||||
*/
|
||||
|
||||
foreach (lst, node->setParam)
|
||||
|
||||
foreach(lst, node->setParam)
|
||||
{
|
||||
ParamExecData *prm = &(plan->state->es_param_exec_vals[lfirsti(lst)]);
|
||||
|
||||
ParamExecData *prm = &(plan->state->es_param_exec_vals[lfirsti(lst)]);
|
||||
|
||||
prm->execPlan = node;
|
||||
}
|
||||
|
||||
parent->chgParam = nconc (parent->chgParam, listCopy(node->setParam));
|
||||
|
||||
parent->chgParam = nconc(parent->chgParam, listCopy(node->setParam));
|
||||
|
||||
}
|
||||
|
|
|
@ -15,7 +15,7 @@
|
|||
* ExecEndTee
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $Header: /cvsroot/pgsql/src/backend/executor/Attic/nodeTee.c,v 1.15 1998/01/07 21:02:58 momjian Exp $
|
||||
* $Header: /cvsroot/pgsql/src/backend/executor/Attic/nodeTee.c,v 1.16 1998/02/26 04:31:33 momjian Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
|
@ -168,7 +168,7 @@ ExecInitTee(Tee *node, EState *currentEstate, Plan *parent)
|
|||
bufferRel = heap_openr(teeState->tee_bufferRelname);
|
||||
else
|
||||
bufferRel = heap_open(
|
||||
heap_create_with_catalog(teeState->tee_bufferRelname, tupType));
|
||||
heap_create_with_catalog(teeState->tee_bufferRelname, tupType));
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -177,7 +177,7 @@ ExecInitTee(Tee *node, EState *currentEstate, Plan *parent)
|
|||
newoid());
|
||||
/* bufferRel = ExecCreatR(len, tupType, _TEMP_RELATION_ID); */
|
||||
bufferRel = heap_open(
|
||||
heap_create_with_catalog(teeState->tee_bufferRelname, tupType));
|
||||
heap_create_with_catalog(teeState->tee_bufferRelname, tupType));
|
||||
}
|
||||
|
||||
teeState->tee_bufferRel = bufferRel;
|
||||
|
@ -246,7 +246,7 @@ initTeeScanDescs(Tee *node)
|
|||
{
|
||||
teeState->tee_leftScanDesc = heap_beginscan(bufferRel,
|
||||
ScanDirectionIsBackward(dir),
|
||||
false, /* seeself */
|
||||
false, /* seeself */
|
||||
0, /* num scan keys */
|
||||
NULL /* scan keys */
|
||||
);
|
||||
|
@ -255,7 +255,7 @@ initTeeScanDescs(Tee *node)
|
|||
{
|
||||
teeState->tee_rightScanDesc = heap_beginscan(bufferRel,
|
||||
ScanDirectionIsBackward(dir),
|
||||
false, /* seeself */
|
||||
false, /* seeself */
|
||||
0, /* num scan keys */
|
||||
NULL /* scan keys */
|
||||
);
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
*
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $Header: /cvsroot/pgsql/src/backend/executor/nodeUnique.c,v 1.16 1998/02/23 06:26:58 vadim Exp $
|
||||
* $Header: /cvsroot/pgsql/src/backend/executor/nodeUnique.c,v 1.17 1998/02/26 04:31:34 momjian Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
|
@ -187,7 +187,7 @@ ExecUnique(Unique *node)
|
|||
char *val1,
|
||||
*val2;
|
||||
|
||||
attr1 = heap_getattr(slot->val,
|
||||
attr1 = heap_getattr(slot->val,
|
||||
uniqueAttrNum, tupDesc, &isNull1);
|
||||
attr2 = heap_getattr(resultTupleSlot->val,
|
||||
uniqueAttrNum, tupDesc, &isNull2);
|
||||
|
@ -197,11 +197,11 @@ ExecUnique(Unique *node)
|
|||
if (isNull1) /* both are null, they are equal */
|
||||
continue;
|
||||
val1 = fmgr(typoutput, attr1,
|
||||
gettypelem(tupDesc->attrs[uniqueAttrNum - 1]->atttypid),
|
||||
tupDesc->attrs[uniqueAttrNum - 1]->atttypmod);
|
||||
gettypelem(tupDesc->attrs[uniqueAttrNum - 1]->atttypid),
|
||||
tupDesc->attrs[uniqueAttrNum - 1]->atttypmod);
|
||||
val2 = fmgr(typoutput, attr2,
|
||||
gettypelem(tupDesc->attrs[uniqueAttrNum - 1]->atttypid),
|
||||
tupDesc->attrs[uniqueAttrNum - 1]->atttypmod);
|
||||
gettypelem(tupDesc->attrs[uniqueAttrNum - 1]->atttypid),
|
||||
tupDesc->attrs[uniqueAttrNum - 1]->atttypmod);
|
||||
|
||||
/*
|
||||
* now, val1 and val2 are ascii representations so we can
|
||||
|
@ -209,12 +209,12 @@ ExecUnique(Unique *node)
|
|||
*/
|
||||
if (strcmp(val1, val2) == 0) /* they are equal */
|
||||
{
|
||||
pfree (val1);
|
||||
pfree (val2);
|
||||
pfree(val1);
|
||||
pfree(val2);
|
||||
continue;
|
||||
}
|
||||
pfree (val1);
|
||||
pfree (val2);
|
||||
pfree(val1);
|
||||
pfree(val2);
|
||||
break;
|
||||
}
|
||||
else
|
||||
|
@ -361,13 +361,14 @@ void
|
|||
ExecReScanUnique(Unique *node, ExprContext *exprCtxt, Plan *parent)
|
||||
{
|
||||
UniqueState *uniquestate = node->uniquestate;
|
||||
|
||||
|
||||
ExecClearTuple(uniquestate->cs_ResultTupleSlot);
|
||||
/*
|
||||
* if chgParam of subnode is not null then plan
|
||||
* will be re-scanned by first ExecProcNode.
|
||||
|
||||
/*
|
||||
* if chgParam of subnode is not null then plan will be re-scanned by
|
||||
* first ExecProcNode.
|
||||
*/
|
||||
if (((Plan*) node)->lefttree->chgParam == NULL)
|
||||
ExecReScan (((Plan*) node)->lefttree, exprCtxt, (Plan *) node);
|
||||
|
||||
if (((Plan *) node)->lefttree->chgParam == NULL)
|
||||
ExecReScan(((Plan *) node)->lefttree, exprCtxt, (Plan *) node);
|
||||
|
||||
}
|
||||
|
|
|
@ -18,7 +18,7 @@ typedef struct
|
|||
Portal portal; /* portal per procedure */
|
||||
MemoryContext savedcxt;
|
||||
CommandId savedId;
|
||||
} _SPI_connection;
|
||||
} _SPI_connection;
|
||||
|
||||
static Portal _SPI_portal = (Portal) NULL;
|
||||
static _SPI_connection *_SPI_stack = NULL;
|
||||
|
@ -38,24 +38,24 @@ typedef struct
|
|||
List *ptlist;
|
||||
int nargs;
|
||||
Oid *argtypes;
|
||||
} _SPI_plan;
|
||||
} _SPI_plan;
|
||||
|
||||
static int _SPI_execute(char *src, int tcount, _SPI_plan * plan);
|
||||
static int _SPI_pquery(QueryDesc * queryDesc, EState * state, int tcount);
|
||||
static int _SPI_execute(char *src, int tcount, _SPI_plan *plan);
|
||||
static int _SPI_pquery(QueryDesc *queryDesc, EState *state, int tcount);
|
||||
|
||||
#if 0
|
||||
static void _SPI_fetch(FetchStmt * stmt);
|
||||
static void _SPI_fetch(FetchStmt *stmt);
|
||||
|
||||
#endif
|
||||
static int
|
||||
_SPI_execute_plan(_SPI_plan * plan,
|
||||
Datum * Values, char *Nulls, int tcount);
|
||||
_SPI_execute_plan(_SPI_plan *plan,
|
||||
Datum *Values, char *Nulls, int tcount);
|
||||
|
||||
#define _SPI_CPLAN_CURCXT 0
|
||||
#define _SPI_CPLAN_PROCXT 1
|
||||
#define _SPI_CPLAN_TOPCXT 2
|
||||
|
||||
static _SPI_plan *_SPI_copy_plan(_SPI_plan * plan, int location);
|
||||
static _SPI_plan *_SPI_copy_plan(_SPI_plan *plan, int location);
|
||||
|
||||
static int _SPI_begin_call(bool execmem);
|
||||
static int _SPI_end_call(bool procmem);
|
||||
|
@ -202,7 +202,7 @@ SPI_exec(char *src, int tcount)
|
|||
}
|
||||
|
||||
int
|
||||
SPI_execp(void *plan, Datum * Values, char *Nulls, int tcount)
|
||||
SPI_execp(void *plan, Datum *Values, char *Nulls, int tcount)
|
||||
{
|
||||
int res;
|
||||
|
||||
|
@ -225,8 +225,8 @@ SPI_execp(void *plan, Datum * Values, char *Nulls, int tcount)
|
|||
return (res);
|
||||
}
|
||||
|
||||
void *
|
||||
SPI_prepare(char *src, int nargs, Oid * argtypes)
|
||||
void *
|
||||
SPI_prepare(char *src, int nargs, Oid *argtypes)
|
||||
{
|
||||
_SPI_plan *plan;
|
||||
|
||||
|
@ -257,7 +257,7 @@ SPI_prepare(char *src, int nargs, Oid * argtypes)
|
|||
|
||||
}
|
||||
|
||||
void *
|
||||
void *
|
||||
SPI_saveplan(void *plan)
|
||||
{
|
||||
_SPI_plan *newplan;
|
||||
|
@ -310,7 +310,7 @@ SPI_copytuple(HeapTuple tuple)
|
|||
|
||||
HeapTuple
|
||||
SPI_modifytuple(Relation rel, HeapTuple tuple, int natts, int *attnum,
|
||||
Datum * Values, char *Nulls)
|
||||
Datum *Values, char *Nulls)
|
||||
{
|
||||
MemoryContext oldcxt = NULL;
|
||||
HeapTuple mtuple;
|
||||
|
@ -392,7 +392,7 @@ SPI_fnumber(TupleDesc tupdesc, char *fname)
|
|||
return (SPI_ERROR_NOATTRIBUTE);
|
||||
}
|
||||
|
||||
char *
|
||||
char *
|
||||
SPI_fname(TupleDesc tupdesc, int fnumber)
|
||||
{
|
||||
|
||||
|
@ -406,7 +406,7 @@ SPI_fname(TupleDesc tupdesc, int fnumber)
|
|||
return (nameout(&(tupdesc->attrs[fnumber - 1]->attname)));
|
||||
}
|
||||
|
||||
char *
|
||||
char *
|
||||
SPI_getvalue(HeapTuple tuple, TupleDesc tupdesc, int fnumber)
|
||||
{
|
||||
Datum val;
|
||||
|
@ -431,12 +431,12 @@ SPI_getvalue(HeapTuple tuple, TupleDesc tupdesc, int fnumber)
|
|||
}
|
||||
|
||||
return (fmgr(foutoid, val,
|
||||
gettypelem(tupdesc->attrs[fnumber - 1]->atttypid),
|
||||
tupdesc->attrs[fnumber - 1]->atttypmod));
|
||||
gettypelem(tupdesc->attrs[fnumber - 1]->atttypid),
|
||||
tupdesc->attrs[fnumber - 1]->atttypmod));
|
||||
}
|
||||
|
||||
Datum
|
||||
SPI_getbinval(HeapTuple tuple, TupleDesc tupdesc, int fnumber, bool * isnull)
|
||||
SPI_getbinval(HeapTuple tuple, TupleDesc tupdesc, int fnumber, bool *isnull)
|
||||
{
|
||||
Datum val;
|
||||
|
||||
|
@ -453,7 +453,7 @@ SPI_getbinval(HeapTuple tuple, TupleDesc tupdesc, int fnumber, bool * isnull)
|
|||
return (val);
|
||||
}
|
||||
|
||||
char *
|
||||
char *
|
||||
SPI_gettype(TupleDesc tupdesc, int fnumber)
|
||||
{
|
||||
HeapTuple typeTuple;
|
||||
|
@ -492,70 +492,70 @@ SPI_gettypeid(TupleDesc tupdesc, int fnumber)
|
|||
return (tupdesc->attrs[fnumber - 1]->atttypid);
|
||||
}
|
||||
|
||||
char *
|
||||
char *
|
||||
SPI_getrelname(Relation rel)
|
||||
{
|
||||
return (pstrdup(rel->rd_rel->relname.data));
|
||||
}
|
||||
|
||||
void *
|
||||
SPI_palloc (Size size)
|
||||
SPI_palloc(Size size)
|
||||
{
|
||||
MemoryContext oldcxt = NULL;
|
||||
void *pointer;
|
||||
|
||||
MemoryContext oldcxt = NULL;
|
||||
void *pointer;
|
||||
|
||||
if (_SPI_curid + 1 == _SPI_connected) /* connected */
|
||||
{
|
||||
if (_SPI_current != &(_SPI_stack[_SPI_curid + 1]))
|
||||
elog(FATAL, "SPI: stack corrupted");
|
||||
oldcxt = MemoryContextSwitchTo(_SPI_current->savedcxt);
|
||||
}
|
||||
|
||||
pointer = palloc (size);
|
||||
|
||||
|
||||
pointer = palloc(size);
|
||||
|
||||
if (oldcxt)
|
||||
MemoryContextSwitchTo(oldcxt);
|
||||
|
||||
|
||||
return (pointer);
|
||||
}
|
||||
|
||||
void *
|
||||
SPI_repalloc (void *pointer, Size size)
|
||||
SPI_repalloc(void *pointer, Size size)
|
||||
{
|
||||
MemoryContext oldcxt = NULL;
|
||||
|
||||
MemoryContext oldcxt = NULL;
|
||||
|
||||
if (_SPI_curid + 1 == _SPI_connected) /* connected */
|
||||
{
|
||||
if (_SPI_current != &(_SPI_stack[_SPI_curid + 1]))
|
||||
elog(FATAL, "SPI: stack corrupted");
|
||||
oldcxt = MemoryContextSwitchTo(_SPI_current->savedcxt);
|
||||
}
|
||||
|
||||
pointer = repalloc (pointer, size);
|
||||
|
||||
|
||||
pointer = repalloc(pointer, size);
|
||||
|
||||
if (oldcxt)
|
||||
MemoryContextSwitchTo(oldcxt);
|
||||
|
||||
|
||||
return (pointer);
|
||||
}
|
||||
|
||||
void
|
||||
SPI_pfree (void *pointer)
|
||||
void
|
||||
SPI_pfree(void *pointer)
|
||||
{
|
||||
MemoryContext oldcxt = NULL;
|
||||
|
||||
MemoryContext oldcxt = NULL;
|
||||
|
||||
if (_SPI_curid + 1 == _SPI_connected) /* connected */
|
||||
{
|
||||
if (_SPI_current != &(_SPI_stack[_SPI_curid + 1]))
|
||||
elog(FATAL, "SPI: stack corrupted");
|
||||
oldcxt = MemoryContextSwitchTo(_SPI_current->savedcxt);
|
||||
}
|
||||
|
||||
pfree (pointer);
|
||||
|
||||
|
||||
pfree(pointer);
|
||||
|
||||
if (oldcxt)
|
||||
MemoryContextSwitchTo(oldcxt);
|
||||
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -613,7 +613,7 @@ spi_printtup(HeapTuple tuple, TupleDesc tupdesc)
|
|||
*/
|
||||
|
||||
static int
|
||||
_SPI_execute(char *src, int tcount, _SPI_plan * plan)
|
||||
_SPI_execute(char *src, int tcount, _SPI_plan *plan)
|
||||
{
|
||||
QueryTreeList *queryTree_list;
|
||||
List *planTree_list;
|
||||
|
@ -710,7 +710,7 @@ _SPI_execute(char *src, int tcount, _SPI_plan * plan)
|
|||
}
|
||||
|
||||
static int
|
||||
_SPI_execute_plan(_SPI_plan * plan, Datum * Values, char *Nulls, int tcount)
|
||||
_SPI_execute_plan(_SPI_plan *plan, Datum *Values, char *Nulls, int tcount)
|
||||
{
|
||||
QueryTreeList *queryTree_list = plan->qtlist;
|
||||
List *planTree_list = plan->ptlist;
|
||||
|
@ -781,12 +781,12 @@ _SPI_execute_plan(_SPI_plan * plan, Datum * Values, char *Nulls, int tcount)
|
|||
}
|
||||
|
||||
static int
|
||||
_SPI_pquery(QueryDesc * queryDesc, EState * state, int tcount)
|
||||
_SPI_pquery(QueryDesc *queryDesc, EState *state, int tcount)
|
||||
{
|
||||
Query *parseTree = queryDesc->parsetree;
|
||||
Plan *plan = queryDesc->plantree;
|
||||
int operation = queryDesc->operation;
|
||||
CommandDest dest = queryDesc->dest;
|
||||
CommandDest dest = queryDesc->dest;
|
||||
TupleDesc tupdesc;
|
||||
bool isRetrieveIntoPortal = false;
|
||||
bool isRetrieveIntoRelation = false;
|
||||
|
@ -810,7 +810,7 @@ _SPI_pquery(QueryDesc * queryDesc, EState * state, int tcount)
|
|||
{
|
||||
res = SPI_OK_SELINTO;
|
||||
isRetrieveIntoRelation = true;
|
||||
queryDesc->dest = None; /* */
|
||||
queryDesc->dest = None; /* */
|
||||
}
|
||||
break;
|
||||
case CMD_INSERT:
|
||||
|
@ -878,7 +878,7 @@ _SPI_pquery(QueryDesc * queryDesc, EState * state, int tcount)
|
|||
|
||||
#if 0
|
||||
static void
|
||||
_SPI_fetch(FetchStmt * stmt)
|
||||
_SPI_fetch(FetchStmt *stmt)
|
||||
{
|
||||
char *name = stmt->portalname;
|
||||
int feature = (stmt->direction == FORWARD) ? EXEC_FOR : EXEC_BACK;
|
||||
|
@ -1001,7 +1001,8 @@ _SPI_checktuples()
|
|||
if (tuptable != NULL)
|
||||
failed = true;
|
||||
}
|
||||
else /* some tuples were processed */
|
||||
else
|
||||
/* some tuples were processed */
|
||||
{
|
||||
if (tuptable == NULL) /* spi_printtup was not called */
|
||||
failed = true;
|
||||
|
@ -1013,7 +1014,7 @@ _SPI_checktuples()
|
|||
}
|
||||
|
||||
static _SPI_plan *
|
||||
_SPI_copy_plan(_SPI_plan * plan, int location)
|
||||
_SPI_copy_plan(_SPI_plan *plan, int location)
|
||||
{
|
||||
_SPI_plan *newplan;
|
||||
MemoryContext oldcxt = NULL;
|
||||
|
|
|
@ -9,7 +9,7 @@
|
|||
*
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $Header: /cvsroot/pgsql/src/backend/lib/dllist.c,v 1.8 1997/09/08 21:43:27 momjian Exp $
|
||||
* $Header: /cvsroot/pgsql/src/backend/lib/dllist.c,v 1.9 1998/02/26 04:31:37 momjian Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
|
@ -18,7 +18,7 @@
|
|||
|
||||
#include <lib/dllist.h>
|
||||
|
||||
Dllist *
|
||||
Dllist *
|
||||
DLNewList(void)
|
||||
{
|
||||
Dllist *l;
|
||||
|
@ -42,7 +42,7 @@ DLFreeList(Dllist *l)
|
|||
free(l);
|
||||
}
|
||||
|
||||
Dlelem *
|
||||
Dlelem *
|
||||
DLNewElem(void *val)
|
||||
{
|
||||
Dlelem *e;
|
||||
|
@ -61,7 +61,7 @@ DLFreeElem(Dlelem *e)
|
|||
free(e);
|
||||
}
|
||||
|
||||
Dlelem *
|
||||
Dlelem *
|
||||
DLGetHead(Dllist *l)
|
||||
{
|
||||
return (l ? l->dll_head : 0);
|
||||
|
@ -69,7 +69,7 @@ DLGetHead(Dllist *l)
|
|||
|
||||
/* get the value stored in the first element */
|
||||
#ifdef NOT_USED
|
||||
void *
|
||||
void *
|
||||
DLGetHeadVal(Dllist *l)
|
||||
{
|
||||
Dlelem *e = DLGetHead(l);
|
||||
|
@ -79,7 +79,7 @@ DLGetHeadVal(Dllist *l)
|
|||
|
||||
#endif
|
||||
|
||||
Dlelem *
|
||||
Dlelem *
|
||||
DLGetTail(Dllist *l)
|
||||
{
|
||||
return (l ? l->dll_tail : 0);
|
||||
|
@ -87,7 +87,7 @@ DLGetTail(Dllist *l)
|
|||
|
||||
/* get the value stored in the first element */
|
||||
#ifdef NOT_USED
|
||||
void *
|
||||
void *
|
||||
DLGetTailVal(Dllist *l)
|
||||
{
|
||||
Dlelem *e = DLGetTail(l);
|
||||
|
@ -97,13 +97,13 @@ DLGetTailVal(Dllist *l)
|
|||
|
||||
#endif
|
||||
|
||||
Dlelem *
|
||||
Dlelem *
|
||||
DLGetPred(Dlelem *e) /* get predecessor */
|
||||
{
|
||||
return (e ? e->dle_prev : 0);
|
||||
}
|
||||
|
||||
Dlelem *
|
||||
Dlelem *
|
||||
DLGetSucc(Dlelem *e) /* get successor */
|
||||
{
|
||||
return (e ? e->dle_next : 0);
|
||||
|
@ -162,7 +162,7 @@ DLAddTail(Dllist *l, Dlelem *e)
|
|||
l->dll_head = l->dll_tail;
|
||||
}
|
||||
|
||||
Dlelem *
|
||||
Dlelem *
|
||||
DLRemHead(Dllist *l)
|
||||
{
|
||||
/* remove and return the head */
|
||||
|
@ -188,7 +188,7 @@ DLRemHead(Dllist *l)
|
|||
return result;
|
||||
}
|
||||
|
||||
Dlelem *
|
||||
Dlelem *
|
||||
DLRemTail(Dllist *l)
|
||||
{
|
||||
/* remove and return the tail */
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
*
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $Header: /cvsroot/pgsql/src/backend/lib/Attic/lispsort.c,v 1.7 1997/09/08 21:43:31 momjian Exp $
|
||||
* $Header: /cvsroot/pgsql/src/backend/lib/Attic/lispsort.c,v 1.8 1998/02/26 04:31:39 momjian Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
|
@ -29,7 +29,7 @@
|
|||
** as passed into lisp_qsort(), and returns a new list with
|
||||
** the nodes sorted. The old list is *not* freed or modified (?)
|
||||
*/
|
||||
List *
|
||||
List *
|
||||
lisp_qsort(List *the_list, /* the list to be sorted */
|
||||
int (*compare) ()) /* function to compare two nodes */
|
||||
{
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
*
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $Header: /cvsroot/pgsql/src/backend/lib/Attic/qsort.c,v 1.5 1998/02/11 19:10:35 momjian Exp $
|
||||
* $Header: /cvsroot/pgsql/src/backend/lib/Attic/qsort.c,v 1.6 1998/02/26 04:31:40 momjian Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
|
@ -129,13 +129,13 @@ pg_qsort(void *bot,
|
|||
static void
|
||||
quick_sort(char *bot, int nmemb, int size, int (*compar) ())
|
||||
{
|
||||
int cnt;
|
||||
u_char ch;
|
||||
char *top,
|
||||
int cnt;
|
||||
u_char ch;
|
||||
char *top,
|
||||
*mid,
|
||||
*t1,
|
||||
*t2;
|
||||
int n1,
|
||||
int n1,
|
||||
n2;
|
||||
char *bsv;
|
||||
|
||||
|
@ -277,9 +277,9 @@ swap: SWAP(bot, replace);
|
|||
static void
|
||||
insertion_sort(char *bot, int nmemb, int size, int (*compar) ())
|
||||
{
|
||||
int cnt;
|
||||
u_char ch;
|
||||
char *s1,
|
||||
int cnt;
|
||||
u_char ch;
|
||||
char *s1,
|
||||
*s2,
|
||||
*t1,
|
||||
*t2,
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
*
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $Header: /cvsroot/pgsql/src/backend/libpq/auth.c,v 1.26 1998/02/25 13:06:49 scrappy Exp $
|
||||
* $Header: /cvsroot/pgsql/src/backend/libpq/auth.c,v 1.27 1998/02/26 04:31:42 momjian Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
|
@ -40,16 +40,16 @@
|
|||
#include <libpq/crypt.h>
|
||||
|
||||
|
||||
static void sendAuthRequest(Port *port, AuthRequest areq, void (*handler)());
|
||||
static void sendAuthRequest(Port *port, AuthRequest areq, void (*handler) ());
|
||||
static void handle_done_auth(Port *port);
|
||||
static void handle_krb4_auth(Port *port);
|
||||
static void handle_krb5_auth(Port *port);
|
||||
static void handle_password_auth(Port *port);
|
||||
static void readPasswordPacket(char *arg, PacketLen len, char *pkt);
|
||||
static void pg_passwordv0_recvauth(char *arg, PacketLen len, char *pkt);
|
||||
static int checkPassword(Port *port, char *user, char *password);
|
||||
static int old_be_recvauth(Port *port);
|
||||
static int map_old_to_new(Port *port, UserAuth old, int status);
|
||||
static int checkPassword(Port *port, char *user, char *password);
|
||||
static int old_be_recvauth(Port *port);
|
||||
static int map_old_to_new(Port *port, UserAuth old, int status);
|
||||
|
||||
|
||||
#ifdef KRB4
|
||||
|
@ -327,14 +327,18 @@ pg_krb5_recvauth(Port *port)
|
|||
* Handle a v0 password packet.
|
||||
*/
|
||||
|
||||
static void pg_passwordv0_recvauth(char *arg, PacketLen len, char *pkt)
|
||||
static void
|
||||
pg_passwordv0_recvauth(char *arg, PacketLen len, char *pkt)
|
||||
{
|
||||
Port *port;
|
||||
Port *port;
|
||||
PasswordPacketV0 *pp;
|
||||
char *user, *password, *cp, *start;
|
||||
char *user,
|
||||
*password,
|
||||
*cp,
|
||||
*start;
|
||||
|
||||
port = (Port *)arg;
|
||||
pp = (PasswordPacketV0 *)pkt;
|
||||
port = (Port *) arg;
|
||||
pp = (PasswordPacketV0 *) pkt;
|
||||
|
||||
/*
|
||||
* The packet is supposed to comprise the user name and the password
|
||||
|
@ -343,7 +347,7 @@ static void pg_passwordv0_recvauth(char *arg, PacketLen len, char *pkt)
|
|||
|
||||
user = password = NULL;
|
||||
|
||||
len -= sizeof (pp->unused);
|
||||
len -= sizeof(pp->unused);
|
||||
|
||||
cp = start = pp->data;
|
||||
|
||||
|
@ -372,8 +376,8 @@ static void pg_passwordv0_recvauth(char *arg, PacketLen len, char *pkt)
|
|||
}
|
||||
else
|
||||
{
|
||||
int status;
|
||||
UserAuth saved;
|
||||
int status;
|
||||
UserAuth saved;
|
||||
|
||||
/* Check the password. */
|
||||
|
||||
|
@ -396,7 +400,8 @@ static void pg_passwordv0_recvauth(char *arg, PacketLen len, char *pkt)
|
|||
* Tell the user the authentication failed, but not why.
|
||||
*/
|
||||
|
||||
void auth_failed(Port *port)
|
||||
void
|
||||
auth_failed(Port *port)
|
||||
{
|
||||
PacketSendError(&port->pktInfo, "User authentication failed");
|
||||
}
|
||||
|
@ -405,15 +410,17 @@ void auth_failed(Port *port)
|
|||
/*
|
||||
* be_recvauth -- server demux routine for incoming authentication information
|
||||
*/
|
||||
void be_recvauth(Port *port)
|
||||
void
|
||||
be_recvauth(Port *port)
|
||||
{
|
||||
|
||||
/*
|
||||
* Get the authentication method to use for this frontend/database
|
||||
* combination.
|
||||
*/
|
||||
|
||||
if (hba_getauthmethod(&port->raddr, port->database, port->auth_arg,
|
||||
&port->auth_method) != STATUS_OK)
|
||||
&port->auth_method) != STATUS_OK)
|
||||
PacketSendError(&port->pktInfo, "Missing or mis-configured pg_hba.conf file");
|
||||
|
||||
else if (PG_PROTOCOL_MAJOR(port->proto) == 0)
|
||||
|
@ -426,7 +433,7 @@ void be_recvauth(Port *port)
|
|||
else
|
||||
{
|
||||
AuthRequest areq;
|
||||
void (*auth_handler)();
|
||||
void (*auth_handler) ();
|
||||
|
||||
/* Keep the compiler quiet. */
|
||||
|
||||
|
@ -438,44 +445,44 @@ void be_recvauth(Port *port)
|
|||
|
||||
switch (port->auth_method)
|
||||
{
|
||||
case uaReject:
|
||||
break;
|
||||
|
||||
case uaKrb4:
|
||||
areq = AUTH_REQ_KRB4;
|
||||
auth_handler = handle_krb4_auth;
|
||||
break;
|
||||
case uaReject:
|
||||
break;
|
||||
|
||||
case uaKrb5:
|
||||
areq = AUTH_REQ_KRB5;
|
||||
auth_handler = handle_krb5_auth;
|
||||
break;
|
||||
case uaKrb4:
|
||||
areq = AUTH_REQ_KRB4;
|
||||
auth_handler = handle_krb4_auth;
|
||||
break;
|
||||
|
||||
case uaTrust:
|
||||
areq = AUTH_REQ_OK;
|
||||
auth_handler = handle_done_auth;
|
||||
break;
|
||||
case uaKrb5:
|
||||
areq = AUTH_REQ_KRB5;
|
||||
auth_handler = handle_krb5_auth;
|
||||
break;
|
||||
|
||||
case uaIdent:
|
||||
if (authident(&port->raddr.in, &port->laddr.in,
|
||||
port->user, port->auth_arg) == STATUS_OK)
|
||||
{
|
||||
case uaTrust:
|
||||
areq = AUTH_REQ_OK;
|
||||
auth_handler = handle_done_auth;
|
||||
}
|
||||
break;
|
||||
|
||||
break;
|
||||
case uaIdent:
|
||||
if (authident(&port->raddr.in, &port->laddr.in,
|
||||
port->user, port->auth_arg) == STATUS_OK)
|
||||
{
|
||||
areq = AUTH_REQ_OK;
|
||||
auth_handler = handle_done_auth;
|
||||
}
|
||||
|
||||
case uaPassword:
|
||||
areq = AUTH_REQ_PASSWORD;
|
||||
auth_handler = handle_password_auth;
|
||||
break;
|
||||
break;
|
||||
|
||||
case uaCrypt:
|
||||
areq = AUTH_REQ_CRYPT;
|
||||
auth_handler = handle_password_auth;
|
||||
break;
|
||||
}
|
||||
case uaPassword:
|
||||
areq = AUTH_REQ_PASSWORD;
|
||||
auth_handler = handle_password_auth;
|
||||
break;
|
||||
|
||||
case uaCrypt:
|
||||
areq = AUTH_REQ_CRYPT;
|
||||
auth_handler = handle_password_auth;
|
||||
break;
|
||||
}
|
||||
|
||||
/* Tell the frontend what we want next. */
|
||||
|
||||
|
@ -485,24 +492,26 @@ void be_recvauth(Port *port)
|
|||
auth_failed(port);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* Send an authentication request packet to the frontend.
|
||||
*/
|
||||
|
||||
static void sendAuthRequest(Port *port, AuthRequest areq, void (*handler)())
|
||||
static void
|
||||
sendAuthRequest(Port *port, AuthRequest areq, void (*handler) ())
|
||||
{
|
||||
char *dp, *sp;
|
||||
int i;
|
||||
uint32 net_areq;
|
||||
char *dp,
|
||||
*sp;
|
||||
int i;
|
||||
uint32 net_areq;
|
||||
|
||||
/* Convert to a byte stream. */
|
||||
|
||||
net_areq = htonl(areq);
|
||||
|
||||
dp = port->pktInfo.pkt.ar.data;
|
||||
sp = (char *)&net_areq;
|
||||
sp = (char *) &net_areq;
|
||||
|
||||
*dp++ = 'R';
|
||||
|
||||
|
@ -518,7 +527,7 @@ static void sendAuthRequest(Port *port, AuthRequest areq, void (*handler)())
|
|||
i += 2;
|
||||
}
|
||||
|
||||
PacketSendSetup(&port -> pktInfo, i, handler, (char *)port);
|
||||
PacketSendSetup(&port->pktInfo, i, handler, (char *) port);
|
||||
}
|
||||
|
||||
|
||||
|
@ -526,8 +535,10 @@ static void sendAuthRequest(Port *port, AuthRequest areq, void (*handler)())
|
|||
* Called when we have told the front end that it is authorised.
|
||||
*/
|
||||
|
||||
static void handle_done_auth(Port *port)
|
||||
static void
|
||||
handle_done_auth(Port *port)
|
||||
{
|
||||
|
||||
/*
|
||||
* Don't generate any more traffic. This will cause the backend to
|
||||
* start.
|
||||
|
@ -542,7 +553,8 @@ static void handle_done_auth(Port *port)
|
|||
* authentication.
|
||||
*/
|
||||
|
||||
static void handle_krb4_auth(Port *port)
|
||||
static void
|
||||
handle_krb4_auth(Port *port)
|
||||
{
|
||||
if (pg_krb4_recvauth(port) != STATUS_OK)
|
||||
auth_failed(port);
|
||||
|
@ -556,7 +568,8 @@ static void handle_krb4_auth(Port *port)
|
|||
* authentication.
|
||||
*/
|
||||
|
||||
static void handle_krb5_auth(Port *port)
|
||||
static void
|
||||
handle_krb5_auth(Port *port)
|
||||
{
|
||||
if (pg_krb5_recvauth(port) != STATUS_OK)
|
||||
auth_failed(port);
|
||||
|
@ -570,11 +583,12 @@ static void handle_krb5_auth(Port *port)
|
|||
* authentication.
|
||||
*/
|
||||
|
||||
static void handle_password_auth(Port *port)
|
||||
static void
|
||||
handle_password_auth(Port *port)
|
||||
{
|
||||
/* Set up the read of the password packet. */
|
||||
|
||||
PacketReceiveSetup(&port->pktInfo, readPasswordPacket, (char *)port);
|
||||
PacketReceiveSetup(&port->pktInfo, readPasswordPacket, (char *) port);
|
||||
}
|
||||
|
||||
|
||||
|
@ -582,19 +596,20 @@ static void handle_password_auth(Port *port)
|
|||
* Called when we have received the password packet.
|
||||
*/
|
||||
|
||||
static void readPasswordPacket(char *arg, PacketLen len, char *pkt)
|
||||
static void
|
||||
readPasswordPacket(char *arg, PacketLen len, char *pkt)
|
||||
{
|
||||
char password[sizeof (PasswordPacket) + 1];
|
||||
Port *port;
|
||||
char password[sizeof(PasswordPacket) + 1];
|
||||
Port *port;
|
||||
|
||||
port = (Port *)arg;
|
||||
port = (Port *) arg;
|
||||
|
||||
/* Silently truncate a password that is too big. */
|
||||
|
||||
if (len > sizeof (PasswordPacket))
|
||||
len = sizeof (PasswordPacket);
|
||||
|
||||
StrNCpy(password, ((PasswordPacket *)pkt)->passwd, len);
|
||||
if (len > sizeof(PasswordPacket))
|
||||
len = sizeof(PasswordPacket);
|
||||
|
||||
StrNCpy(password, ((PasswordPacket *) pkt)->passwd, len);
|
||||
|
||||
if (checkPassword(port, port->user, password) != STATUS_OK)
|
||||
auth_failed(port);
|
||||
|
@ -609,7 +624,8 @@ static void readPasswordPacket(char *arg, PacketLen len, char *pkt)
|
|||
* not.
|
||||
*/
|
||||
|
||||
static int checkPassword(Port *port, char *user, char *password)
|
||||
static int
|
||||
checkPassword(Port *port, char *user, char *password)
|
||||
{
|
||||
if (port->auth_method == uaPassword && port->auth_arg[0] != '\0')
|
||||
return verify_password(port->auth_arg, user, password);
|
||||
|
@ -622,83 +638,85 @@ static int checkPassword(Port *port, char *user, char *password)
|
|||
* Server demux routine for incoming authentication information for protocol
|
||||
* version 0.
|
||||
*/
|
||||
static int old_be_recvauth(Port *port)
|
||||
static int
|
||||
old_be_recvauth(Port *port)
|
||||
{
|
||||
int status;
|
||||
MsgType msgtype = (MsgType)port->proto;
|
||||
int status;
|
||||
MsgType msgtype = (MsgType) port->proto;
|
||||
|
||||
/* Handle the authentication that's offered. */
|
||||
|
||||
switch (msgtype)
|
||||
{
|
||||
case STARTUP_KRB4_MSG:
|
||||
status = map_old_to_new(port,uaKrb4,pg_krb4_recvauth(port));
|
||||
break;
|
||||
{
|
||||
case STARTUP_KRB4_MSG:
|
||||
status = map_old_to_new(port, uaKrb4, pg_krb4_recvauth(port));
|
||||
break;
|
||||
|
||||
case STARTUP_KRB5_MSG:
|
||||
status = map_old_to_new(port,uaKrb5,pg_krb5_recvauth(port));
|
||||
break;
|
||||
case STARTUP_KRB5_MSG:
|
||||
status = map_old_to_new(port, uaKrb5, pg_krb5_recvauth(port));
|
||||
break;
|
||||
|
||||
case STARTUP_MSG:
|
||||
status = map_old_to_new(port,uaTrust,STATUS_OK);
|
||||
break;
|
||||
case STARTUP_MSG:
|
||||
status = map_old_to_new(port, uaTrust, STATUS_OK);
|
||||
break;
|
||||
|
||||
case STARTUP_PASSWORD_MSG:
|
||||
PacketReceiveSetup(&port->pktInfo, pg_passwordv0_recvauth,
|
||||
(char *)port);
|
||||
case STARTUP_PASSWORD_MSG:
|
||||
PacketReceiveSetup(&port->pktInfo, pg_passwordv0_recvauth,
|
||||
(char *) port);
|
||||
|
||||
return STATUS_OK;
|
||||
return STATUS_OK;
|
||||
|
||||
default:
|
||||
fprintf(stderr, "Invalid startup message type: %u\n", msgtype);
|
||||
default:
|
||||
fprintf(stderr, "Invalid startup message type: %u\n", msgtype);
|
||||
|
||||
return STATUS_OK;
|
||||
}
|
||||
return STATUS_OK;
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* The old style authentication has been done. Modify the result of this (eg.
|
||||
* The old style authentication has been done. Modify the result of this (eg.
|
||||
* allow the connection anyway, disallow it anyway, or use the result)
|
||||
* depending on what authentication we really want to use.
|
||||
*/
|
||||
|
||||
static int map_old_to_new(Port *port, UserAuth old, int status)
|
||||
static int
|
||||
map_old_to_new(Port *port, UserAuth old, int status)
|
||||
{
|
||||
switch (port->auth_method)
|
||||
{
|
||||
case uaCrypt:
|
||||
case uaReject:
|
||||
status = STATUS_ERROR;
|
||||
break;
|
||||
|
||||
case uaKrb4:
|
||||
if (old != uaKrb4)
|
||||
case uaCrypt:
|
||||
case uaReject:
|
||||
status = STATUS_ERROR;
|
||||
break;
|
||||
break;
|
||||
|
||||
case uaKrb5:
|
||||
if (old != uaKrb5)
|
||||
status = STATUS_ERROR;
|
||||
break;
|
||||
case uaKrb4:
|
||||
if (old != uaKrb4)
|
||||
status = STATUS_ERROR;
|
||||
break;
|
||||
|
||||
case uaTrust:
|
||||
status = STATUS_OK;
|
||||
break;
|
||||
case uaKrb5:
|
||||
if (old != uaKrb5)
|
||||
status = STATUS_ERROR;
|
||||
break;
|
||||
|
||||
case uaIdent:
|
||||
status = authident(&port->raddr.in, &port->laddr.in,
|
||||
port->user, port->auth_arg);
|
||||
break;
|
||||
case uaTrust:
|
||||
status = STATUS_OK;
|
||||
break;
|
||||
|
||||
case uaPassword:
|
||||
if (old != uaPassword)
|
||||
status = STATUS_ERROR;
|
||||
case uaIdent:
|
||||
status = authident(&port->raddr.in, &port->laddr.in,
|
||||
port->user, port->auth_arg);
|
||||
break;
|
||||
|
||||
break;
|
||||
case uaPassword:
|
||||
if (old != uaPassword)
|
||||
status = STATUS_ERROR;
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
return status;
|
||||
}
|
||||
|
|
|
@ -8,7 +8,7 @@
|
|||
*
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $Header: /cvsroot/pgsql/src/backend/libpq/Attic/be-dumpdata.c,v 1.13 1998/02/10 16:03:12 momjian Exp $
|
||||
* $Header: /cvsroot/pgsql/src/backend/libpq/Attic/be-dumpdata.c,v 1.14 1998/02/26 04:31:44 momjian Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
|
@ -313,8 +313,8 @@ be_printtup(HeapTuple tuple, TupleDesc typeinfo)
|
|||
if (!isnull && OidIsValid(typoutput))
|
||||
{
|
||||
values[i] = fmgr(typoutput, attr,
|
||||
gettypelem(typeinfo->attrs[i]->atttypid),
|
||||
typeinfo->attrs[i]->atttypmod);
|
||||
gettypelem(typeinfo->attrs[i]->atttypid),
|
||||
typeinfo->attrs[i]->atttypmod);
|
||||
}
|
||||
else
|
||||
values[i] = NULL;
|
||||
|
|
|
@ -8,7 +8,7 @@
|
|||
*
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $Header: /cvsroot/pgsql/src/backend/libpq/Attic/be-pqexec.c,v 1.14 1998/01/26 01:41:06 scrappy Exp $
|
||||
* $Header: /cvsroot/pgsql/src/backend/libpq/Attic/be-pqexec.c,v 1.15 1998/02/26 04:31:45 momjian Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
|
@ -58,7 +58,7 @@ static char *strmake(char *str, int len);
|
|||
* This code scavanged from HandleFunctionRequest() in tcop/fastpath.h
|
||||
* ----------------
|
||||
*/
|
||||
char *
|
||||
char *
|
||||
PQfn(int fnid,
|
||||
int *result_buf, /* can't use void, dec compiler barfs */
|
||||
int result_len,
|
||||
|
@ -129,7 +129,7 @@ PQfn(int fnid,
|
|||
* returns because the system longjmp's back to the main loop.
|
||||
* ----------------
|
||||
*/
|
||||
char *
|
||||
char *
|
||||
PQexec(char *query)
|
||||
{
|
||||
PortalEntry *entry = NULL;
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
/*-------------------------------------------------------------------------
|
||||
*
|
||||
* crypt.c--
|
||||
* Look into pg_shadow and check the encrypted password with the one
|
||||
* passed in from the frontend.
|
||||
* Look into pg_shadow and check the encrypted password with the one
|
||||
* passed in from the frontend.
|
||||
*
|
||||
* Modification History
|
||||
*
|
||||
|
@ -28,262 +28,313 @@
|
|||
#include <crypt.h>
|
||||
#endif
|
||||
|
||||
char** pwd_cache = NULL;
|
||||
int pwd_cache_count = 0;
|
||||
char **pwd_cache = NULL;
|
||||
int pwd_cache_count = 0;
|
||||
|
||||
/*-------------------------------------------------------------------------*/
|
||||
|
||||
char* crypt_getpwdfilename() {
|
||||
char *
|
||||
crypt_getpwdfilename()
|
||||
{
|
||||
|
||||
static char* pfnam = NULL;
|
||||
static char *pfnam = NULL;
|
||||
|
||||
if (!pfnam) {
|
||||
pfnam = (char*)malloc(strlen(DataDir) + strlen(CRYPT_PWD_FILE) + 2);
|
||||
sprintf(pfnam, "%s/%s", DataDir, CRYPT_PWD_FILE);
|
||||
}
|
||||
if (!pfnam)
|
||||
{
|
||||
pfnam = (char *) malloc(strlen(DataDir) + strlen(CRYPT_PWD_FILE) + 2);
|
||||
sprintf(pfnam, "%s/%s", DataDir, CRYPT_PWD_FILE);
|
||||
}
|
||||
|
||||
return pfnam;
|
||||
return pfnam;
|
||||
}
|
||||
|
||||
/*-------------------------------------------------------------------------*/
|
||||
|
||||
char* crypt_getpwdreloadfilename() {
|
||||
char *
|
||||
crypt_getpwdreloadfilename()
|
||||
{
|
||||
|
||||
static char* rpfnam = NULL;
|
||||
static char *rpfnam = NULL;
|
||||
|
||||
if (!rpfnam) {
|
||||
char* pwdfilename;
|
||||
if (!rpfnam)
|
||||
{
|
||||
char *pwdfilename;
|
||||
|
||||
pwdfilename = crypt_getpwdfilename();
|
||||
rpfnam = (char*)malloc(strlen(pwdfilename) + strlen(CRYPT_PWD_RELOAD_SUFX) + 1);
|
||||
sprintf(rpfnam, "%s%s", pwdfilename, CRYPT_PWD_RELOAD_SUFX);
|
||||
}
|
||||
pwdfilename = crypt_getpwdfilename();
|
||||
rpfnam = (char *) malloc(strlen(pwdfilename) + strlen(CRYPT_PWD_RELOAD_SUFX) + 1);
|
||||
sprintf(rpfnam, "%s%s", pwdfilename, CRYPT_PWD_RELOAD_SUFX);
|
||||
}
|
||||
|
||||
return rpfnam;
|
||||
return rpfnam;
|
||||
}
|
||||
|
||||
/*-------------------------------------------------------------------------*/
|
||||
|
||||
static
|
||||
FILE* crypt_openpwdfile() {
|
||||
char* filename;
|
||||
FILE* pwdfile;
|
||||
FILE *
|
||||
crypt_openpwdfile()
|
||||
{
|
||||
char *filename;
|
||||
FILE *pwdfile;
|
||||
|
||||
filename = crypt_getpwdfilename();
|
||||
pwdfile = AllocateFile(filename, "r");
|
||||
filename = crypt_getpwdfilename();
|
||||
pwdfile = AllocateFile(filename, "r");
|
||||
|
||||
return pwdfile;
|
||||
return pwdfile;
|
||||
}
|
||||
|
||||
/*-------------------------------------------------------------------------*/
|
||||
|
||||
static
|
||||
int compar_user(const void* user_a, const void* user_b) {
|
||||
int
|
||||
compar_user(const void *user_a, const void *user_b)
|
||||
{
|
||||
|
||||
int min,
|
||||
value;
|
||||
char* login_a;
|
||||
char* login_b;
|
||||
int min,
|
||||
value;
|
||||
char *login_a;
|
||||
char *login_b;
|
||||
|
||||
login_a = *((char**)user_a);
|
||||
login_b = *((char**)user_b);
|
||||
login_a = *((char **) user_a);
|
||||
login_b = *((char **) user_b);
|
||||
|
||||
/* We only really want to compare the user logins which are first. We look
|
||||
* for the first SEPSTR char getting the number of chars there are before it.
|
||||
* We only need to compare to the min count from the two strings.
|
||||
*/
|
||||
min = strcspn(login_a, CRYPT_PWD_FILE_SEPSTR);
|
||||
value = strcspn(login_b, CRYPT_PWD_FILE_SEPSTR);
|
||||
if (value < min)
|
||||
min = value;
|
||||
/*
|
||||
* We only really want to compare the user logins which are first. We
|
||||
* look for the first SEPSTR char getting the number of chars there
|
||||
* are before it. We only need to compare to the min count from the
|
||||
* two strings.
|
||||
*/
|
||||
min = strcspn(login_a, CRYPT_PWD_FILE_SEPSTR);
|
||||
value = strcspn(login_b, CRYPT_PWD_FILE_SEPSTR);
|
||||
if (value < min)
|
||||
min = value;
|
||||
|
||||
/* We add one to min so that the separator character is included in the
|
||||
* comparison. Why? I believe this will prevent logins that are proper
|
||||
* prefixes of other logins from being 'masked out'. Being conservative!
|
||||
*/
|
||||
return strncmp(login_a, login_b, min + 1);
|
||||
/*
|
||||
* We add one to min so that the separator character is included in
|
||||
* the comparison. Why? I believe this will prevent logins that are
|
||||
* proper prefixes of other logins from being 'masked out'. Being
|
||||
* conservative!
|
||||
*/
|
||||
return strncmp(login_a, login_b, min + 1);
|
||||
}
|
||||
|
||||
/*-------------------------------------------------------------------------*/
|
||||
|
||||
static
|
||||
void crypt_loadpwdfile() {
|
||||
void
|
||||
crypt_loadpwdfile()
|
||||
{
|
||||
|
||||
char* filename;
|
||||
int result;
|
||||
FILE* pwd_file;
|
||||
char buffer[256];
|
||||
char *filename;
|
||||
int result;
|
||||
FILE *pwd_file;
|
||||
char buffer[256];
|
||||
|
||||
filename = crypt_getpwdreloadfilename();
|
||||
result = unlink(filename);
|
||||
filename = crypt_getpwdreloadfilename();
|
||||
result = unlink(filename);
|
||||
|
||||
/* We want to delete the flag file before reading the contents of the pg_pwd
|
||||
* file. If result == 0 then the unlink of the reload file was successful.
|
||||
* This means that a backend performed a COPY of the pg_shadow file to
|
||||
* pg_pwd. Therefore we must now do a reload.
|
||||
*/
|
||||
if (!pwd_cache || !result) {
|
||||
if (pwd_cache) { /* free the old data only if this is a reload */
|
||||
while (pwd_cache_count--) {
|
||||
free((void*)pwd_cache[pwd_cache_count]);
|
||||
}
|
||||
free((void*)pwd_cache);
|
||||
pwd_cache = NULL;
|
||||
pwd_cache_count = 0;
|
||||
}
|
||||
/*
|
||||
* We want to delete the flag file before reading the contents of the
|
||||
* pg_pwd file. If result == 0 then the unlink of the reload file was
|
||||
* successful. This means that a backend performed a COPY of the
|
||||
* pg_shadow file to pg_pwd. Therefore we must now do a reload.
|
||||
*/
|
||||
if (!pwd_cache || !result)
|
||||
{
|
||||
if (pwd_cache)
|
||||
{ /* free the old data only if this is a
|
||||
* reload */
|
||||
while (pwd_cache_count--)
|
||||
{
|
||||
free((void *) pwd_cache[pwd_cache_count]);
|
||||
}
|
||||
free((void *) pwd_cache);
|
||||
pwd_cache = NULL;
|
||||
pwd_cache_count = 0;
|
||||
}
|
||||
|
||||
if (!(pwd_file = crypt_openpwdfile()))
|
||||
return;
|
||||
if (!(pwd_file = crypt_openpwdfile()))
|
||||
return;
|
||||
|
||||
/* Here is where we load the data from pg_pwd.
|
||||
*/
|
||||
while (fgets(buffer, 256, pwd_file) != NULL) {
|
||||
/* We must remove the return char at the end of the string, as this will
|
||||
* affect the correct parsing of the password entry.
|
||||
*/
|
||||
if (buffer[(result = strlen(buffer) - 1)] == '\n')
|
||||
buffer[result] = '\0';
|
||||
/*
|
||||
* Here is where we load the data from pg_pwd.
|
||||
*/
|
||||
while (fgets(buffer, 256, pwd_file) != NULL)
|
||||
{
|
||||
|
||||
pwd_cache = (char**)realloc((void*)pwd_cache, sizeof(char*) * (pwd_cache_count + 1));
|
||||
pwd_cache[pwd_cache_count++] = strdup(buffer);
|
||||
}
|
||||
fclose(pwd_file);
|
||||
/*
|
||||
* We must remove the return char at the end of the string, as
|
||||
* this will affect the correct parsing of the password entry.
|
||||
*/
|
||||
if (buffer[(result = strlen(buffer) - 1)] == '\n')
|
||||
buffer[result] = '\0';
|
||||
|
||||
/* Now sort the entries in the cache for faster searching later.
|
||||
*/
|
||||
qsort((void*)pwd_cache, pwd_cache_count, sizeof(char*), compar_user);
|
||||
}
|
||||
pwd_cache = (char **) realloc((void *) pwd_cache, sizeof(char *) * (pwd_cache_count + 1));
|
||||
pwd_cache[pwd_cache_count++] = strdup(buffer);
|
||||
}
|
||||
fclose(pwd_file);
|
||||
|
||||
/*
|
||||
* Now sort the entries in the cache for faster searching later.
|
||||
*/
|
||||
qsort((void *) pwd_cache, pwd_cache_count, sizeof(char *), compar_user);
|
||||
}
|
||||
}
|
||||
|
||||
/*-------------------------------------------------------------------------*/
|
||||
|
||||
static
|
||||
void crypt_parsepwdentry(char* buffer, char** pwd, char** valdate) {
|
||||
void
|
||||
crypt_parsepwdentry(char *buffer, char **pwd, char **valdate)
|
||||
{
|
||||
|
||||
char* parse = buffer;
|
||||
int count,
|
||||
i;
|
||||
char *parse = buffer;
|
||||
int count,
|
||||
i;
|
||||
|
||||
/* skip to the password field
|
||||
*/
|
||||
for (i = 0; i < 6; i++)
|
||||
parse += (strcspn(parse, CRYPT_PWD_FILE_SEPSTR) + 1);
|
||||
/*
|
||||
* skip to the password field
|
||||
*/
|
||||
for (i = 0; i < 6; i++)
|
||||
parse += (strcspn(parse, CRYPT_PWD_FILE_SEPSTR) + 1);
|
||||
|
||||
/* store a copy of user password to return
|
||||
*/
|
||||
count = strcspn(parse, CRYPT_PWD_FILE_SEPSTR);
|
||||
*pwd = (char*)malloc(count + 1);
|
||||
strncpy(*pwd, parse, count);
|
||||
(*pwd)[count] = '\0';
|
||||
parse += (count + 1);
|
||||
/*
|
||||
* store a copy of user password to return
|
||||
*/
|
||||
count = strcspn(parse, CRYPT_PWD_FILE_SEPSTR);
|
||||
*pwd = (char *) malloc(count + 1);
|
||||
strncpy(*pwd, parse, count);
|
||||
(*pwd)[count] = '\0';
|
||||
parse += (count + 1);
|
||||
|
||||
/* store a copy of date login becomes invalid
|
||||
*/
|
||||
count = strcspn(parse, CRYPT_PWD_FILE_SEPSTR);
|
||||
*valdate = (char*)malloc(count + 1);
|
||||
strncpy(*valdate, parse, count);
|
||||
(*valdate)[count] = '\0';
|
||||
parse += (count + 1);
|
||||
/*
|
||||
* store a copy of date login becomes invalid
|
||||
*/
|
||||
count = strcspn(parse, CRYPT_PWD_FILE_SEPSTR);
|
||||
*valdate = (char *) malloc(count + 1);
|
||||
strncpy(*valdate, parse, count);
|
||||
(*valdate)[count] = '\0';
|
||||
parse += (count + 1);
|
||||
}
|
||||
|
||||
/*-------------------------------------------------------------------------*/
|
||||
|
||||
static
|
||||
int crypt_getloginfo(const char* user, char** passwd, char** valuntil) {
|
||||
int
|
||||
crypt_getloginfo(const char *user, char **passwd, char **valuntil)
|
||||
{
|
||||
|
||||
char* pwd;
|
||||
char* valdate;
|
||||
void* fakeout;
|
||||
char *pwd;
|
||||
char *valdate;
|
||||
void *fakeout;
|
||||
|
||||
*passwd = NULL;
|
||||
*valuntil = NULL;
|
||||
crypt_loadpwdfile();
|
||||
*passwd = NULL;
|
||||
*valuntil = NULL;
|
||||
crypt_loadpwdfile();
|
||||
|
||||
if (pwd_cache) {
|
||||
char** pwd_entry;
|
||||
char user_search[NAMEDATALEN + 2];
|
||||
if (pwd_cache)
|
||||
{
|
||||
char **pwd_entry;
|
||||
char user_search[NAMEDATALEN + 2];
|
||||
|
||||
sprintf(user_search, "%s\t", user);
|
||||
fakeout = (void*)&user_search;
|
||||
if ((pwd_entry = (char**)bsearch((void*)&fakeout, (void*)pwd_cache, pwd_cache_count, sizeof(char*), compar_user))) {
|
||||
crypt_parsepwdentry(*pwd_entry, &pwd, &valdate);
|
||||
*passwd = pwd;
|
||||
*valuntil = valdate;
|
||||
return STATUS_OK;
|
||||
}
|
||||
sprintf(user_search, "%s\t", user);
|
||||
fakeout = (void *) &user_search;
|
||||
if ((pwd_entry = (char **) bsearch((void *) &fakeout, (void *) pwd_cache, pwd_cache_count, sizeof(char *), compar_user)))
|
||||
{
|
||||
crypt_parsepwdentry(*pwd_entry, &pwd, &valdate);
|
||||
*passwd = pwd;
|
||||
*valuntil = valdate;
|
||||
return STATUS_OK;
|
||||
}
|
||||
|
||||
return STATUS_OK;
|
||||
}
|
||||
return STATUS_OK;
|
||||
}
|
||||
|
||||
return STATUS_ERROR;
|
||||
return STATUS_ERROR;
|
||||
}
|
||||
|
||||
/*-------------------------------------------------------------------------*/
|
||||
|
||||
#if 0
|
||||
MsgType crypt_salt(const char* user) {
|
||||
MsgType
|
||||
crypt_salt(const char *user)
|
||||
{
|
||||
|
||||
char* passwd;
|
||||
char* valuntil;
|
||||
char *passwd;
|
||||
char *valuntil;
|
||||
|
||||
if (crypt_getloginfo(user, &passwd, &valuntil) == STATUS_ERROR)
|
||||
return STARTUP_UNSALT_MSG;
|
||||
if (crypt_getloginfo(user, &passwd, &valuntil) == STATUS_ERROR)
|
||||
return STARTUP_UNSALT_MSG;
|
||||
|
||||
if (passwd == NULL || *passwd == '\0' || !strcmp(passwd, "\\N")) {
|
||||
if (passwd) free((void*)passwd);
|
||||
if (valuntil) free((void*)valuntil);
|
||||
return STARTUP_UNSALT_MSG;
|
||||
}
|
||||
if (passwd == NULL || *passwd == '\0' || !strcmp(passwd, "\\N"))
|
||||
{
|
||||
if (passwd)
|
||||
free((void *) passwd);
|
||||
if (valuntil)
|
||||
free((void *) valuntil);
|
||||
return STARTUP_UNSALT_MSG;
|
||||
}
|
||||
|
||||
free((void*)passwd);
|
||||
if (valuntil) free((void*)valuntil);
|
||||
return STARTUP_SALT_MSG;
|
||||
free((void *) passwd);
|
||||
if (valuntil)
|
||||
free((void *) valuntil);
|
||||
return STARTUP_SALT_MSG;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
/*-------------------------------------------------------------------------*/
|
||||
|
||||
int crypt_verify(Port* port, const char* user, const char* pgpass) {
|
||||
int
|
||||
crypt_verify(Port *port, const char *user, const char *pgpass)
|
||||
{
|
||||
|
||||
char* passwd;
|
||||
char* valuntil;
|
||||
char* crypt_pwd;
|
||||
int retval = STATUS_ERROR;
|
||||
AbsoluteTime vuntil,
|
||||
current;
|
||||
char *passwd;
|
||||
char *valuntil;
|
||||
char *crypt_pwd;
|
||||
int retval = STATUS_ERROR;
|
||||
AbsoluteTime vuntil,
|
||||
current;
|
||||
|
||||
if (crypt_getloginfo(user, &passwd, &valuntil) == STATUS_ERROR)
|
||||
return STATUS_ERROR;
|
||||
if (crypt_getloginfo(user, &passwd, &valuntil) == STATUS_ERROR)
|
||||
return STATUS_ERROR;
|
||||
|
||||
if (passwd == NULL || *passwd == '\0') {
|
||||
if (passwd) free((void*)passwd);
|
||||
if (valuntil) free((void*)valuntil);
|
||||
return STATUS_ERROR;
|
||||
}
|
||||
if (passwd == NULL || *passwd == '\0')
|
||||
{
|
||||
if (passwd)
|
||||
free((void *) passwd);
|
||||
if (valuntil)
|
||||
free((void *) valuntil);
|
||||
return STATUS_ERROR;
|
||||
}
|
||||
|
||||
/*
|
||||
* Compare with the encrypted or plain password depending on the
|
||||
* authentication method being used for this connection.
|
||||
*/
|
||||
/*
|
||||
* Compare with the encrypted or plain password depending on the
|
||||
* authentication method being used for this connection.
|
||||
*/
|
||||
|
||||
crypt_pwd = (port->auth_method == uaCrypt ? crypt(passwd, port->salt) : passwd);
|
||||
crypt_pwd = (port->auth_method == uaCrypt ? crypt(passwd, port->salt) : passwd);
|
||||
|
||||
if (!strcmp(pgpass, crypt_pwd)) {
|
||||
/* check here to be sure we are not past valuntil
|
||||
*/
|
||||
if (!valuntil || strcmp(valuntil, "\\N") == 0)
|
||||
vuntil = INVALID_ABSTIME;
|
||||
else
|
||||
vuntil = nabstimein(valuntil);
|
||||
current = GetCurrentAbsoluteTime();
|
||||
if (vuntil != INVALID_ABSTIME && vuntil < current)
|
||||
retval = STATUS_ERROR;
|
||||
else
|
||||
retval = STATUS_OK;
|
||||
}
|
||||
if (!strcmp(pgpass, crypt_pwd))
|
||||
{
|
||||
|
||||
free((void*)passwd);
|
||||
if (valuntil) free((void*)valuntil);
|
||||
|
||||
return retval;
|
||||
/*
|
||||
* check here to be sure we are not past valuntil
|
||||
*/
|
||||
if (!valuntil || strcmp(valuntil, "\\N") == 0)
|
||||
vuntil = INVALID_ABSTIME;
|
||||
else
|
||||
vuntil = nabstimein(valuntil);
|
||||
current = GetCurrentAbsoluteTime();
|
||||
if (vuntil != INVALID_ABSTIME && vuntil < current)
|
||||
retval = STATUS_ERROR;
|
||||
else
|
||||
retval = STATUS_OK;
|
||||
}
|
||||
|
||||
free((void *) passwd);
|
||||
if (valuntil)
|
||||
free((void *) valuntil);
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
*
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $Header: /cvsroot/pgsql/src/backend/libpq/hba.c,v 1.28 1998/02/24 15:18:41 scrappy Exp $
|
||||
* $Header: /cvsroot/pgsql/src/backend/libpq/hba.c,v 1.29 1998/02/26 04:31:49 momjian Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
|
@ -97,8 +97,8 @@ read_through_eol(FILE *file)
|
|||
|
||||
|
||||
static void
|
||||
read_hba_entry2(FILE *file, UserAuth * userauth_p, char auth_arg[],
|
||||
bool *error_p)
|
||||
read_hba_entry2(FILE *file, UserAuth *userauth_p, char auth_arg[],
|
||||
bool *error_p)
|
||||
{
|
||||
/*--------------------------------------------------------------------------
|
||||
Read from file FILE the rest of a host record, after the mask field,
|
||||
|
@ -156,7 +156,7 @@ read_hba_entry2(FILE *file, UserAuth * userauth_p, char auth_arg[],
|
|||
static void
|
||||
process_hba_record(FILE *file, SockAddr *raddr, const char database[],
|
||||
bool *matches_p, bool *error_p,
|
||||
UserAuth * userauth_p, char auth_arg[])
|
||||
UserAuth *userauth_p, char auth_arg[])
|
||||
{
|
||||
/*---------------------------------------------------------------------------
|
||||
Process the non-comment record in the config file that is next on the file.
|
||||
|
@ -167,7 +167,8 @@ process_hba_record(FILE *file, SockAddr *raddr, const char database[],
|
|||
return *error_p true, after issuing a message to stderr. If no error,
|
||||
leave *error_p as it was.
|
||||
---------------------------------------------------------------------------*/
|
||||
char db[MAX_TOKEN], buf[MAX_TOKEN];
|
||||
char db[MAX_TOKEN],
|
||||
buf[MAX_TOKEN];
|
||||
|
||||
/* Read the record type field. */
|
||||
|
||||
|
@ -196,9 +197,9 @@ process_hba_record(FILE *file, SockAddr *raddr, const char database[],
|
|||
*/
|
||||
|
||||
if (!*error_p &&
|
||||
(*userauth_p == uaIdent ||
|
||||
*userauth_p == uaKrb4 ||
|
||||
*userauth_p == uaKrb5))
|
||||
(*userauth_p == uaIdent ||
|
||||
*userauth_p == uaKrb4 ||
|
||||
*userauth_p == uaKrb5))
|
||||
*error_p = true;
|
||||
|
||||
if (*error_p)
|
||||
|
@ -210,12 +211,13 @@ process_hba_record(FILE *file, SockAddr *raddr, const char database[],
|
|||
*/
|
||||
|
||||
if ((strcmp(db, database) != 0 && strcmp(db, "all") != 0) ||
|
||||
raddr->sa.sa_family != AF_UNIX)
|
||||
raddr->sa.sa_family != AF_UNIX)
|
||||
return;
|
||||
}
|
||||
else if (strcmp(buf, "host") == 0)
|
||||
{
|
||||
struct in_addr file_ip_addr, mask;
|
||||
struct in_addr file_ip_addr,
|
||||
mask;
|
||||
|
||||
/* Get the database. */
|
||||
|
||||
|
@ -284,7 +286,7 @@ process_hba_record(FILE *file, SockAddr *raddr, const char database[],
|
|||
|
||||
syntax:
|
||||
sprintf(PQerrormsg,
|
||||
"process_hba_record: invalid syntax in pg_hba.conf file\n");
|
||||
"process_hba_record: invalid syntax in pg_hba.conf file\n");
|
||||
|
||||
fputs(PQerrormsg, stderr);
|
||||
pqdebug("%s", PQerrormsg);
|
||||
|
@ -296,8 +298,8 @@ syntax:
|
|||
|
||||
static void
|
||||
process_open_config_file(FILE *file, SockAddr *raddr, const char database[],
|
||||
bool *host_ok_p, UserAuth * userauth_p,
|
||||
char auth_arg[])
|
||||
bool *host_ok_p, UserAuth *userauth_p,
|
||||
char auth_arg[])
|
||||
{
|
||||
/*---------------------------------------------------------------------------
|
||||
This function does the same thing as find_hba_entry, only with
|
||||
|
@ -332,7 +334,7 @@ process_open_config_file(FILE *file, SockAddr *raddr, const char database[],
|
|||
else
|
||||
{
|
||||
process_hba_record(file, raddr, database,
|
||||
&found_entry, &error, userauth_p, auth_arg);
|
||||
&found_entry, &error, userauth_p, auth_arg);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -352,7 +354,7 @@ process_open_config_file(FILE *file, SockAddr *raddr, const char database[],
|
|||
|
||||
static void
|
||||
find_hba_entry(SockAddr *raddr, const char database[], bool *host_ok_p,
|
||||
UserAuth * userauth_p, char auth_arg[])
|
||||
UserAuth *userauth_p, char auth_arg[])
|
||||
{
|
||||
/*--------------------------------------------------------------------------
|
||||
Read the config file and find an entry that allows connection from
|
||||
|
@ -812,7 +814,7 @@ verify_against_usermap(const char pguser[],
|
|||
|
||||
|
||||
int
|
||||
authident(struct sockaddr_in *raddr, struct sockaddr_in *laddr,
|
||||
authident(struct sockaddr_in * raddr, struct sockaddr_in * laddr,
|
||||
const char postgres_username[],
|
||||
const char auth_arg[])
|
||||
{
|
||||
|
@ -840,7 +842,7 @@ authident(struct sockaddr_in *raddr, struct sockaddr_in *laddr,
|
|||
return STATUS_ERROR;
|
||||
|
||||
verify_against_usermap(postgres_username, ident_username, auth_arg,
|
||||
&checks_out);
|
||||
&checks_out);
|
||||
|
||||
return (checks_out ? STATUS_OK : STATUS_ERROR);
|
||||
}
|
||||
|
@ -849,193 +851,207 @@ authident(struct sockaddr_in *raddr, struct sockaddr_in *laddr,
|
|||
#ifdef CYR_RECODE
|
||||
#define CHARSET_FILE "charset.conf"
|
||||
#define MAX_CHARSETS 10
|
||||
#define KEY_HOST 1
|
||||
#define KEY_BASE 2
|
||||
#define KEY_TABLE 3
|
||||
#define KEY_HOST 1
|
||||
#define KEY_BASE 2
|
||||
#define KEY_TABLE 3
|
||||
|
||||
struct CharsetItem
|
||||
{
|
||||
char Orig[MAX_TOKEN];
|
||||
char Dest[MAX_TOKEN];
|
||||
char Table[MAX_TOKEN];
|
||||
char Orig[MAX_TOKEN];
|
||||
char Dest[MAX_TOKEN];
|
||||
char Table[MAX_TOKEN];
|
||||
};
|
||||
|
||||
int InRange(char *buf,int host)
|
||||
int
|
||||
InRange(char *buf, int host)
|
||||
{
|
||||
int valid,i,FromAddr,ToAddr,tmp;
|
||||
struct in_addr file_ip_addr;
|
||||
char *p;
|
||||
unsigned int one=0x80000000,NetMask=0;
|
||||
unsigned char mask;
|
||||
p = strchr(buf,'/');
|
||||
if(p)
|
||||
{
|
||||
*p++ = '\0';
|
||||
valid = inet_aton(buf, &file_ip_addr);
|
||||
if(valid)
|
||||
{
|
||||
mask = strtoul(p,0,0);
|
||||
FromAddr = ntohl(file_ip_addr.s_addr);
|
||||
ToAddr = ntohl(file_ip_addr.s_addr);
|
||||
for(i=0;i<mask;i++)
|
||||
{
|
||||
NetMask |= one;
|
||||
one >>= 1;
|
||||
}
|
||||
FromAddr &= NetMask;
|
||||
ToAddr = ToAddr | ~NetMask;
|
||||
tmp = ntohl(host);
|
||||
return ((unsigned)tmp>=(unsigned)FromAddr &&
|
||||
(unsigned)tmp<=(unsigned)ToAddr);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
p = strchr(buf,'-');
|
||||
if(p)
|
||||
{
|
||||
*p++ = '\0';
|
||||
valid = inet_aton(buf, &file_ip_addr);
|
||||
if(valid)
|
||||
{
|
||||
FromAddr = ntohl(file_ip_addr.s_addr);
|
||||
valid = inet_aton(p, &file_ip_addr);
|
||||
if(valid)
|
||||
{
|
||||
ToAddr = ntohl(file_ip_addr.s_addr);
|
||||
tmp = ntohl(host);
|
||||
return ((unsigned)tmp>=(unsigned)FromAddr &&
|
||||
(unsigned)tmp<=(unsigned)ToAddr);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
valid = inet_aton(buf, &file_ip_addr);
|
||||
if(valid)
|
||||
{
|
||||
FromAddr = file_ip_addr.s_addr;
|
||||
return ((unsigned)FromAddr == (unsigned)host);
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
int valid,
|
||||
i,
|
||||
FromAddr,
|
||||
ToAddr,
|
||||
tmp;
|
||||
struct in_addr file_ip_addr;
|
||||
char *p;
|
||||
unsigned int one = 0x80000000,
|
||||
NetMask = 0;
|
||||
unsigned char mask;
|
||||
|
||||
p = strchr(buf, '/');
|
||||
if (p)
|
||||
{
|
||||
*p++ = '\0';
|
||||
valid = inet_aton(buf, &file_ip_addr);
|
||||
if (valid)
|
||||
{
|
||||
mask = strtoul(p, 0, 0);
|
||||
FromAddr = ntohl(file_ip_addr.s_addr);
|
||||
ToAddr = ntohl(file_ip_addr.s_addr);
|
||||
for (i = 0; i < mask; i++)
|
||||
{
|
||||
NetMask |= one;
|
||||
one >>= 1;
|
||||
}
|
||||
FromAddr &= NetMask;
|
||||
ToAddr = ToAddr | ~NetMask;
|
||||
tmp = ntohl(host);
|
||||
return ((unsigned) tmp >= (unsigned) FromAddr &&
|
||||
(unsigned) tmp <= (unsigned) ToAddr);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
p = strchr(buf, '-');
|
||||
if (p)
|
||||
{
|
||||
*p++ = '\0';
|
||||
valid = inet_aton(buf, &file_ip_addr);
|
||||
if (valid)
|
||||
{
|
||||
FromAddr = ntohl(file_ip_addr.s_addr);
|
||||
valid = inet_aton(p, &file_ip_addr);
|
||||
if (valid)
|
||||
{
|
||||
ToAddr = ntohl(file_ip_addr.s_addr);
|
||||
tmp = ntohl(host);
|
||||
return ((unsigned) tmp >= (unsigned) FromAddr &&
|
||||
(unsigned) tmp <= (unsigned) ToAddr);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
valid = inet_aton(buf, &file_ip_addr);
|
||||
if (valid)
|
||||
{
|
||||
FromAddr = file_ip_addr.s_addr;
|
||||
return ((unsigned) FromAddr == (unsigned) host);
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void GetCharSetByHost(char TableName[],int host, const char DataDir[])
|
||||
void
|
||||
GetCharSetByHost(char TableName[], int host, const char DataDir[])
|
||||
{
|
||||
FILE *file;
|
||||
char buf[MAX_TOKEN],BaseCharset[MAX_TOKEN],
|
||||
OrigCharset[MAX_TOKEN],DestCharset[MAX_TOKEN],HostCharset[MAX_TOKEN];
|
||||
char c,eof=false;
|
||||
char *map_file;
|
||||
int key=0,i;
|
||||
struct CharsetItem* ChArray[MAX_CHARSETS];
|
||||
int ChIndex=0;
|
||||
FILE *file;
|
||||
char buf[MAX_TOKEN],
|
||||
BaseCharset[MAX_TOKEN],
|
||||
OrigCharset[MAX_TOKEN],
|
||||
DestCharset[MAX_TOKEN],
|
||||
HostCharset[MAX_TOKEN];
|
||||
char c,
|
||||
eof = false;
|
||||
char *map_file;
|
||||
int key = 0,
|
||||
i;
|
||||
struct CharsetItem *ChArray[MAX_CHARSETS];
|
||||
int ChIndex = 0;
|
||||
|
||||
*TableName = '\0';
|
||||
map_file = (char *) malloc((strlen(DataDir) +
|
||||
strlen(CHARSET_FILE)+2)*sizeof(char));
|
||||
sprintf(map_file, "%s/%s", DataDir, CHARSET_FILE);
|
||||
file = fopen(map_file, "r");
|
||||
if (file == NULL)
|
||||
return;
|
||||
while (!eof)
|
||||
{
|
||||
c = getc(file);
|
||||
ungetc(c, file);
|
||||
if (c == EOF)
|
||||
eof = true;
|
||||
else
|
||||
{
|
||||
if (c == '#')
|
||||
read_through_eol(file);
|
||||
else
|
||||
{
|
||||
/* Read the key */
|
||||
next_token(file, buf, sizeof(buf));
|
||||
if (buf[0] != '\0')
|
||||
{
|
||||
if (strcasecmp(buf, "HostCharset") == 0)
|
||||
key = KEY_HOST;
|
||||
if (strcasecmp(buf, "BaseCharset") == 0)
|
||||
key = KEY_BASE;
|
||||
if (strcasecmp(buf, "RecodeTable") == 0)
|
||||
key = KEY_TABLE;
|
||||
switch(key)
|
||||
{
|
||||
case KEY_HOST:
|
||||
/* Read the host */
|
||||
next_token(file, buf, sizeof(buf));
|
||||
if (buf[0] != '\0')
|
||||
{
|
||||
if (InRange(buf,host))
|
||||
{
|
||||
/* Read the charset */
|
||||
next_token(file, buf, sizeof(buf));
|
||||
if (buf[0] != '\0')
|
||||
{
|
||||
strcpy(HostCharset,buf);
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
case KEY_BASE:
|
||||
/* Read the base charset */
|
||||
next_token(file, buf, sizeof(buf));
|
||||
if (buf[0] != '\0')
|
||||
{
|
||||
strcpy(BaseCharset,buf);
|
||||
}
|
||||
break;
|
||||
case KEY_TABLE:
|
||||
/* Read the original charset */
|
||||
next_token(file, buf, sizeof(buf));
|
||||
if (buf[0] != '\0')
|
||||
{
|
||||
strcpy(OrigCharset,buf);
|
||||
/* Read the destination charset */
|
||||
next_token(file, buf, sizeof(buf));
|
||||
if (buf[0] != '\0')
|
||||
{
|
||||
strcpy(DestCharset,buf);
|
||||
/* Read the table filename */
|
||||
next_token(file, buf, sizeof(buf));
|
||||
if (buf[0] != '\0')
|
||||
{
|
||||
ChArray[ChIndex] = (struct CharsetItem *) malloc(sizeof(struct CharsetItem));
|
||||
strcpy(ChArray[ChIndex]->Orig,OrigCharset);
|
||||
strcpy(ChArray[ChIndex]->Dest,DestCharset);
|
||||
strcpy(ChArray[ChIndex]->Table,buf);
|
||||
ChIndex++;
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
read_through_eol(file);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
fclose(file);
|
||||
free(map_file);
|
||||
|
||||
for(i=0; i<ChIndex; i++)
|
||||
{
|
||||
if(!strcasecmp(BaseCharset,ChArray[i]->Orig) &&
|
||||
!strcasecmp(HostCharset,ChArray[i]->Dest))
|
||||
{
|
||||
strncpy(TableName,ChArray[i]->Table,79);
|
||||
}
|
||||
free((struct CharsetItem *) ChArray[i]);
|
||||
}
|
||||
*TableName = '\0';
|
||||
map_file = (char *) malloc((strlen(DataDir) +
|
||||
strlen(CHARSET_FILE) + 2) * sizeof(char));
|
||||
sprintf(map_file, "%s/%s", DataDir, CHARSET_FILE);
|
||||
file = fopen(map_file, "r");
|
||||
if (file == NULL)
|
||||
return;
|
||||
while (!eof)
|
||||
{
|
||||
c = getc(file);
|
||||
ungetc(c, file);
|
||||
if (c == EOF)
|
||||
eof = true;
|
||||
else
|
||||
{
|
||||
if (c == '#')
|
||||
read_through_eol(file);
|
||||
else
|
||||
{
|
||||
/* Read the key */
|
||||
next_token(file, buf, sizeof(buf));
|
||||
if (buf[0] != '\0')
|
||||
{
|
||||
if (strcasecmp(buf, "HostCharset") == 0)
|
||||
key = KEY_HOST;
|
||||
if (strcasecmp(buf, "BaseCharset") == 0)
|
||||
key = KEY_BASE;
|
||||
if (strcasecmp(buf, "RecodeTable") == 0)
|
||||
key = KEY_TABLE;
|
||||
switch (key)
|
||||
{
|
||||
case KEY_HOST:
|
||||
/* Read the host */
|
||||
next_token(file, buf, sizeof(buf));
|
||||
if (buf[0] != '\0')
|
||||
{
|
||||
if (InRange(buf, host))
|
||||
{
|
||||
/* Read the charset */
|
||||
next_token(file, buf, sizeof(buf));
|
||||
if (buf[0] != '\0')
|
||||
{
|
||||
strcpy(HostCharset, buf);
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
case KEY_BASE:
|
||||
/* Read the base charset */
|
||||
next_token(file, buf, sizeof(buf));
|
||||
if (buf[0] != '\0')
|
||||
{
|
||||
strcpy(BaseCharset, buf);
|
||||
}
|
||||
break;
|
||||
case KEY_TABLE:
|
||||
/* Read the original charset */
|
||||
next_token(file, buf, sizeof(buf));
|
||||
if (buf[0] != '\0')
|
||||
{
|
||||
strcpy(OrigCharset, buf);
|
||||
/* Read the destination charset */
|
||||
next_token(file, buf, sizeof(buf));
|
||||
if (buf[0] != '\0')
|
||||
{
|
||||
strcpy(DestCharset, buf);
|
||||
/* Read the table filename */
|
||||
next_token(file, buf, sizeof(buf));
|
||||
if (buf[0] != '\0')
|
||||
{
|
||||
ChArray[ChIndex] = (struct CharsetItem *) malloc(sizeof(struct CharsetItem));
|
||||
strcpy(ChArray[ChIndex]->Orig, OrigCharset);
|
||||
strcpy(ChArray[ChIndex]->Dest, DestCharset);
|
||||
strcpy(ChArray[ChIndex]->Table, buf);
|
||||
ChIndex++;
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
read_through_eol(file);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
fclose(file);
|
||||
free(map_file);
|
||||
|
||||
for (i = 0; i < ChIndex; i++)
|
||||
{
|
||||
if (!strcasecmp(BaseCharset, ChArray[i]->Orig) &&
|
||||
!strcasecmp(HostCharset, ChArray[i]->Dest))
|
||||
{
|
||||
strncpy(TableName, ChArray[i]->Table, 79);
|
||||
}
|
||||
free((struct CharsetItem *) ChArray[i]);
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
extern int
|
||||
hba_getauthmethod(SockAddr *raddr, char *database, char *auth_arg,
|
||||
UserAuth *auth_method)
|
||||
UserAuth *auth_method)
|
||||
{
|
||||
/*---------------------------------------------------------------------------
|
||||
Determine what authentication method should be used when accessing database
|
||||
|
|
|
@ -12,8 +12,8 @@
|
|||
int
|
||||
verify_password(char *auth_arg, char *user, char *password)
|
||||
{
|
||||
char *pw_file_fullname;
|
||||
FILE *pw_file;
|
||||
char *pw_file_fullname;
|
||||
FILE *pw_file;
|
||||
|
||||
pw_file_fullname = (char *) palloc(strlen(DataDir) + strlen(auth_arg) + 2);
|
||||
strcpy(pw_file_fullname, DataDir);
|
||||
|
@ -36,9 +36,12 @@ verify_password(char *auth_arg, char *user, char *password)
|
|||
|
||||
while (!feof(pw_file))
|
||||
{
|
||||
char pw_file_line[255], *p, *test_user, *test_pw;
|
||||
char pw_file_line[255],
|
||||
*p,
|
||||
*test_user,
|
||||
*test_pw;
|
||||
|
||||
fgets(pw_file_line, sizeof (pw_file_line), pw_file);
|
||||
fgets(pw_file_line, sizeof(pw_file_line), pw_file);
|
||||
p = pw_file_line;
|
||||
|
||||
test_user = strtok(p, ":");
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
*
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $Header: /cvsroot/pgsql/src/backend/libpq/Attic/portal.c,v 1.12 1997/12/09 03:10:43 scrappy Exp $
|
||||
* $Header: /cvsroot/pgsql/src/backend/libpq/Attic/portal.c,v 1.13 1998/02/26 04:31:51 momjian Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
|
@ -295,7 +295,7 @@ PQfnumberGroup(PortalBuffer *portal, int group_index, char *field_name)
|
|||
* the group index and field index.
|
||||
* --------------------------------
|
||||
*/
|
||||
char *
|
||||
char *
|
||||
PQfnameGroup(PortalBuffer *portal, int group_index, int field_number)
|
||||
{
|
||||
GroupBuffer *gbp;
|
||||
|
@ -451,7 +451,7 @@ PQfnumber(PortalBuffer *portal, int tuple_index, char *field_name)
|
|||
* PQfname - Return the name of a field
|
||||
* --------------------------------
|
||||
*/
|
||||
char *
|
||||
char *
|
||||
PQfname(PortalBuffer *portal, int tuple_index, int field_number)
|
||||
{
|
||||
GroupBuffer *gbp;
|
||||
|
@ -578,7 +578,7 @@ PQGetTupleBlock(PortalBuffer *portal,
|
|||
* PQgetvalue - Return an attribute (field) value
|
||||
* --------------------------------
|
||||
*/
|
||||
char *
|
||||
char *
|
||||
PQgetvalue(PortalBuffer *portal,
|
||||
int tuple_index,
|
||||
int field_number)
|
||||
|
@ -598,7 +598,7 @@ PQgetvalue(PortalBuffer *portal,
|
|||
* a copy. The CALLER is responsible for free'ing the data returned.
|
||||
* --------------------------------
|
||||
*/
|
||||
char *
|
||||
char *
|
||||
PQgetAttr(PortalBuffer *portal,
|
||||
int tuple_index,
|
||||
int field_number)
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
*
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $Header: /cvsroot/pgsql/src/backend/libpq/Attic/portalbuf.c,v 1.9 1997/12/09 03:10:45 scrappy Exp $
|
||||
* $Header: /cvsroot/pgsql/src/backend/libpq/Attic/portalbuf.c,v 1.10 1998/02/26 04:31:52 momjian Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
|
@ -235,7 +235,7 @@ pbuf_addTuple(int n)
|
|||
* pbuf_addTupleValueLengths - Allocate a tuple of n lengths (attributes)
|
||||
* --------------------------------
|
||||
*/
|
||||
int *
|
||||
int *
|
||||
pbuf_addTupleValueLengths(int n)
|
||||
{
|
||||
return (int *)
|
||||
|
@ -246,7 +246,7 @@ pbuf_addTupleValueLengths(int n)
|
|||
* pbuf_addValues - Allocate n bytes for a value
|
||||
* --------------------------------
|
||||
*/
|
||||
char *
|
||||
char *
|
||||
pbuf_addValues(int n)
|
||||
{
|
||||
return
|
||||
|
@ -510,7 +510,7 @@ pbuf_checkFnumber(GroupBuffer *group,
|
|||
* pbuf_findFname - Find the field name given the field index
|
||||
* --------------------------------
|
||||
*/
|
||||
char *
|
||||
char *
|
||||
pbuf_findFname(GroupBuffer *group,
|
||||
int field_number)
|
||||
{
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
*
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $Header: /cvsroot/pgsql/src/backend/libpq/pqcomm.c,v 1.38 1998/02/24 04:01:53 scrappy Exp $
|
||||
* $Header: /cvsroot/pgsql/src/backend/libpq/pqcomm.c,v 1.39 1998/02/26 04:31:53 momjian Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
|
@ -38,9 +38,9 @@
|
|||
|
||||
#include <stdio.h>
|
||||
#if defined(HAVE_STRING_H)
|
||||
# include <string.h>
|
||||
#include <string.h>
|
||||
#else
|
||||
# include <strings.h>
|
||||
#include <strings.h>
|
||||
#endif
|
||||
#include <signal.h>
|
||||
#include <errno.h>
|
||||
|
@ -558,7 +558,7 @@ pq_async_notify()
|
|||
* RETURNS: STATUS_OK or STATUS_ERROR
|
||||
*/
|
||||
|
||||
static char sock_path[MAXPGPATH+1] = "";
|
||||
static char sock_path[MAXPGPATH + 1] = "";
|
||||
|
||||
/* do_unlink()
|
||||
* Shutdown routine for backend connection
|
||||
|
@ -574,7 +574,7 @@ do_unlink()
|
|||
int
|
||||
StreamServerPort(char *hostName, short portName, int *fdP)
|
||||
{
|
||||
SockAddr saddr;
|
||||
SockAddr saddr;
|
||||
int fd,
|
||||
err,
|
||||
family;
|
||||
|
@ -613,22 +613,22 @@ StreamServerPort(char *hostName, short portName, int *fdP)
|
|||
{
|
||||
saddr.in.sin_addr.s_addr = htonl(INADDR_ANY);
|
||||
saddr.in.sin_port = htons(portName);
|
||||
len = sizeof (struct sockaddr_in);
|
||||
len = sizeof(struct sockaddr_in);
|
||||
}
|
||||
err = bind(fd, &saddr.sa, len);
|
||||
if (err < 0)
|
||||
{
|
||||
sprintf(PQerrormsg,
|
||||
"FATAL: StreamServerPort: bind() failed: errno=%d\n",
|
||||
errno);
|
||||
pqdebug("%s", PQerrormsg);
|
||||
strcat(PQerrormsg, "\tIs another postmaster already running on that port?\n");
|
||||
if (family == AF_UNIX)
|
||||
strcat(PQerrormsg, "\tIf not, remove socket node (/tmp/.s.PGSQL.<portnr>)and retry.\n");
|
||||
else
|
||||
strcat(PQerrormsg, "\tIf not, wait a few seconds and retry.\n");
|
||||
fputs(PQerrormsg, stderr);
|
||||
return (STATUS_ERROR);
|
||||
sprintf(PQerrormsg,
|
||||
"FATAL: StreamServerPort: bind() failed: errno=%d\n",
|
||||
errno);
|
||||
pqdebug("%s", PQerrormsg);
|
||||
strcat(PQerrormsg, "\tIs another postmaster already running on that port?\n");
|
||||
if (family == AF_UNIX)
|
||||
strcat(PQerrormsg, "\tIf not, remove socket node (/tmp/.s.PGSQL.<portnr>)and retry.\n");
|
||||
else
|
||||
strcat(PQerrormsg, "\tIf not, wait a few seconds and retry.\n");
|
||||
fputs(PQerrormsg, stderr);
|
||||
return (STATUS_ERROR);
|
||||
}
|
||||
|
||||
listen(fd, SOMAXCONN);
|
||||
|
@ -643,10 +643,10 @@ StreamServerPort(char *hostName, short portName, int *fdP)
|
|||
|
||||
*fdP = fd;
|
||||
if (family == AF_UNIX)
|
||||
{
|
||||
chmod(sock_path, 0777);
|
||||
atexit(do_unlink);
|
||||
}
|
||||
{
|
||||
chmod(sock_path, 0777);
|
||||
atexit(do_unlink);
|
||||
}
|
||||
return (STATUS_OK);
|
||||
}
|
||||
|
||||
|
|
|
@ -63,12 +63,12 @@
|
|||
int
|
||||
pqPutShort(int integer, FILE *f)
|
||||
{
|
||||
uint16 n;
|
||||
uint16 n;
|
||||
|
||||
#ifdef FRONTEND
|
||||
n = htons((uint16)integer);
|
||||
n = htons((uint16) integer);
|
||||
#else
|
||||
n = ((PG_PROTOCOL_MAJOR(FrontendProtocol) == 0) ? hton_s(integer) : htons((uint16)integer));
|
||||
n = ((PG_PROTOCOL_MAJOR(FrontendProtocol) == 0) ? hton_s(integer) : htons((uint16) integer));
|
||||
#endif
|
||||
|
||||
if (fwrite(&n, 2, 1, f) != 1)
|
||||
|
@ -81,12 +81,12 @@ pqPutShort(int integer, FILE *f)
|
|||
int
|
||||
pqPutLong(int integer, FILE *f)
|
||||
{
|
||||
uint32 n;
|
||||
uint32 n;
|
||||
|
||||
#ifdef FRONTEND
|
||||
n = htonl((uint32)integer);
|
||||
n = htonl((uint32) integer);
|
||||
#else
|
||||
n = ((PG_PROTOCOL_MAJOR(FrontendProtocol) == 0) ? hton_l(integer) : htonl((uint32)integer));
|
||||
n = ((PG_PROTOCOL_MAJOR(FrontendProtocol) == 0) ? hton_l(integer) : htonl((uint32) integer));
|
||||
#endif
|
||||
|
||||
if (fwrite(&n, 4, 1, f) != 1)
|
||||
|
@ -99,15 +99,15 @@ pqPutLong(int integer, FILE *f)
|
|||
int
|
||||
pqGetShort(int *result, FILE *f)
|
||||
{
|
||||
uint16 n;
|
||||
uint16 n;
|
||||
|
||||
if (fread(&n, 2, 1, f) != 1)
|
||||
return EOF;
|
||||
|
||||
#ifdef FRONTEND
|
||||
*result = (int)ntohs(n);
|
||||
*result = (int) ntohs(n);
|
||||
#else
|
||||
*result = (int)((PG_PROTOCOL_MAJOR(FrontendProtocol) == 0) ? ntoh_s(n) : ntohs(n));
|
||||
*result = (int) ((PG_PROTOCOL_MAJOR(FrontendProtocol) == 0) ? ntoh_s(n) : ntohs(n));
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
|
@ -117,15 +117,15 @@ pqGetShort(int *result, FILE *f)
|
|||
int
|
||||
pqGetLong(int *result, FILE *f)
|
||||
{
|
||||
uint32 n;
|
||||
uint32 n;
|
||||
|
||||
if (fread(&n, 4, 1, f) != 1)
|
||||
return EOF;
|
||||
|
||||
#ifdef FRONTEND
|
||||
*result = (int)ntohl(n);
|
||||
*result = (int) ntohl(n);
|
||||
#else
|
||||
*result = (int)((PG_PROTOCOL_MAJOR(FrontendProtocol) == 0) ? ntoh_l(n) : ntohl(n));
|
||||
*result = (int) ((PG_PROTOCOL_MAJOR(FrontendProtocol) == 0) ? ntoh_l(n) : ntohl(n));
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
|
@ -139,7 +139,7 @@ pqGetLong(int *result, FILE *f)
|
|||
int
|
||||
pqGetNBytes(char *s, size_t len, FILE *f)
|
||||
{
|
||||
int cnt;
|
||||
int cnt;
|
||||
|
||||
if (f == NULL)
|
||||
return EOF;
|
||||
|
@ -167,7 +167,7 @@ pqPutNBytes(const char *s, size_t len, FILE *f)
|
|||
int
|
||||
pqGetString(char *s, size_t len, FILE *f)
|
||||
{
|
||||
int c;
|
||||
int c;
|
||||
|
||||
if (f == NULL)
|
||||
return EOF;
|
||||
|
|
|
@ -8,7 +8,7 @@
|
|||
*
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $Header: /cvsroot/pgsql/src/backend/libpq/Attic/pqpacket.c,v 1.14 1998/01/31 20:12:09 scrappy Exp $
|
||||
* $Header: /cvsroot/pgsql/src/backend/libpq/Attic/pqpacket.c,v 1.15 1998/02/26 04:31:56 momjian Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
|
@ -33,30 +33,31 @@
|
|||
* Set up a packet read for the postmaster event loop.
|
||||
*/
|
||||
|
||||
void PacketReceiveSetup(Packet *pkt, void (*iodone)(), char *arg)
|
||||
void PacketReceiveSetup(Packet *pkt, void (*iodone) (), char *arg)
|
||||
{
|
||||
pkt->nrtodo = sizeof (pkt->len);
|
||||
pkt->ptr = (char *)&pkt->len;
|
||||
pkt->nrtodo = sizeof(pkt->len);
|
||||
pkt->ptr = (char *) &pkt->len;
|
||||
pkt->iodone = iodone;
|
||||
pkt->arg = arg;
|
||||
pkt->state = ReadingPacketLength;
|
||||
|
||||
/* Clear the destination. */
|
||||
|
||||
MemSet(&pkt->pkt, 0, sizeof (pkt->pkt));
|
||||
MemSet(&pkt->pkt, 0, sizeof(pkt->pkt));
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Read a packet fragment. Return STATUS_OK if the connection should stay
|
||||
* Read a packet fragment. Return STATUS_OK if the connection should stay
|
||||
* open.
|
||||
*/
|
||||
|
||||
int PacketReceiveFragment(Packet *pkt, int sock)
|
||||
int
|
||||
PacketReceiveFragment(Packet *pkt, int sock)
|
||||
{
|
||||
int got;
|
||||
int got;
|
||||
|
||||
if ((got = read(sock,pkt->ptr,pkt->nrtodo)) > 0)
|
||||
if ((got = read(sock, pkt->ptr, pkt->nrtodo)) > 0)
|
||||
{
|
||||
pkt->nrtodo -= got;
|
||||
pkt->ptr += got;
|
||||
|
@ -67,18 +68,18 @@ int PacketReceiveFragment(Packet *pkt, int sock)
|
|||
{
|
||||
pkt->len = ntohl(pkt->len);
|
||||
|
||||
if (pkt->len < sizeof (pkt->len) ||
|
||||
pkt->len > sizeof (pkt->len) + sizeof (pkt->pkt))
|
||||
if (pkt->len < sizeof(pkt->len) ||
|
||||
pkt->len > sizeof(pkt->len) + sizeof(pkt->pkt))
|
||||
{
|
||||
PacketSendError(pkt,"Invalid packet length");
|
||||
PacketSendError(pkt, "Invalid packet length");
|
||||
|
||||
return STATUS_OK;
|
||||
}
|
||||
|
||||
/* Set up for the rest of the packet. */
|
||||
|
||||
pkt->nrtodo = pkt->len - sizeof (pkt->len);
|
||||
pkt->ptr = (char *)&pkt->pkt;
|
||||
pkt->nrtodo = pkt->len - sizeof(pkt->len);
|
||||
pkt->ptr = (char *) &pkt->pkt;
|
||||
pkt->state = ReadingPacket;
|
||||
}
|
||||
|
||||
|
@ -93,8 +94,8 @@ int PacketReceiveFragment(Packet *pkt, int sock)
|
|||
if (pkt->iodone == NULL)
|
||||
return STATUS_ERROR;
|
||||
|
||||
(*pkt->iodone)(pkt->arg, pkt->len - sizeof (pkt->len),
|
||||
(char *)&pkt->pkt);
|
||||
(*pkt->iodone) (pkt->arg, pkt->len - sizeof(pkt->len),
|
||||
(char *) &pkt->pkt);
|
||||
}
|
||||
|
||||
return STATUS_OK;
|
||||
|
@ -116,10 +117,10 @@ int PacketReceiveFragment(Packet *pkt, int sock)
|
|||
* Set up a packet write for the postmaster event loop.
|
||||
*/
|
||||
|
||||
void PacketSendSetup(Packet *pkt, int nbytes, void (*iodone)(), char *arg)
|
||||
void PacketSendSetup(Packet *pkt, int nbytes, void (*iodone) (), char *arg)
|
||||
{
|
||||
pkt->nrtodo = nbytes;
|
||||
pkt->ptr = (char *)&pkt->pkt;
|
||||
pkt->ptr = (char *) &pkt->pkt;
|
||||
pkt->iodone = iodone;
|
||||
pkt->arg = arg;
|
||||
pkt->state = WritingPacket;
|
||||
|
@ -131,11 +132,12 @@ void PacketSendSetup(Packet *pkt, int nbytes, void (*iodone)(), char *arg)
|
|||
* open.
|
||||
*/
|
||||
|
||||
int PacketSendFragment(Packet *pkt, int sock)
|
||||
int
|
||||
PacketSendFragment(Packet *pkt, int sock)
|
||||
{
|
||||
int done;
|
||||
int done;
|
||||
|
||||
if ((done = write(sock,pkt->ptr,pkt->nrtodo)) > 0)
|
||||
if ((done = write(sock, pkt->ptr, pkt->nrtodo)) > 0)
|
||||
{
|
||||
pkt->nrtodo -= done;
|
||||
pkt->ptr += done;
|
||||
|
@ -151,7 +153,7 @@ int PacketSendFragment(Packet *pkt, int sock)
|
|||
if (pkt->iodone == NULL)
|
||||
return STATUS_ERROR;
|
||||
|
||||
(*pkt->iodone)(pkt->arg);
|
||||
(*pkt->iodone) (pkt->arg);
|
||||
}
|
||||
|
||||
return STATUS_OK;
|
||||
|
@ -173,12 +175,13 @@ int PacketSendFragment(Packet *pkt, int sock)
|
|||
* Send an error message from the postmaster to the frontend.
|
||||
*/
|
||||
|
||||
void PacketSendError(Packet *pkt, char *errormsg)
|
||||
void
|
||||
PacketSendError(Packet *pkt, char *errormsg)
|
||||
{
|
||||
fprintf(stderr, "%s\n", errormsg);
|
||||
|
||||
pkt->pkt.em.data[0] = 'E';
|
||||
StrNCpy(&pkt->pkt.em.data[1], errormsg, sizeof (pkt->pkt.em.data) - 2);
|
||||
StrNCpy(&pkt->pkt.em.data[1], errormsg, sizeof(pkt->pkt.em.data) - 2);
|
||||
|
||||
/*
|
||||
* The NULL i/o callback will cause the connection to be broken when
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
*
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $Header: /cvsroot/pgsql/src/backend/main/main.c,v 1.13 1998/02/05 04:21:56 scrappy Exp $
|
||||
* $Header: /cvsroot/pgsql/src/backend/main/main.c,v 1.14 1998/02/26 04:31:58 momjian Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
|
@ -36,17 +36,19 @@ main(int argc, char *argv[])
|
|||
int len;
|
||||
|
||||
#if defined(alpha)
|
||||
# ifdef NOFIXADE
|
||||
int buffer[] = {SSIN_UACPROC, UAC_SIGBUS};
|
||||
# endif /* NOFIXADE */
|
||||
# ifdef NOPRINTADE
|
||||
int buffer[] = {SSIN_UACPROC, UAC_NOPRINT};
|
||||
# endif /* NOPRINTADE */
|
||||
#ifdef NOFIXADE
|
||||
int buffer[] = {SSIN_UACPROC, UAC_SIGBUS};
|
||||
|
||||
#endif /* NOFIXADE */
|
||||
#ifdef NOPRINTADE
|
||||
int buffer[] = {SSIN_UACPROC, UAC_NOPRINT};
|
||||
|
||||
#endif /* NOPRINTADE */
|
||||
#endif
|
||||
|
||||
#ifdef USE_LOCALE
|
||||
setlocale(LC_CTYPE, ""); /* take locale information from an
|
||||
* environment */
|
||||
* environment */
|
||||
setlocale(LC_COLLATE, "");
|
||||
setlocale(LC_MONETARY, "");
|
||||
#endif
|
||||
|
@ -58,18 +60,18 @@ main(int argc, char *argv[])
|
|||
*/
|
||||
|
||||
#if defined(ultrix4)
|
||||
syscall(SYS_sysmips, MIPS_FIXADE, 0, NULL, NULL, NULL);
|
||||
syscall(SYS_sysmips, MIPS_FIXADE, 0, NULL, NULL, NULL);
|
||||
#endif
|
||||
|
||||
#if defined(alpha)
|
||||
if (setsysinfo(SSI_NVPAIRS, buffer, 1, (caddr_t) NULL,
|
||||
(unsigned long) NULL) < 0)
|
||||
(unsigned long) NULL) < 0)
|
||||
{
|
||||
elog(NOTICE, "setsysinfo failed: %d\n", errno);
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#endif /* NOFIXADE || NOPRINTADE */
|
||||
#endif /* NOFIXADE || NOPRINTADE */
|
||||
|
||||
/*
|
||||
* use one executable for both postgres and postmaster, invoke one or
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
*
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $Header: /cvsroot/pgsql/src/backend/nodes/copyfuncs.c,v 1.40 1998/02/23 02:54:11 momjian Exp $
|
||||
* $Header: /cvsroot/pgsql/src/backend/nodes/copyfuncs.c,v 1.41 1998/02/26 04:32:04 momjian Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
|
@ -35,7 +35,7 @@
|
|||
* this copy function only copies the "lcons-cells" of the list but not
|
||||
* its contents. (good for list of pointers as well as list of integers).
|
||||
*/
|
||||
List *
|
||||
List *
|
||||
listCopy(List *list)
|
||||
{
|
||||
List *newlist = NIL;
|
||||
|
@ -79,8 +79,8 @@ listCopy(List *list)
|
|||
static void
|
||||
CopyPlanFields(Plan *from, Plan *newnode)
|
||||
{
|
||||
extern List *SS_pull_subplan (void *expr);
|
||||
|
||||
extern List *SS_pull_subplan(void *expr);
|
||||
|
||||
newnode->cost = from->cost;
|
||||
newnode->plan_size = from->plan_size;
|
||||
newnode->plan_width = from->plan_width;
|
||||
|
@ -90,12 +90,12 @@ CopyPlanFields(Plan *from, Plan *newnode)
|
|||
newnode->qual = copyObject(from->qual);
|
||||
newnode->lefttree = copyObject(from->lefttree);
|
||||
newnode->righttree = copyObject(from->righttree);
|
||||
newnode->extParam = listCopy (from->extParam);
|
||||
newnode->locParam = listCopy (from->locParam);
|
||||
newnode->chgParam = listCopy (from->chgParam);
|
||||
newnode->extParam = listCopy(from->extParam);
|
||||
newnode->locParam = listCopy(from->locParam);
|
||||
newnode->chgParam = listCopy(from->chgParam);
|
||||
Node_Copy(from, newnode, initPlan);
|
||||
if ( from->subPlan != NULL )
|
||||
newnode->subPlan = SS_pull_subplan (newnode->qual);
|
||||
if (from->subPlan != NULL)
|
||||
newnode->subPlan = SS_pull_subplan(newnode->qual);
|
||||
else
|
||||
newnode->subPlan = NULL;
|
||||
newnode->nParamExec = from->nParamExec;
|
||||
|
@ -471,7 +471,7 @@ _copySort(Sort *from)
|
|||
Node_Copy(from, newnode, sortstate);
|
||||
Node_Copy(from, newnode, psortstate);
|
||||
newnode->cleaned = from->cleaned;
|
||||
|
||||
|
||||
return newnode;
|
||||
}
|
||||
|
||||
|
@ -484,13 +484,13 @@ static Group *
|
|||
_copyGroup(Group *from)
|
||||
{
|
||||
Group *newnode = makeNode(Group);
|
||||
|
||||
|
||||
CopyPlanFields((Plan *) from, (Plan *) newnode);
|
||||
|
||||
newnode->tuplePerGroup = from->tuplePerGroup;
|
||||
newnode->numCols = from->numCols;
|
||||
newnode->grpColIdx = palloc (from->numCols * sizeof (AttrNumber));
|
||||
memcpy (newnode->grpColIdx, from->grpColIdx, from->numCols * sizeof (AttrNumber));
|
||||
newnode->grpColIdx = palloc(from->numCols * sizeof(AttrNumber));
|
||||
memcpy(newnode->grpColIdx, from->grpColIdx, from->numCols * sizeof(AttrNumber));
|
||||
Node_Copy(from, newnode, grpstate);
|
||||
|
||||
return newnode;
|
||||
|
@ -520,12 +520,12 @@ _copyAgg(Agg *from)
|
|||
static GroupClause *
|
||||
_copyGroupClause(GroupClause *from)
|
||||
{
|
||||
GroupClause *newnode = makeNode(GroupClause);
|
||||
GroupClause *newnode = makeNode(GroupClause);
|
||||
|
||||
Node_Copy(from, newnode, entry);
|
||||
newnode->grpOpoid = from->grpOpoid;
|
||||
Node_Copy(from, newnode, entry);
|
||||
newnode->grpOpoid = from->grpOpoid;
|
||||
|
||||
return newnode;
|
||||
return newnode;
|
||||
}
|
||||
|
||||
|
||||
|
@ -592,13 +592,13 @@ _copyHash(Hash *from)
|
|||
static SubPlan *
|
||||
_copySubPlan(SubPlan *from)
|
||||
{
|
||||
SubPlan *newnode = makeNode(SubPlan);
|
||||
|
||||
SubPlan *newnode = makeNode(SubPlan);
|
||||
|
||||
Node_Copy(from, newnode, plan);
|
||||
newnode->plan_id = from->plan_id;
|
||||
Node_Copy(from, newnode, rtable);
|
||||
newnode->setParam = listCopy (from->setParam);
|
||||
newnode->parParam = listCopy (from->parParam);
|
||||
newnode->setParam = listCopy(from->setParam);
|
||||
newnode->parParam = listCopy(from->parParam);
|
||||
Node_Copy(from, newnode, sublink);
|
||||
newnode->shutdown = from->shutdown;
|
||||
|
||||
|
@ -761,7 +761,7 @@ _copyConst(Const *from)
|
|||
* XXX super cheesy hack until parser/planner
|
||||
* puts in the right values here.
|
||||
*
|
||||
* But I like cheese.
|
||||
* But I like cheese.
|
||||
* ----------------
|
||||
*/
|
||||
if (!from->constisnull && cached_type != from->consttype)
|
||||
|
@ -931,7 +931,7 @@ _copyAggreg(Aggreg *from)
|
|||
static SubLink *
|
||||
_copySubLink(SubLink *from)
|
||||
{
|
||||
SubLink *newnode = makeNode(SubLink);
|
||||
SubLink *newnode = makeNode(SubLink);
|
||||
|
||||
/* ----------------
|
||||
* copy remainder of node
|
||||
|
@ -1049,7 +1049,7 @@ _copyRel(Rel *from)
|
|||
newnode->relam = from->relam;
|
||||
newnode->indproc = from->indproc;
|
||||
Node_Copy(from, newnode, indpred);
|
||||
|
||||
|
||||
if (from->ordering)
|
||||
{
|
||||
for (len = 0; from->ordering[len] != 0; len++)
|
||||
|
@ -1389,7 +1389,7 @@ _copyHInfo(HInfo *from)
|
|||
* copy remainder of node
|
||||
* ----------------
|
||||
*/
|
||||
CopyJoinMethodFields((JoinMethod *)from, (JoinMethod *)newnode);
|
||||
CopyJoinMethodFields((JoinMethod *) from, (JoinMethod *) newnode);
|
||||
newnode->hashop = from->hashop;
|
||||
|
||||
return newnode;
|
||||
|
@ -1408,7 +1408,7 @@ _copyMInfo(MInfo *from)
|
|||
* copy remainder of node
|
||||
* ----------------
|
||||
*/
|
||||
CopyJoinMethodFields((JoinMethod *)from, (JoinMethod *)newnode);
|
||||
CopyJoinMethodFields((JoinMethod *) from, (JoinMethod *) newnode);
|
||||
Node_Copy(from, newnode, m_ordering);
|
||||
|
||||
return newnode;
|
||||
|
@ -1498,9 +1498,9 @@ _copyRangeTblEntry(RangeTblEntry *from)
|
|||
newnode->relid = from->relid;
|
||||
newnode->inh = from->inh;
|
||||
newnode->inFromCl = from->inFromCl;
|
||||
newnode->skipAcl = from->skipAcl;
|
||||
newnode->skipAcl = from->skipAcl;
|
||||
|
||||
|
||||
|
||||
return newnode;
|
||||
}
|
||||
|
||||
|
@ -1545,7 +1545,7 @@ static Query *
|
|||
_copyQuery(Query *from)
|
||||
{
|
||||
Query *newnode = makeNode(Query);
|
||||
|
||||
|
||||
newnode->commandType = from->commandType;
|
||||
if (from->utilityStmt && nodeTag(from->utilityStmt) == T_NotifyStmt)
|
||||
{
|
||||
|
@ -1576,13 +1576,14 @@ _copyQuery(Query *from)
|
|||
|
||||
if (from->unionClause)
|
||||
{
|
||||
List *ulist, *temp_list = NIL;
|
||||
List *ulist,
|
||||
*temp_list = NIL;
|
||||
|
||||
foreach(ulist, from->unionClause)
|
||||
temp_list = lappend(temp_list,copyObject(lfirst(ulist)));
|
||||
temp_list = lappend(temp_list, copyObject(lfirst(ulist)));
|
||||
newnode->unionClause = temp_list;
|
||||
}
|
||||
|
||||
|
||||
return newnode;
|
||||
}
|
||||
|
||||
|
@ -1625,7 +1626,7 @@ _copyValue(Value *from)
|
|||
* recursively copies its items.
|
||||
* ----------------
|
||||
*/
|
||||
void *
|
||||
void *
|
||||
copyObject(void *from)
|
||||
{
|
||||
void *retval;
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
*
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $Header: /cvsroot/pgsql/src/backend/nodes/equalfuncs.c,v 1.15 1998/02/13 03:27:44 vadim Exp $
|
||||
* $Header: /cvsroot/pgsql/src/backend/nodes/equalfuncs.c,v 1.16 1998/02/26 04:32:07 momjian Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
|
@ -512,7 +512,7 @@ _equalSubPlan(SubPlan *a, SubPlan *b)
|
|||
|
||||
if (!equal((a->sublink->oper), (b->sublink->oper)))
|
||||
return (false);
|
||||
|
||||
|
||||
return (true);
|
||||
}
|
||||
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue