1
0
mirror of https://github.com/postgres/postgres.git synced 2025-07-31 22:04:40 +03:00

Massive commit to run PGINDENT on all *.c and *.h files.

This commit is contained in:
Bruce Momjian
1997-09-07 05:04:48 +00:00
parent 8fecd4febf
commit 1ccd423235
687 changed files with 150775 additions and 136888 deletions

View File

@ -41,7 +41,7 @@
#include "utils/elog.h"
static int32
array_iterator(Oid elemtype, Oid proc, int and, ArrayType *array, Datum value)
array_iterator(Oid elemtype, Oid proc, int and, ArrayType * array, Datum value)
{
HeapTuple typ_tuple;
TypeTupleForm typ_struct;
@ -49,28 +49,34 @@ array_iterator(Oid elemtype, Oid proc, int and, ArrayType *array, Datum value)
int typlen;
func_ptr proc_fn;
int pronargs;
int nitems, i, result;
int ndim, *dim;
int nitems,
i,
result;
int ndim,
*dim;
char *p;
/* Sanity checks */
if ((array == (ArrayType *) NULL)
|| (ARR_IS_LO(array) == true)) {
|| (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) {
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(WARN,"array_iterator: cache lookup failed for type %d", elemtype);
typ_tuple = SearchSysCacheTuple(TYPOID, ObjectIdGetDatum(elemtype), 0, 0, 0);
if (!HeapTupleIsValid(typ_tuple))
{
elog(WARN, "array_iterator: cache lookup failed for type %d", elemtype);
return 0;
}
typ_struct = (TypeTupleForm) GETSTRUCT(typ_tuple);
@ -80,7 +86,8 @@ array_iterator(Oid elemtype, Oid proc, int and, ArrayType *array, Datum value)
/* Lookup the function entry point */
proc_fn == (func_ptr) NULL;
fmgr_info(proc, &proc_fn, &pronargs);
if ((proc_fn == NULL) || (pronargs != 2)) {
if ((proc_fn == NULL) || (pronargs != 2))
{
elog(WARN, "array_iterator: fmgr_info lookup failed for oid %d", proc);
return (0);
}
@ -88,43 +95,59 @@ array_iterator(Oid elemtype, Oid proc, int and, ArrayType *array, Datum value)
/* 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) {
for (i = 0; i < nitems; i++)
{
if (typbyval)
{
switch (typlen)
{
case 1:
result = (int) (*proc_fn)(*p, value);
result = (int) (*proc_fn) (*p, value);
break;
case 2:
result = (int) (*proc_fn)(* (int16 *) p, value);
result = (int) (*proc_fn) (*(int16 *) p, value);
break;
case 3:
case 4:
result = (int) (*proc_fn)(* (int32 *) p, value);
result = (int) (*proc_fn) (*(int32 *) p, value);
break;
}
p += typlen;
} else {
result = (int) (*proc_fn)(p, value);
if (typlen > 0) {
}
else
{
result = (int) (*proc_fn) (p, value);
if (typlen > 0)
{
p += typlen;
} else {
p += INTALIGN(* (int32 *) p);
}
else
{
p += INTALIGN(*(int32 *) p);
}
}
if (result) {
if (!and) {
if (result)
{
if (!and)
{
return (1);
}
} else {
if (and) {
}
else
{
if (and)
{
return (0);
}
}
}
if (and && result) {
if (and && result)
{
return (1);
} else {
}
else
{
return (0);
}
}
@ -134,39 +157,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);
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);
array, (Datum) value);
}
int32
array_textregexeq(ArrayType *array, char* value)
array_textregexeq(ArrayType * array, char *value)
{
return array_iterator((Oid) 25, /* text */
(Oid) 81, /* textregexeq */
0, /* logical or */
array, (Datum)value);
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) 81, /* textregexeq */
1, /* logical and */
array, (Datum)value);
array, (Datum) value);
}
/*
@ -175,39 +198,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) 490, /* char16eq */
0, /* logical or */
array, (Datum)value);
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) 490, /* char16eq */
1, /* logical and */
array, (Datum)value);
array, (Datum) value);
}
int32
array_char16regexeq(ArrayType *array, char* value)
array_char16regexeq(ArrayType * array, char *value)
{
return array_iterator((Oid) 20, /* char16 */
(Oid) 700, /* char16regexeq */
0, /* logical or */
array, (Datum)value);
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) 700, /* char16regexeq */
1, /* logical and */
array, (Datum)value);
array, (Datum) value);
}
/*
@ -215,37 +238,37 @@ array_all_char16regexeq(ArrayType *array, char* value)
*/
int32
array_int4eq(ArrayType *array, int4 value)
array_int4eq(ArrayType * array, int4 value)
{
return array_iterator((Oid) 23, /* int4 */
(Oid) 65, /* int4eq */
0, /* logical or */
array, (Datum)value);
array, (Datum) value);
}
int32
array_all_int4eq(ArrayType *array, int4 value)
array_all_int4eq(ArrayType * array, int4 value)
{
return array_iterator((Oid) 23, /* int4 */
(Oid) 65, /* int4eq */
1, /* logical and */
array, (Datum)value);
array, (Datum) value);
}
int32
array_int4gt(ArrayType *array, int4 value)
array_int4gt(ArrayType * array, int4 value)
{
return array_iterator((Oid) 23, /* int4 */
(Oid) 147, /* int4gt */
0, /* logical or */
array, (Datum)value);
array, (Datum) value);
}
int32
array_all_int4gt(ArrayType *array, int4 value)
array_all_int4gt(ArrayType * array, int4 value)
{
return array_iterator((Oid) 23, /* int4 */
(Oid) 147, /* int4gt */
1, /* logical and */
array, (Datum)value);
array, (Datum) value);
}

View File

@ -13,14 +13,17 @@
#include "utils/datetime.h"
TimeADT *time_difference(TimeADT * time1, TimeADT * time2)
TimeADT *
time_difference(TimeADT * time1, TimeADT * time2)
{
TimeADT *result = (TimeADT *) palloc(sizeof(TimeADT));
*result = *time1 - *time2;
return (result);
}
TimeADT *currenttime()
TimeADT *
currenttime()
{
time_t current_time;
struct tm *tm;
@ -28,69 +31,79 @@ TimeADT *currenttime()
current_time = time(NULL);
tm = localtime(&current_time);
*result = ((((tm->tm_hour*60)+tm->tm_min)*60)+tm->tm_sec);
*result = ((((tm->tm_hour * 60) + tm->tm_min) * 60) + tm->tm_sec);
return (result);
}
DateADT currentdate()
DateADT
currentdate()
{
time_t current_time;
struct tm *tm;
DateADT result;
current_time = time(NULL);
tm = localtime(&current_time);
result = date2j(tm->tm_year,tm->tm_mon + 1,tm->tm_mday) -
date2j(100,1,1);
result = date2j(tm->tm_year, tm->tm_mon + 1, tm->tm_mday) -
date2j(100, 1, 1);
return (result);
}
int4 hours(TimeADT * time)
int4
hours(TimeADT * time)
{
return(*time / (60*60));
return (*time / (60 * 60));
}
int4 minutes(TimeADT * time)
int4
minutes(TimeADT * time)
{
return(((int) (*time / 60)) % 60);
return (((int) (*time / 60)) % 60);
}
int4 seconds(TimeADT * time)
int4
seconds(TimeADT * time)
{
return(((int) *time) % 60);
return (((int) *time) % 60);
}
int4 day(DateADT *date)
int4
day(DateADT * date)
{
struct tm tm;
j2date( (*date + date2j(2000,1,1)),
j2date((*date + date2j(2000, 1, 1)),
&tm.tm_year, &tm.tm_mon, &tm.tm_mday);
return (tm.tm_mday);
}
int4 month(DateADT *date)
int4
month(DateADT * date)
{
struct tm tm;
j2date( (*date + date2j(2000,1,1)),
j2date((*date + date2j(2000, 1, 1)),
&tm.tm_year, &tm.tm_mon, &tm.tm_mday);
return (tm.tm_mon);
}
int4 year(DateADT *date)
int4
year(DateADT * date)
{
struct tm tm;
j2date( (*date + date2j(2000,1,1)),
j2date((*date + date2j(2000, 1, 1)),
&tm.tm_year, &tm.tm_mon, &tm.tm_mday);
return (tm.tm_year);
}
int4 asminutes(TimeADT * time)
int4
asminutes(TimeADT * time)
{
int seconds = (int) *time;
return (seconds / 60);
}
int4 asseconds(TimeADT * time)
int4
asseconds(TimeADT * time)
{
int seconds = (int) *time;

View File

@ -26,52 +26,57 @@
#endif
#ifndef HAVE_64BIT_INTS
typedef char[8] int64;
typedef char [8] int64;
#elif defined(__alpha)
typedef long int int64;
#define INT64_FORMAT "%ld"
#elif defined(__GNUC__)
typedef long long int int64;
#define INT64_FORMAT "%Ld"
#else
typedef long int int64;
#define INT64_FORMAT "%ld"
#endif
int64 *int8in(char *str);
char *int8out(int64 *val);
char *int8out(int64 * val);
bool int8eq(int64 *val1, int64 *val2);
bool int8ne(int64 *val1, int64 *val2);
bool int8lt(int64 *val1, int64 *val2);
bool int8gt(int64 *val1, int64 *val2);
bool int8le(int64 *val1, int64 *val2);
bool int8ge(int64 *val1, int64 *val2);
bool int8eq(int64 * val1, int64 * val2);
bool int8ne(int64 * val1, int64 * val2);
bool int8lt(int64 * val1, int64 * val2);
bool int8gt(int64 * val1, int64 * val2);
bool int8le(int64 * val1, int64 * val2);
bool int8ge(int64 * val1, int64 * val2);
bool int84eq(int64 *val1, int32 val2);
bool int84ne(int64 *val1, int32 val2);
bool int84lt(int64 *val1, int32 val2);
bool int84gt(int64 *val1, int32 val2);
bool int84le(int64 *val1, int32 val2);
bool int84ge(int64 *val1, int32 val2);
bool int84eq(int64 * val1, int32 val2);
bool int84ne(int64 * val1, int32 val2);
bool int84lt(int64 * val1, int32 val2);
bool int84gt(int64 * val1, int32 val2);
bool int84le(int64 * val1, int32 val2);
bool int84ge(int64 * val1, int32 val2);
int64 *int8um(int64 *val);
int64 *int8pl(int64 *val1, int64 *val2);
int64 *int8mi(int64 *val1, int64 *val2);
int64 *int8mul(int64 *val1, int64 *val2);
int64 *int8div(int64 *val1, int64 *val2);
int64 *int8um(int64 * val);
int64 *int8pl(int64 * val1, int64 * val2);
int64 *int8mi(int64 * val1, int64 * val2);
int64 *int8mul(int64 * val1, int64 * val2);
int64 *int8div(int64 * val1, int64 * val2);
int64 *int48(int32 val);
int32 int84(int64 *val);
int32 int84(int64 * val);
#if FALSE
int64 *int28(int16 val);
int16 int82(int64 *val);
int16 int82(int64 * val);
#endif
float64 i8tod(int64 *val);
float64 i8tod(int64 * val);
int64 *dtoi8(float64 val);
#if USE_LOCAL_CODE
@ -98,52 +103,54 @@ int64 *dtoi8(float64 val);
/* int8in()
*/
int64 *int8in(char *str)
int64 *
int8in(char *str)
{
int64 *result = PALLOCTYPE(int64);
#if HAVE_64BIT_INTS
if (!PointerIsValid(str))
elog (WARN,"Bad (null) int8 external representation",NULL);
elog(WARN, "Bad (null) int8 external representation", NULL);
if (sscanf(str, INT64_FORMAT, result) != 1)
elog(WARN,"Bad int8 external representation '%s'",str);
elog(WARN, "Bad int8 external representation '%s'", str);
#else
elog(WARN,"64-bit integers are not supported",NULL);
elog(WARN, "64-bit integers are not supported", NULL);
result = NULL;
#endif
return(result);
return (result);
} /* int8in() */
/* int8out()
*/
char *int8out(int64 *val)
char *
int8out(int64 * val)
{
char *result;
int len;
char buf[MAXINT8LEN+1];
char buf[MAXINT8LEN + 1];
#if HAVE_64BIT_INTS
if (!PointerIsValid(val))
return(NULL);
return (NULL);
if ((len = snprintf( buf, MAXINT8LEN, INT64_FORMAT, *val)) < 0)
elog (WARN,"Unable to format int8",NULL);
if ((len = snprintf(buf, MAXINT8LEN, INT64_FORMAT, *val)) < 0)
elog(WARN, "Unable to format int8", NULL);
result = PALLOC(len+1);
result = PALLOC(len + 1);
strcpy(result, buf);
#else
elog(WARN,"64-bit integers are not supported",NULL);
elog(WARN, "64-bit integers are not supported", NULL);
result = NULL;
#endif
return( result);
return (result);
} /* int8out() */
@ -154,68 +161,80 @@ char *int8out(int64 *val)
/* int8relop()
* Is val1 relop val2?
*/
bool int8eq(int64 *val1, int64 *val2)
bool
int8eq(int64 * val1, int64 * val2)
{
return(*val1 == *val2);
return (*val1 == *val2);
} /* int8eq() */
bool int8ne(int64 *val1, int64 *val2)
bool
int8ne(int64 * val1, int64 * val2)
{
return(*val1 != *val2);
return (*val1 != *val2);
} /* int8ne() */
bool int8lt(int64 *val1, int64 *val2)
bool
int8lt(int64 * val1, int64 * val2)
{
return(*val1 < *val2);
return (*val1 < *val2);
} /* int8lt() */
bool int8gt(int64 *val1, int64 *val2)
bool
int8gt(int64 * val1, int64 * val2)
{
return(*val1 > *val2);
return (*val1 > *val2);
} /* int8gt() */
bool int8le(int64 *val1, int64 *val2)
bool
int8le(int64 * val1, int64 * val2)
{
return(*val1 <= *val2);
return (*val1 <= *val2);
} /* int8le() */
bool int8ge(int64 *val1, int64 *val2)
bool
int8ge(int64 * val1, int64 * val2)
{
return(*val1 >= *val2);
return (*val1 >= *val2);
} /* int8ge() */
/* int84relop()
* Is 64-bit val1 relop 32-bit val2?
*/
bool int84eq(int64 *val1, int32 val2)
bool
int84eq(int64 * val1, int32 val2)
{
return(*val1 == val2);
return (*val1 == val2);
} /* int84eq() */
bool int84ne(int64 *val1, int32 val2)
bool
int84ne(int64 * val1, int32 val2)
{
return(*val1 != val2);
return (*val1 != val2);
} /* int84ne() */
bool int84lt(int64 *val1, int32 val2)
bool
int84lt(int64 * val1, int32 val2)
{
return(*val1 < val2);
return (*val1 < val2);
} /* int84lt() */
bool int84gt(int64 *val1, int32 val2)
bool
int84gt(int64 * val1, int32 val2)
{
return(*val1 > val2);
return (*val1 > val2);
} /* int84gt() */
bool int84le(int64 *val1, int32 val2)
bool
int84le(int64 * val1, int32 val2)
{
return(*val1 <= val2);
return (*val1 <= val2);
} /* int84le() */
bool int84ge(int64 *val1, int32 val2)
bool
int84ge(int64 * val1, int32 val2)
{
return(*val1 >= val2);
return (*val1 >= val2);
} /* int84ge() */
@ -223,19 +242,21 @@ bool int84ge(int64 *val1, int32 val2)
* Arithmetic operators on 64-bit integers.
*---------------------------------------------------------*/
int64 *int8um(int64 *val)
int64 *
int8um(int64 * val)
{
int64 *result = PALLOCTYPE(int64);
if (!PointerIsValid(val))
return NULL;
*result = (- *val);
*result = (-*val);
return(result);
return (result);
} /* int8um() */
int64 *int8pl(int64 *val1, int64 *val2)
int64 *
int8pl(int64 * val1, int64 * val2)
{
int64 *result = PALLOCTYPE(int64);
@ -244,10 +265,11 @@ int64 *int8pl(int64 *val1, int64 *val2)
*result = *val1 + *val2;
return(result);
return (result);
} /* int8pl() */
int64 *int8mi(int64 *val1, int64 *val2)
int64 *
int8mi(int64 * val1, int64 * val2)
{
int64 *result = PALLOCTYPE(int64);
@ -256,10 +278,11 @@ int64 *int8mi(int64 *val1, int64 *val2)
*result = *val1 - *val2;
return(result);
return (result);
} /* int8mi() */
int64 *int8mul(int64 *val1, int64 *val2)
int64 *
int8mul(int64 * val1, int64 * val2)
{
int64 *result = PALLOCTYPE(int64);
@ -268,10 +291,11 @@ int64 *int8mul(int64 *val1, int64 *val2)
*result = *val1 * *val2;
return(result);
return (result);
} /* int8mul() */
int64 *int8div(int64 *val1, int64 *val2)
int64 *
int8div(int64 * val1, int64 * val2)
{
int64 *result = PALLOCTYPE(int64);
@ -280,7 +304,7 @@ int64 *int8div(int64 *val1, int64 *val2)
*result = *val1 / *val2;
return(result);
return (result);
} /* int8div() */
@ -288,74 +312,80 @@ int64 *int8div(int64 *val1, int64 *val2)
* Conversion operators.
*---------------------------------------------------------*/
int64 *int48(int32 val)
int64 *
int48(int32 val)
{
int64 *result = PALLOCTYPE(int64);
*result = val;
return(result);
return (result);
} /* int48() */
int32 int84(int64 *val)
int32
int84(int64 * val)
{
int32 result;
if (!PointerIsValid(val))
elog(WARN,"Invalid (null) int64, can't convert int8 to int4",NULL);
elog(WARN, "Invalid (null) int64, can't convert int8 to int4", NULL);
if ((*val < INT_MIN) || (*val > INT_MAX))
elog(WARN,"int8 conversion to int4 is out of range",NULL);
elog(WARN, "int8 conversion to int4 is out of range", NULL);
result = *val;
return(result);
return (result);
} /* int84() */
#if FALSE
int64 *int28(int16 val)
int64 *
int28(int16 val)
{
int64 *result;
if (!PointerIsValid(result = PALLOCTYPE(int64)))
elog(WARN,"Memory allocation failed, can't convert int8 to int2",NULL);
elog(WARN, "Memory allocation failed, can't convert int8 to int2", NULL);
*result = val;
return(result);
return (result);
} /* int28() */
int16 int82(int64 *val)
int16
int82(int64 * val)
{
int16 result;
if (!PointerIsValid(val))
elog(WARN,"Invalid (null) int8, can't convert to int2",NULL);
elog(WARN, "Invalid (null) int8, can't convert to int2", NULL);
result = *val;
return(result);
return (result);
} /* int82() */
#endif
float64 i8tod(int64 *val)
float64
i8tod(int64 * val)
{
float64 result = PALLOCTYPE(float64data);
*result = *val;
return(result);
return (result);
} /* i8tod() */
int64 *dtoi8(float64 val)
int64 *
dtoi8(float64 val)
{
int64 *result = PALLOCTYPE(int64);
if ((*val < (-pow(2,64)+1)) || (*val > (pow(2,64)-1)))
elog(WARN,"Floating point conversion to int64 is out of range",NULL);
if ((*val < (-pow(2, 64) + 1)) || (*val > (pow(2, 64) - 1)))
elog(WARN, "Floating point conversion to int64 is out of range", NULL);
*result = *val;
return(result);
return (result);
} /* dtoi8() */

View File

@ -20,39 +20,41 @@
**------------------------------------------------------------------------*/
/*VARARGS*/
void halt(va_alist)
void
halt(va_alist)
va_dcl
{
va_list arg_ptr;
char *format, *pstr;
void (*sig_func)();
char *format,
*pstr;
void (*sig_func) ();
va_start(arg_ptr);
format = va_arg(arg_ptr,char *);
if (strncmp(format,"PERROR", 6) != 0)
vfprintf(stderr,format,arg_ptr);
format = va_arg(arg_ptr, char *);
if (strncmp(format, "PERROR", 6) != 0)
vfprintf(stderr, format, arg_ptr);
else
{
for (pstr=format+6; *pstr == ' ' || *pstr == ':'; pstr++)
for (pstr = format + 6; *pstr == ' ' || *pstr == ':'; pstr++)
;
vfprintf(stderr,pstr,arg_ptr);
vfprintf(stderr, pstr, arg_ptr);
perror("");
}
va_end(arg_ptr);
fflush(stderr);
/* call one clean up function if defined */
if ( (sig_func = signal(SIGTERM, SIG_DFL)) != SIG_DFL &&
if ((sig_func = signal(SIGTERM, SIG_DFL)) != SIG_DFL &&
sig_func != SIG_IGN)
(*sig_func)(0);
else if ( (sig_func = signal(SIGHUP, SIG_DFL)) != SIG_DFL &&
(*sig_func) (0);
else if ((sig_func = signal(SIGHUP, SIG_DFL)) != SIG_DFL &&
sig_func != SIG_IGN)
(*sig_func)(0);
else if ( (sig_func = signal(SIGINT, SIG_DFL)) != SIG_DFL &&
(*sig_func) (0);
else if ((sig_func = signal(SIGINT, SIG_DFL)) != SIG_DFL &&
sig_func != SIG_IGN)
(*sig_func)(0);
else if ( (sig_func = signal(SIGQUIT, SIG_DFL)) != SIG_DFL &&
(*sig_func) (0);
else if ((sig_func = signal(SIGQUIT, SIG_DFL)) != SIG_DFL &&
sig_func != SIG_IGN)
(*sig_func)(0);
(*sig_func) (0);
exit(1);
}

View File

@ -4,4 +4,3 @@
*/
void halt();

View File

@ -10,20 +10,25 @@
#include "halt.h"
#include "pginterface.h"
int main(int argc, char **argv)
int
main(int argc, char **argv)
{
char query[4000];
int row =1;
int row = 1;
int aint;
float afloat;
double adouble;
char achar[11], achar16[17], abpchar[11], avarchar[51], atext[51];
char achar[11],
achar16[17],
abpchar[11],
avarchar[51],
atext[51];
time_t aabstime;
if (argc != 2)
halt("Usage: %s database\n",argv[0]);
halt("Usage: %s database\n", argv[0]);
connectdb(argv[1],NULL,NULL,NULL,NULL);
connectdb(argv[1], NULL, NULL, NULL, NULL);
on_error_continue();
doquery("DROP TABLE testfetch");
@ -42,9 +47,9 @@ int main(int argc, char **argv)
aabstime abstime) \
");
while(1)
while (1)
{
sprintf(query,"INSERT INTO testfetch VALUES ( \
sprintf(query, "INSERT INTO testfetch VALUES ( \
%d, \
2322.12, \
'923121.0323'::float8, \
@ -87,7 +92,7 @@ bpchar %s\nvarchar %s\ntext %s\nabstime %s",
doquery("CLOSE c_testfetch");
doquery("COMMIT WORK");
printf("--- %-d rows inserted so far\n",row);
printf("--- %-d rows inserted so far\n", row);
row++;
}
@ -95,4 +100,3 @@ bpchar %s\nvarchar %s\ntext %s\nabstime %s",
disconnectdb();
return 0;
}

View File

@ -18,8 +18,8 @@ static void set_signals();
#define NUL '\0'
/* GLOBAL VARIABLES */
static PGconn* conn;
static PGresult* res = NULL;
static PGconn *conn;
static PGresult *res = NULL;
#define ON_ERROR_STOP 0
#define ON_ERROR_CONTINUE 1
@ -27,7 +27,8 @@ static PGresult* res = NULL;
static int on_error_state = ON_ERROR_STOP;
/* LOCAL VARIABLES */
static sigset_t block_sigs, unblock_sigs;
static sigset_t block_sigs,
unblock_sigs;
static int tuple;
/*
@ -35,7 +36,8 @@ static int tuple;
** connectdb - returns PGconn structure
**
*/
PGconn *connectdb( char *dbName,
PGconn *
connectdb(char *dbName,
char *pghost,
char *pgport,
char *pgoptions,
@ -55,7 +57,8 @@ PGconn *connectdb( char *dbName,
** disconnectdb
**
*/
void disconnectdb()
void
disconnectdb()
{
PQfinish(conn);
}
@ -65,14 +68,15 @@ void disconnectdb()
** doquery - returns PGresult structure
**
*/
PGresult *doquery(char *query)
PGresult *
doquery(char *query)
{
if (res != NULL)
PQclear(res);
sigprocmask(SIG_SETMASK,&block_sigs,NULL);
sigprocmask(SIG_SETMASK, &block_sigs, NULL);
res = PQexec(conn, query);
sigprocmask(SIG_SETMASK,&unblock_sigs,NULL);
sigprocmask(SIG_SETMASK, &unblock_sigs, NULL);
if (on_error_state == ON_ERROR_STOP &&
(res == NULL ||
@ -81,8 +85,9 @@ PGresult *doquery(char *query)
PQresultStatus(res) == PGRES_FATAL_ERROR))
{
if (res != NULL)
fprintf(stderr,"query error: %s\n",PQcmdStatus(res));
else fprintf(stderr,"connection error: %s\n",PQerrorMessage(conn));
fprintf(stderr, "query error: %s\n", PQcmdStatus(res));
else
fprintf(stderr, "connection error: %s\n", PQerrorMessage(conn));
PQfinish(conn);
halt("failed request: %s\n", query);
}
@ -96,10 +101,12 @@ PGresult *doquery(char *query)
** NULL pointers are skipped
**
*/
int fetch(void *param, ...)
int
fetch(void *param,...)
{
va_list ap;
int arg, num_fields;
int arg,
num_fields;
num_fields = PQnfields(res);
@ -113,11 +120,11 @@ int fetch(void *param, ...)
{
if (PQfsize(res, arg) == -1)
{
memcpy(param,PQgetvalue(res,tuple,arg),PQgetlength(res,tuple,arg));
((char *)param)[PQgetlength(res,tuple,arg)] = NUL;
memcpy(param, PQgetvalue(res, tuple, arg), PQgetlength(res, tuple, arg));
((char *) param)[PQgetlength(res, tuple, arg)] = NUL;
}
else
memcpy(param,PQgetvalue(res,tuple,arg),PQfsize(res,arg));
memcpy(param, PQgetvalue(res, tuple, arg), PQfsize(res, arg));
}
param = va_arg(ap, char *);
}
@ -132,10 +139,12 @@ int fetch(void *param, ...)
** Returns true or false into null indicator variables
** NULL pointers are skipped
*/
int fetchwithnulls(void *param, ...)
int
fetchwithnulls(void *param,...)
{
va_list ap;
int arg, num_fields;
int arg,
num_fields;
num_fields = PQnfields(res);
@ -149,17 +158,17 @@ int fetchwithnulls(void *param, ...)
{
if (PQfsize(res, arg) == -1)
{
memcpy(param,PQgetvalue(res,tuple,arg),PQgetlength(res,tuple,arg));
((char *)param)[PQgetlength(res,tuple,arg)] = NUL;
memcpy(param, PQgetvalue(res, tuple, arg), PQgetlength(res, tuple, arg));
((char *) param)[PQgetlength(res, tuple, arg)] = NUL;
}
else
memcpy(param,PQgetvalue(res,tuple,arg),PQfsize(res,arg));
memcpy(param, PQgetvalue(res, tuple, arg), PQfsize(res, arg));
}
param = va_arg(ap, char *);
if (PQgetisnull(res,tuple,arg) != 0)
*(int *)param = 1;
if (PQgetisnull(res, tuple, arg) != 0)
*(int *) param = 1;
else
*(int *)param = 0;
*(int *) param = 0;
param = va_arg(ap, char *);
}
va_end(ap);
@ -171,7 +180,8 @@ int fetchwithnulls(void *param, ...)
** on_error_stop
**
*/
void on_error_stop()
void
on_error_stop()
{
on_error_state = ON_ERROR_STOP;
}
@ -181,7 +191,8 @@ void on_error_stop()
** on_error_continue
**
*/
void on_error_continue()
void
on_error_continue()
{
on_error_state = ON_ERROR_CONTINUE;
}
@ -191,9 +202,10 @@ void on_error_continue()
** sig_disconnect
**
*/
static void sig_disconnect()
static void
sig_disconnect()
{
fprintf(stderr,"exiting...\n");
fprintf(stderr, "exiting...\n");
PQfinish(conn);
exit(1);
}
@ -203,17 +215,18 @@ static void sig_disconnect()
** set_signals
**
*/
static void set_signals()
static void
set_signals()
{
sigemptyset(&block_sigs);
sigemptyset(&unblock_sigs);
sigaddset(&block_sigs,SIGTERM);
sigaddset(&block_sigs,SIGHUP);
sigaddset(&block_sigs,SIGINT);
sigaddset(&block_sigs, SIGTERM);
sigaddset(&block_sigs, SIGHUP);
sigaddset(&block_sigs, SIGINT);
/* sigaddset(&block_sigs,SIGQUIT); no block */
sigprocmask(SIG_SETMASK,&unblock_sigs,NULL);
signal(SIGTERM,sig_disconnect);
signal(SIGHUP,sig_disconnect);
signal(SIGINT,sig_disconnect);
signal(SIGQUIT,sig_disconnect);
sigprocmask(SIG_SETMASK, &unblock_sigs, NULL);
signal(SIGTERM, sig_disconnect);
signal(SIGHUP, sig_disconnect);
signal(SIGINT, sig_disconnect);
signal(SIGQUIT, sig_disconnect);
}

View File

@ -6,8 +6,8 @@
PGresult *doquery(char *query);
PGconn *connectdb();
void disconnectdb();
int fetch(void *param, ...);
int fetchwithnulls(void *param, ...);
int fetch(void *param,...);
int fetchwithnulls(void *param,...);
void on_error_continue();
void on_error_stop();

View File

@ -12,14 +12,19 @@
#include <libpq-fe.h>
#include <pginterface.h>
int main(int argc, char **argv)
int
main(int argc, char **argv)
{
char query[4000];
int row =1;
int row = 1;
int aint;
float afloat;
double adouble;
char achar[11], achar16[17], abpchar[11], avarchar[51], atext[51];
char achar[11],
achar16[17],
abpchar[11],
avarchar[51],
atext[51];
time_t aabstime;
int aint_null,
afloat_null,
@ -32,9 +37,9 @@ int main(int argc, char **argv)
aabstime_null;
if (argc != 2)
halt("Usage: %s database\n",argv[0]);
halt("Usage: %s database\n", argv[0]);
connectdb(argv[1],NULL,NULL,NULL,NULL);
connectdb(argv[1], NULL, NULL, NULL, NULL);
on_error_continue();
doquery("DROP TABLE testfetch");
@ -54,7 +59,7 @@ int main(int argc, char **argv)
");
#ifdef TEST_NON_NULLS
sprintf(query,"INSERT INTO testfetch VALUES ( \
sprintf(query, "INSERT INTO testfetch VALUES ( \
0, \
0, \
0, \
@ -65,7 +70,7 @@ int main(int argc, char **argv)
'', \
'');");
#else
sprintf(query,"INSERT INTO testfetch VALUES ( \
sprintf(query, "INSERT INTO testfetch VALUES ( \
NULL, \
NULL, \
NULL, \
@ -129,11 +134,10 @@ bpchar %d\nvarchar %d\ntext %d\nabstime %d\n",
doquery("CLOSE c_testfetch");
doquery("COMMIT WORK");
printf("--- %-d rows inserted so far\n",row);
printf("--- %-d rows inserted so far\n", row);
row++;
disconnectdb();
return 0;
}

View File

@ -10,7 +10,8 @@
#include <libpq-fe.h>
#include "pginterface.h"
int main(int argc, char **argv)
int
main(int argc, char **argv)
{
char query[4000];
int row = 0;
@ -18,9 +19,9 @@ int main(int argc, char **argv)
char line[4000];
if (argc != 2)
halt("Usage: %s database\n",argv[0]);
halt("Usage: %s database\n", argv[0]);
connectdb(argv[1],NULL,NULL,NULL,NULL);
connectdb(argv[1], NULL, NULL, NULL, NULL);
on_error_continue();
doquery("DROP TABLE words");
on_error_stop();
@ -35,12 +36,12 @@ int main(int argc, char **argv)
word text_ops )\
");
while(1)
while (1)
{
if (scanf("%s",line) != 1)
if (scanf("%s", line) != 1)
break;
doquery("BEGIN WORK");
sprintf(query,"\
sprintf(query, "\
DECLARE c_words BINARY CURSOR FOR \
SELECT count(*) \
FROM words \
@ -54,11 +55,11 @@ int main(int argc, char **argv)
doquery("COMMIT WORK");
if (count == 0)
sprintf(query,"\
sprintf(query, "\
INSERT INTO words \
VALUES (1, '%s')", line);
else
sprintf(query,"\
sprintf(query, "\
UPDATE words \
SET matches = matches + 1 \
WHERE word = '%s'", line);
@ -69,4 +70,3 @@ int main(int argc, char **argv)
disconnectdb();
return 0;
}

View File

@ -13,29 +13,30 @@
/* prototype for soundex function */
char *soundex(char *instr, char *outstr);
text *text_soundex(text *t)
text *
text_soundex(text * t)
{
/* ABCDEFGHIJKLMNOPQRSTUVWXYZ */
char *table = "01230120022455012623010202";
int count = 0;
text *new_t;
char outstr[6+1]; /* max length of soundex is 6 */
char outstr[6 + 1]; /* max length of soundex is 6 */
char *instr;
/* make a null-terminated string */
instr=palloc(VARSIZE(t)+1);
memcpy(instr,VARDATA(t),VARSIZE(t)-VARHDRSZ);
instr[VARSIZE(t)-VARHDRSZ] = (char)0;
instr = palloc(VARSIZE(t) + 1);
memcpy(instr, VARDATA(t), VARSIZE(t) - VARHDRSZ);
instr[VARSIZE(t) - VARHDRSZ] = (char) 0;
/* load soundex into outstr */
soundex(instr, outstr);
/* Now the outstr contains the soundex of instr */
/* copy outstr to new_t */
new_t = (text *) palloc(strlen(outstr)+VARHDRSZ);
memset(new_t, 0, strlen(outstr)+1);
VARSIZE(new_t) = strlen(outstr)+VARHDRSZ;
new_t = (text *) palloc(strlen(outstr) + VARHDRSZ);
memset(new_t, 0, strlen(outstr) + 1);
VARSIZE(new_t) = strlen(outstr) + VARHDRSZ;
memcpy((void *) VARDATA(new_t),
(void *) outstr,
strlen(outstr));
@ -43,33 +44,39 @@ text *text_soundex(text *t)
/* free instr */
pfree(instr);
return(new_t);
return (new_t);
}
char *soundex(char *instr, char *outstr)
char *
soundex(char *instr, char *outstr)
{ /* ABCDEFGHIJKLMNOPQRSTUVWXYZ */
char *table = "01230120022455012623010202";
int count = 0;
while(!isalpha(instr[0]) && instr[0])
while (!isalpha(instr[0]) && instr[0])
++instr;
if(!instr[0]) { /* Hey! Where'd the string go? */
outstr[0]=(char)0;
if (!instr[0])
{ /* Hey! Where'd the string go? */
outstr[0] = (char) 0;
return outstr;
}
if(toupper(instr[0]) == 'P' && toupper(instr[1]) == 'H') {
if (toupper(instr[0]) == 'P' && toupper(instr[1]) == 'H')
{
instr[0] = 'F';
instr[1] = 'A';
}
*outstr++ = (char)toupper(*instr++);
*outstr++ = (char) toupper(*instr++);
while(*instr && count < 5) {
if(isalpha(*instr) && *instr != *(instr-1)) {
while (*instr && count < 5)
{
if (isalpha(*instr) && *instr != *(instr - 1))
{
*outstr = table[toupper(instr[0]) - 'A'];
if(*outstr != '0') {
if (*outstr != '0')
{
++outstr;
++count;
}
@ -78,6 +85,5 @@ char *soundex(char *instr, char *outstr)
}
*outstr = '\0';
return(outstr);
return (outstr);
}

View File

@ -48,26 +48,34 @@
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) {
if (data == NULL)
{
result = (char *) palloc(2);
result[0] = '-';
result[1] = '\0';
return (result);
}
if (size < 0) {
if (size < 0)
{
size = strlen(data);
}
/* adjust string length for escapes */
len = size;
for (p=data,l=size; l>0; p++,l--) {
switch (*p) {
for (p = data, l = size; l > 0; p++, l--)
{
switch (*p)
{
case '\\':
case '"' :
case '"':
case '{':
case '}':
case '\b':
@ -79,7 +87,8 @@ string_output(char *data, int size)
len++;
break;
default:
if (NOTPRINTABLE(*p)) {
if (NOTPRINTABLE(*p))
{
len += 3;
}
}
@ -88,10 +97,12 @@ string_output(char *data, int size)
result = (char *) palloc(len);
for (p=data,r=result,l=size; (l > 0) && (c = *p); p++,l--) {
switch (c) {
for (p = data, r = result, l = size; (l > 0) && (c = *p); p++, l--)
{
switch (c)
{
case '\\':
case '"' :
case '"':
case '{':
case '}':
*r++ = '\\';
@ -122,7 +133,8 @@ string_output(char *data, int size)
*r++ = 'v';
break;
default:
if (NOTPRINTABLE(c)) {
if (NOTPRINTABLE(c))
{
*r = '\\';
r += 3;
*r-- = DIGIT(c & 07);
@ -131,14 +143,16 @@ string_output(char *data, int size)
c >>= 3;
*r = DIGIT(c & 03);
r += 3;
} else {
}
else
{
*r++ = c;
}
}
}
*r = '\0';
return((char *) result);
return ((char *) result);
}
/*
@ -170,54 +184,69 @@ string_output(char *data, int size)
char *
string_input(char *str, int size, int hdrsize, int *rtn_size)
{
register unsigned char *p, *r;
register unsigned char *p,
*r;
unsigned char *result;
int len;
if ((str == NULL) || (hdrsize < 0)) {
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))) {
for (p = str; *p;)
{
if (*p++ == '\\')
{
if (ISOCTAL(*p))
{
if (ISOCTAL(*(p + 1)))
{
p++;
len--;
}
if (ISOCTAL(*(p+1))) {
if (ISOCTAL(*(p + 1)))
{
p++;
len--;
}
}
if (*p) p++;
if (*p)
p++;
len--;
}
}
/* result has variable length */
if (size == 0) {
size = len+1;
} else
if (size == 0)
{
size = len + 1;
}
else
/* result has variable length with maximum size */
if (size < 0) {
size = MIN(len, - size)+1;
if (size < 0)
{
size = MIN(len, -size) + 1;
}
result = (char *) palloc(hdrsize+size);
memset(result, 0, hdrsize+size);
if (rtn_size) {
result = (char *) palloc(hdrsize + size);
memset(result, 0, hdrsize + size);
if (rtn_size)
{
*rtn_size = size;
}
r = result + hdrsize;
for (p=str; *p; ) {
for (p = str; *p;)
{
register unsigned char c;
if ((c = *p++) == '\\') {
switch (c = *p++) {
if ((c = *p++) == '\\')
{
switch (c = *p++)
{
case '\0':
p--;
break;
@ -230,11 +259,13 @@ string_input(char *str, int size, int hdrsize, int *rtn_size)
case '6':
case '7':
c = VALUE(c);
if (isdigit(*p)) {
c = (c<<3) + VALUE(*p++);
if (isdigit(*p))
{
c = (c << 3) + VALUE(*p++);
}
if (isdigit(*p)) {
c = (c<<3) + VALUE(*p++);
if (isdigit(*p))
{
c = (c << 3) + VALUE(*p++);
}
*r++ = c;
break;
@ -259,12 +290,14 @@ string_input(char *str, int size, int hdrsize, int *rtn_size)
default:
*r++ = c;
}
} else {
}
else
{
*r++ = c;
}
}
return((char *) result);
return ((char *) result);
}
char *
@ -307,12 +340,13 @@ c_char16out(char *s)
*/
char *
c_textout(struct varlena *vlena)
c_textout(struct varlena * vlena)
{
int len = 0;
char *s = NULL;
if (vlena) {
if (vlena)
{
len = VARSIZE(vlena) - VARHDRSZ;
s = VARDATA(vlena);
}
@ -328,8 +362,9 @@ c_varcharout(char *s)
{
int len;
if (s) {
len = *(int32*)s - 4;
if (s)
{
len = *(int32 *) s - 4;
s += 4;
}
return (string_output(s, len));
@ -342,7 +377,8 @@ c_textin(char *str)
struct varlena *result;
int len;
if (str == NULL) {
if (str == NULL)
{
return ((struct varlena *) NULL);
}
@ -357,5 +393,5 @@ c_char16in(char *str)
{
return (string_input(str, 16, 0, NULL));
}
#endif
#endif

View File

@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/access/common/heaptuple.c,v 1.21 1997/08/26 23:31:20 momjian Exp $
* $Header: /cvsroot/pgsql/src/backend/access/common/heaptuple.c,v 1.22 1997/09/07 04:37:30 momjian Exp $
*
* NOTES
* The old interface functions have been converted to macros
@ -27,9 +27,9 @@
#include <utils/memutils.h>
#ifndef HAVE_MEMMOVE
# include <regex/utils.h>
#include <regex/utils.h>
#else
# include <string.h>
#include <string.h>
#endif
@ -58,19 +58,26 @@ ComputeDataSize(TupleDesc tupleDesc,
int numberOfAttributes = tupleDesc->natts;
AttributeTupleForm *att = tupleDesc->attrs;
for (data_length = 0, i = 0; i < numberOfAttributes; i++) {
if (nulls[i] != ' ') continue;
for (data_length = 0, i = 0; i < numberOfAttributes; i++)
{
if (nulls[i] != ' ')
continue;
switch (att[i]->attlen) {
switch (att[i]->attlen)
{
case -1:
/*
* This is the size of the disk representation and so
* must include the additional sizeof long.
* This is the size of the disk representation and so must
* include the additional sizeof long.
*/
if (att[i]->attalign == 'd') {
if (att[i]->attalign == 'd')
{
data_length = DOUBLEALIGN(data_length)
+ VARSIZE(DatumGetPointer(value[i]));
} else {
}
else
{
data_length = INTALIGN(data_length)
+ VARSIZE(DatumGetPointer(value[i]));
}
@ -109,7 +116,7 @@ DataFill(char *data,
Datum value[],
char nulls[],
char *infomask,
bits8 *bit)
bits8 * bit)
{
bits8 *bitP = 0;
int bitmask = 0;
@ -118,24 +125,31 @@ DataFill(char *data,
int numberOfAttributes = tupleDesc->natts;
AttributeTupleForm *att = tupleDesc->attrs;
if (bit != NULL) {
if (bit != NULL)
{
bitP = &bit[-1];
bitmask = CSIGNBIT;
}
*infomask = 0;
for (i = 0; i < numberOfAttributes; i++) {
if (bit != NULL) {
if (bitmask != CSIGNBIT) {
for (i = 0; i < numberOfAttributes; i++)
{
if (bit != NULL)
{
if (bitmask != CSIGNBIT)
{
bitmask <<= 1;
} else {
}
else
{
bitP += 1;
*bitP = 0x0;
bitmask = 1;
}
if (nulls[i] == 'n') {
if (nulls[i] == 'n')
{
*infomask |= HEAP_HASNULL;
continue;
}
@ -143,16 +157,20 @@ DataFill(char *data,
*bitP |= bitmask;
}
switch (att[i]->attlen) {
switch (att[i]->attlen)
{
case -1:
*infomask |= HEAP_HASVARLENA;
if (att[i]->attalign=='d') {
if (att[i]->attalign == 'd')
{
data = (char *) DOUBLEALIGN(data);
} else {
}
else
{
data = (char *) INTALIGN(data);
}
data_length = VARSIZE(DatumGetPointer(value[i]));
memmove(data, DatumGetPointer(value[i]),data_length);
memmove(data, DatumGetPointer(value[i]), data_length);
data += data_length;
break;
case sizeof(char):
@ -162,14 +180,14 @@ DataFill(char *data,
break;
case sizeof(int16):
data = (char *) SHORTALIGN(data);
* (short *) data = (att[i]->attbyval ?
*(short *) data = (att[i]->attbyval ?
DatumGetInt16(value[i]) :
*((short *) value[i]));
data += sizeof(short);
break;
case sizeof(int32):
data = (char *) INTALIGN(data);
* (int32 *) data = (att[i]->attbyval ?
*(int32 *) data = (att[i]->attbyval ?
DatumGetInt32(value[i]) :
*((int32 *) value[i]));
data += sizeof(int32);
@ -178,12 +196,15 @@ DataFill(char *data,
if (att[i]->attlen < sizeof(int32))
elog(WARN, "DataFill: attribute %d has len %d",
i, att[i]->attlen);
if (att[i]->attalign == 'd') {
if (att[i]->attalign == 'd')
{
data = (char *) DOUBLEALIGN(data);
memmove(data, DatumGetPointer(value[i]),
att[i]->attlen);
data += att[i]->attlen;
} else {
}
else
{
data = (char *) LONGALIGN(data);
memmove(data, DatumGetPointer(value[i]),
att[i]->attlen);
@ -206,15 +227,19 @@ DataFill(char *data,
int
heap_attisnull(HeapTuple tup, int attnum)
{
if (attnum > (int)tup->t_natts)
if (attnum > (int) tup->t_natts)
return (1);
if (HeapTupleNoNulls(tup)) return(0);
if (HeapTupleNoNulls(tup))
return (0);
if (attnum > 0) {
return(att_isnull(attnum - 1, tup->t_bits));
} else
switch (attnum) {
if (attnum > 0)
{
return (att_isnull(attnum - 1, tup->t_bits));
}
else
switch (attnum)
{
case SelfItemPointerAttributeNumber:
case ObjectIdAttributeNumber:
case MinTransactionIdAttributeNumber:
@ -254,17 +279,28 @@ heap_sysattrlen(AttrNumber attno)
{
HeapTupleData *f = NULL;
switch (attno) {
case SelfItemPointerAttributeNumber: return sizeof f->t_ctid;
case ObjectIdAttributeNumber: return sizeof f->t_oid;
case MinTransactionIdAttributeNumber: return sizeof f->t_xmin;
case MinCommandIdAttributeNumber: return sizeof f->t_cmin;
case MaxTransactionIdAttributeNumber: return sizeof f->t_xmax;
case MaxCommandIdAttributeNumber: return sizeof f->t_cmax;
case ChainItemPointerAttributeNumber: return sizeof f->t_chain;
case MinAbsoluteTimeAttributeNumber: return sizeof f->t_tmin;
case MaxAbsoluteTimeAttributeNumber: return sizeof f->t_tmax;
case VersionTypeAttributeNumber: return sizeof f->t_vtype;
switch (attno)
{
case SelfItemPointerAttributeNumber:
return sizeof f->t_ctid;
case ObjectIdAttributeNumber:
return sizeof f->t_oid;
case MinTransactionIdAttributeNumber:
return sizeof f->t_xmin;
case MinCommandIdAttributeNumber:
return sizeof f->t_cmin;
case MaxTransactionIdAttributeNumber:
return sizeof f->t_xmax;
case MaxCommandIdAttributeNumber:
return sizeof f->t_cmax;
case ChainItemPointerAttributeNumber:
return sizeof f->t_chain;
case MinAbsoluteTimeAttributeNumber:
return sizeof f->t_tmin;
case MaxAbsoluteTimeAttributeNumber:
return sizeof f->t_tmax;
case VersionTypeAttributeNumber:
return sizeof f->t_vtype;
case AnchorItemPointerAttributeNumber:
elog(WARN, "heap_sysattrlen: field t_anchor does not exist!");
@ -287,7 +323,8 @@ heap_sysattrbyval(AttrNumber attno)
{
bool byval;
switch (attno) {
switch (attno)
{
case SelfItemPointerAttributeNumber:
byval = false;
break;
@ -338,9 +375,10 @@ heap_sysattrbyval(AttrNumber attno)
char *
heap_getsysattr(HeapTuple tup, Buffer b, int attnum)
{
switch (attnum) {
switch (attnum)
{
case SelfItemPointerAttributeNumber:
return ((char *)&tup->t_ctid);
return ((char *) &tup->t_ctid);
case ObjectIdAttributeNumber:
return ((char *) (long) tup->t_oid);
case MinTransactionIdAttributeNumber:
@ -359,12 +397,12 @@ heap_getsysattr(HeapTuple tup, Buffer b, int attnum)
/*
* For tmin and tmax, we need to do some extra work. These don't
* get filled in until the vacuum cleaner runs (or we manage to flush
* a page after setting the value correctly below). If the vacuum
* cleaner hasn't run yet, then the times stored in the tuple are
* wrong, and we need to look up the commit time of the transaction.
* We cache this value in the tuple to avoid doing the work more than
* once.
* get filled in until the vacuum cleaner runs (or we manage to
* flush a page after setting the value correctly below). If the
* vacuum cleaner hasn't run yet, then the times stored in the
* tuple are wrong, and we need to look up the commit time of the
* transaction. We cache this value in the tuple to avoid doing
* the work more than once.
*/
case MinAbsoluteTimeAttributeNumber:
@ -373,7 +411,8 @@ heap_getsysattr(HeapTuple tup, Buffer b, int attnum)
tup->t_tmin = TransactionIdGetCommitTime(tup->t_xmin);
return ((char *) (long) tup->t_tmin);
case MaxAbsoluteTimeAttributeNumber:
if (!AbsoluteTimeIsBackwardCompatiblyReal(tup->t_tmax)) {
if (!AbsoluteTimeIsBackwardCompatiblyReal(tup->t_tmax))
{
if (TransactionIdDidCommit(tup->t_xmax))
tup->t_tmax = TransactionIdGetCommitTime(tup->t_xmax);
else
@ -385,7 +424,7 @@ heap_getsysattr(HeapTuple tup, Buffer b, int attnum)
default:
elog(WARN, "heap_getsysattr: undefined attnum %d", attnum);
}
return(NULL);
return (NULL);
}
/* ----------------
@ -409,7 +448,7 @@ char *
fastgetattr(HeapTuple tup,
int attnum,
TupleDesc tupleDesc,
bool *isnull)
bool * isnull)
{
char *tp; /* ptr to att in tuple */
bits8 *bp = NULL; /* ptr to att in tuple */
@ -435,23 +474,31 @@ fastgetattr(HeapTuple tup,
if (isnull)
*isnull = false;
if (HeapTupleNoNulls(tup)) {
if (HeapTupleNoNulls(tup))
{
attnum--;
if (att[attnum]->attcacheoff > 0) {
if (att[attnum]->attcacheoff > 0)
{
return (char *)
fetchatt( &(att[attnum]),
(char *)tup + tup->t_hoff + att[attnum]->attcacheoff);
} else if (attnum == 0) {
fetchatt(&(att[attnum]),
(char *) tup + tup->t_hoff + att[attnum]->attcacheoff);
}
else if (attnum == 0)
{
/*
* first attribute is always at position zero
*/
return((char *) fetchatt(&(att[0]), (char *) tup + tup->t_hoff));
return ((char *) fetchatt(&(att[0]), (char *) tup + tup->t_hoff));
}
tp = (char *) tup + tup->t_hoff;
slow = 0;
} else {
}
else
{
/*
* there's a null somewhere in the tuple
*/
@ -466,7 +513,8 @@ fastgetattr(HeapTuple tup,
* ----------------
*/
if (att_isnull(attnum, bp)) {
if (att_isnull(attnum, bp))
{
if (isnull)
*isnull = true;
return NULL;
@ -480,8 +528,10 @@ fastgetattr(HeapTuple tup,
{
register int i = 0; /* current offset in bp */
for (i = 0; i < attnum && !slow; i++) {
if (att_isnull(i, bp)) slow = 1;
for (i = 0; i < attnum && !slow; i++)
{
if (att_isnull(i, bp))
slow = 1;
}
}
}
@ -489,28 +539,36 @@ fastgetattr(HeapTuple tup,
/*
* now check for any non-fixed length attrs before our attribute
*/
if (!slow) {
if (att[attnum]->attcacheoff > 0) {
if (!slow)
{
if (att[attnum]->attcacheoff > 0)
{
return (char *)
fetchatt(&(att[attnum]),
tp + att[attnum]->attcacheoff);
} else if (attnum == 0) {
}
else if (attnum == 0)
{
return (char *)
fetchatt(&(att[0]), (char *) tup + tup->t_hoff);
} else if (!HeapTupleAllFixed(tup)) {
}
else if (!HeapTupleAllFixed(tup))
{
register int j = 0;
for (j = 0; j < attnum && !slow; j++)
if (att[j]->attlen < 1) slow = 1;
if (att[j]->attlen < 1)
slow = 1;
}
}
/*
* if slow is zero, and we got here, we know that we have a tuple with
* no nulls. We also have to initialize the remainder of
* the attribute cached offset values.
* no nulls. We also have to initialize the remainder of the
* attribute cached offset values.
*/
if (!slow) {
if (!slow)
{
register int j = 1;
register long off;
@ -520,14 +578,17 @@ fastgetattr(HeapTuple tup,
att[0]->attcacheoff = 0;
while (att[j]->attcacheoff > 0) j++;
while (att[j]->attcacheoff > 0)
j++;
off = att[j-1]->attcacheoff + att[j-1]->attlen;
off = att[j - 1]->attcacheoff + att[j - 1]->attlen;
for (; j < attnum + 1; j++) {
switch(att[j]->attlen) {
for (; j < attnum + 1; j++)
{
switch (att[j]->attlen)
{
case -1:
off = (att[j]->attalign=='d') ?
off = (att[j]->attalign == 'd') ?
DOUBLEALIGN(off) : INTALIGN(off);
break;
case sizeof(char):
@ -539,7 +600,8 @@ fastgetattr(HeapTuple tup,
off = INTALIGN(off);
break;
default:
if (att[j]->attlen < sizeof(int32)) {
if (att[j]->attlen < sizeof(int32))
{
elog(WARN,
"fastgetattr: attribute %d has len %d",
j, att[j]->attlen);
@ -556,8 +618,10 @@ fastgetattr(HeapTuple tup,
}
return
(char *)fetchatt(&(att[attnum]), tp + att[attnum]->attcacheoff);
} else {
(char *) fetchatt(&(att[attnum]), tp + att[attnum]->attcacheoff);
}
else
{
register bool usecache = true;
register int off = 0;
register int i;
@ -565,23 +629,27 @@ fastgetattr(HeapTuple tup,
/*
* Now we know that we have to walk the tuple CAREFULLY.
*
* Note - This loop is a little tricky. On iteration i we
* first set the offset for attribute i and figure out how much
* the offset should be incremented. Finally, we need to align the
* offset based on the size of attribute i+1 (for which the offset
* has been computed). -mer 12 Dec 1991
* Note - This loop is a little tricky. On iteration i we first set
* the offset for attribute i and figure out how much the offset
* should be incremented. Finally, we need to align the offset
* based on the size of attribute i+1 (for which the offset has
* been computed). -mer 12 Dec 1991
*/
for (i = 0; i < attnum; i++) {
if (!HeapTupleNoNulls(tup)) {
if (att_isnull(i, bp)) {
for (i = 0; i < attnum; i++)
{
if (!HeapTupleNoNulls(tup))
{
if (att_isnull(i, bp))
{
usecache = false;
continue;
}
}
switch (att[i]->attlen) {
switch (att[i]->attlen)
{
case -1:
off = (att[i]->attalign=='d') ?
off = (att[i]->attalign == 'd') ?
DOUBLEALIGN(off) : INTALIGN(off);
break;
case sizeof(char):
@ -603,16 +671,22 @@ fastgetattr(HeapTuple tup,
off = LONGALIGN(off);
break;
}
if (usecache && att[i]->attcacheoff > 0) {
if (usecache && att[i]->attcacheoff > 0)
{
off = att[i]->attcacheoff;
if (att[i]->attlen == -1) {
if (att[i]->attlen == -1)
{
usecache = false;
}
} else {
if (usecache) att[i]->attcacheoff = off;
}
else
{
if (usecache)
att[i]->attcacheoff = off;
}
switch(att[i]->attlen) {
switch (att[i]->attlen)
{
case sizeof(char):
off++;
break;
@ -631,9 +705,10 @@ fastgetattr(HeapTuple tup,
break;
}
}
switch (att[attnum]->attlen) {
switch (att[attnum]->attlen)
{
case -1:
off = (att[attnum]->attalign=='d')?
off = (att[attnum]->attalign == 'd') ?
DOUBLEALIGN(off) : INTALIGN(off);
break;
case sizeof(char):
@ -654,7 +729,7 @@ fastgetattr(HeapTuple tup,
off = LONGALIGN(off);
break;
}
return((char *) fetchatt(&(att[attnum]), tp + off));
return ((char *) fetchatt(&(att[attnum]), tp + off));
}
}
@ -669,18 +744,19 @@ heap_copytuple(HeapTuple tuple)
{
HeapTuple newTuple;
if (! HeapTupleIsValid(tuple))
if (!HeapTupleIsValid(tuple))
return (NULL);
/* XXX For now, just prevent an undetectable executor related error */
if (tuple->t_len > MAXTUPLEN) {
if (tuple->t_len > MAXTUPLEN)
{
elog(WARN, "palloctup: cannot handle length %d tuples",
tuple->t_len);
}
newTuple = (HeapTuple) palloc(tuple->t_len);
memmove((char *) newTuple, (char *) tuple, (int) tuple->t_len);
return(newTuple);
return (newTuple);
}
#ifdef NOT_USED
@ -702,12 +778,13 @@ heap_deformtuple(HeapTuple tuple,
Assert(HeapTupleIsValid(tuple));
natts = tuple->t_natts;
for (i = 0; i<natts; i++) {
for (i = 0; i < natts; i++)
{
bool isnull;
values[i] = (Datum)heap_getattr(tuple,
values[i] = (Datum) heap_getattr(tuple,
InvalidBuffer,
i+1,
i + 1,
tdesc,
&isnull);
if (isnull)
@ -716,6 +793,7 @@ heap_deformtuple(HeapTuple tuple,
nulls[i] = ' ';
}
}
#endif
/* ----------------
@ -752,15 +830,18 @@ heap_formtuple(TupleDesc tupleDescriptor,
len = sizeof *tuple - sizeof tuple->t_bits;
for (i = 0; i < numberOfAttributes && !hasnull; i++) {
if (nulls[i] != ' ') hasnull = true;
for (i = 0; i < numberOfAttributes && !hasnull; i++)
{
if (nulls[i] != ' ')
hasnull = true;
}
if (numberOfAttributes > MaxHeapAttributeNumber)
elog(WARN, "heap_formtuple: numberOfAttributes of %d > %d",
numberOfAttributes, MaxHeapAttributeNumber);
if (hasnull) {
if (hasnull)
{
bitmaplen = BITMAPLEN(numberOfAttributes);
len += bitmaplen;
}
@ -772,7 +853,7 @@ heap_formtuple(TupleDesc tupleDescriptor,
tp = (char *) palloc(len);
tuple = (HeapTuple) tp;
memset(tp, 0, (int)len);
memset(tp, 0, (int) len);
tuple->t_len = len;
tuple->t_natts = numberOfAttributes;
@ -780,7 +861,7 @@ heap_formtuple(TupleDesc tupleDescriptor,
tuple->t_tmin = INVALID_ABSTIME;
tuple->t_tmax = CURRENT_ABSTIME;
DataFill((char *)tuple + tuple->t_hoff,
DataFill((char *) tuple + tuple->t_hoff,
tupleDescriptor,
value,
nulls,
@ -831,7 +912,8 @@ heap_modifytuple(HeapTuple tuple,
* ----------------
*/
madecopy = 0;
if (BufferIsValid(buffer) == true) {
if (BufferIsValid(buffer) == true)
{
relation = (Relation) BufferGetRelation(buffer);
tuple = heap_copytuple(tuple);
madecopy = 1;
@ -849,9 +931,11 @@ heap_modifytuple(HeapTuple tuple,
for (attoff = 0;
attoff < numberOfAttributes;
attoff += 1) {
attoff += 1)
{
if (repl[attoff] == ' ') {
if (repl[attoff] == ' ')
{
char *attr;
attr =
@ -859,14 +943,18 @@ heap_modifytuple(HeapTuple tuple,
InvalidBuffer,
AttrOffsetGetAttrNumber(attoff),
RelationGetTupleDescriptor(relation),
&isNull) ;
&isNull);
value[attoff] = PointerGetDatum(attr);
nulls[attoff] = (isNull) ? 'n' : ' ';
} else if (repl[attoff] != 'r') {
}
else if (repl[attoff] != 'r')
{
elog(WARN, "heap_modifytuple: repl is \\%3d", repl[attoff]);
} else { /* == 'r' */
}
else
{ /* == 'r' */
value[attoff] = replValue[attoff];
nulls[attoff] = replNull[attoff];
}
@ -885,11 +973,12 @@ heap_modifytuple(HeapTuple tuple,
* ----------------
*/
infomask = newTuple->t_infomask;
memmove((char *) &newTuple->t_ctid, /*XXX*/
memmove((char *) &newTuple->t_ctid, /* XXX */
(char *) &tuple->t_ctid,
((char *) &tuple->t_hoff - (char *) &tuple->t_ctid)); /*XXX*/
((char *) &tuple->t_hoff - (char *) &tuple->t_ctid)); /* XXX */
newTuple->t_infomask = infomask;
newTuple->t_natts = numberOfAttributes; /* fix t_natts just in case */
newTuple->t_natts = numberOfAttributes; /* fix t_natts just in
* case */
/* ----------------
* if we made a copy of the tuple, then free it.
@ -919,13 +1008,13 @@ heap_addheader(uint32 natts, /* max domain index */
AssertArg(natts > 0);
len = sizeof (HeapTupleData) - sizeof (tup->t_bits);
len = sizeof(HeapTupleData) - sizeof(tup->t_bits);
hoff = len = DOUBLEALIGN(len); /* be conservative */
len += structlen;
tp = (char *) palloc(len);
tup = (HeapTuple) tp;
memset((char*)tup, 0, len);
memset((char *) tup, 0, len);
tup->t_len = (short) len; /* XXX */
tp += tup->t_hoff = hoff;

View File

@ -7,7 +7,7 @@
*
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/access/common/Attic/heapvalid.c,v 1.16 1997/08/29 09:12:20 vadim Exp $
* $Header: /cvsroot/pgsql/src/backend/access/common/Attic/heapvalid.c,v 1.17 1997/09/07 04:37:36 momjian Exp $
*
*-------------------------------------------------------------------------
*/
@ -40,8 +40,9 @@ heap_keytest(HeapTuple t,
Datum atp;
int test;
for (; nkeys--; keys++) {
atp = (Datum)heap_getattr(t, InvalidBuffer,
for (; nkeys--; keys++)
{
atp = (Datum) heap_getattr(t, InvalidBuffer,
keys->sk_attno,
tupdesc,
&isnull);
@ -50,11 +51,12 @@ heap_keytest(HeapTuple t,
/* XXX eventually should check if SK_ISNULL */
return false;
if (keys->sk_flags & SK_ISNULL) {
if (keys->sk_flags & SK_ISNULL)
{
return (false);
}
if (keys->sk_func == (func_ptr)oideq) /* optimization */
if (keys->sk_func == (func_ptr) oideq) /* optimization */
test = (keys->sk_argument == atp);
else if (keys->sk_flags & SK_COMMUTE)
test = (long) FMGR_PTR2(keys->sk_func, keys->sk_procedure,
@ -99,11 +101,13 @@ heap_tuple_satisfies(ItemId itemId,
int nKeys,
ScanKey key)
{
HeapTuple tuple, result;
HeapTuple tuple,
result;
bool res;
TransactionId old_tmin, old_tmax;
TransactionId old_tmin,
old_tmax;
if (! ItemIdIsUsed(itemId))
if (!ItemIdIsUsed(itemId))
return NULL;
tuple = (HeapTuple) PageGetItem((Page) disk_page, itemId);
@ -114,19 +118,25 @@ heap_tuple_satisfies(ItemId itemId,
else
res = TRUE;
result = (HeapTuple)NULL;
if (res) {
if(relation->rd_rel->relkind == RELKIND_UNCATALOGED) {
result = (HeapTuple) NULL;
if (res)
{
if (relation->rd_rel->relkind == RELKIND_UNCATALOGED)
{
result = tuple;
} else {
}
else
{
old_tmin = tuple->t_tmin;
old_tmax = tuple->t_tmax;
res = HeapTupleSatisfiesTimeQual(tuple,qual);
if(tuple->t_tmin != old_tmin ||
tuple->t_tmax != old_tmax) {
res = HeapTupleSatisfiesTimeQual(tuple, qual);
if (tuple->t_tmin != old_tmin ||
tuple->t_tmax != old_tmax)
{
SetBufferCommitInfoNeedsSave(buffer);
}
if(res) {
if (res)
{
result = tuple;
}
}
@ -145,7 +155,7 @@ TupleUpdatedByCurXactAndCmd(HeapTuple t)
{
if (TransactionIdEquals(t->t_xmax,
GetCurrentTransactionId()) &&
CommandIdGEScanCommandId (t->t_cmax))
CommandIdGEScanCommandId(t->t_cmax))
return true;
return false;

View File

@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/access/common/indextuple.c,v 1.15 1997/08/19 21:28:50 momjian Exp $
* $Header: /cvsroot/pgsql/src/backend/access/common/indextuple.c,v 1.16 1997/09/07 04:37:37 momjian Exp $
*
*-------------------------------------------------------------------------
*/
@ -21,14 +21,15 @@
#include <access/tupmacs.h>
#ifndef HAVE_MEMMOVE
# include <regex/utils.h>
#include <regex/utils.h>
#else
# include <string.h>
#include <string.h>
#endif
static Size IndexInfoFindDataOffset(unsigned short t_info);
static char *fastgetiattr(IndexTuple tup, int attnum,
TupleDesc att, bool *isnull);
static char *
fastgetiattr(IndexTuple tup, int attnum,
TupleDesc att, bool * isnull);
/* ----------------------------------------------------------------
* index_ tuple interface routines
@ -46,7 +47,8 @@ index_formtuple(TupleDesc tupleDescriptor,
{
register char *tp; /* tuple pointer */
IndexTuple tuple; /* return tuple */
Size size, hoff;
Size size,
hoff;
int i;
unsigned short infomask = 0;
bool hasnull = false;
@ -58,11 +60,14 @@ index_formtuple(TupleDesc tupleDescriptor,
numberOfAttributes, MaxIndexAttributeNumber);
for (i = 0; i < numberOfAttributes && !hasnull; i++) {
if (null[i] != ' ') hasnull = true;
for (i = 0; i < numberOfAttributes && !hasnull; i++)
{
if (null[i] != ' ')
hasnull = true;
}
if (hasnull) infomask |= INDEX_NULL_MASK;
if (hasnull)
infomask |= INDEX_NULL_MASK;
hoff = IndexInfoFindDataOffset(infomask);
size = hoff
@ -72,23 +77,24 @@ index_formtuple(TupleDesc tupleDescriptor,
tp = (char *) palloc(size);
tuple = (IndexTuple) tp;
memset(tp,0,(int)size);
memset(tp, 0, (int) size);
DataFill((char *)tp + hoff,
DataFill((char *) tp + hoff,
tupleDescriptor,
value,
null,
&tupmask,
(hasnull ? (bits8*)tp + sizeof(*tuple) : NULL));
(hasnull ? (bits8 *) tp + sizeof(*tuple) : NULL));
/*
* We do this because DataFill wants to initialize a "tupmask" which
* is used for HeapTuples, but we want an indextuple infomask. The only
* "relevent" info is the "has variable attributes" field, which is in
* mask position 0x02. We have already set the null mask above.
* is used for HeapTuples, but we want an indextuple infomask. The
* only "relevent" info is the "has variable attributes" field, which
* is in mask position 0x02. We have already set the null mask above.
*/
if (tupmask & 0x02) infomask |= INDEX_VAR_MASK;
if (tupmask & 0x02)
infomask |= INDEX_VAR_MASK;
/*
* Here we make sure that we can actually hold the size. We also want
@ -131,7 +137,7 @@ static char *
fastgetiattr(IndexTuple tup,
int attnum,
TupleDesc tupleDesc,
bool *isnull)
bool * isnull)
{
register char *tp; /* ptr to att in tuple */
register char *bp = NULL; /* ptr to att in tuple */
@ -160,17 +166,20 @@ fastgetiattr(IndexTuple tup,
data_off = IndexTupleHasMinHeader(tup) ? sizeof *tup :
IndexInfoFindDataOffset(tup->t_info);
if (IndexTupleNoNulls(tup)) {
if (IndexTupleNoNulls(tup))
{
/* first attribute is always at position zero */
if (attnum == 1) {
return(fetchatt(&(att[0]), (char *) tup + data_off));
if (attnum == 1)
{
return (fetchatt(&(att[0]), (char *) tup + data_off));
}
attnum--;
if (att[attnum]->attcacheoff > 0) {
return(fetchatt(&(att[attnum]),
if (att[attnum]->attcacheoff > 0)
{
return (fetchatt(&(att[attnum]),
(char *) tup + data_off +
att[attnum]->attcacheoff));
}
@ -178,9 +187,12 @@ fastgetiattr(IndexTuple tup,
tp = (char *) tup + data_off;
slow = 0;
}else { /* there's a null somewhere in the tuple */
}
else
{ /* there's a null somewhere in the tuple */
bp = (char *) tup + sizeof(*tup); /* "knows" t_bits are here! */
bp = (char *) tup + sizeof(*tup); /* "knows" t_bits are
* here! */
slow = 0;
/* ----------------
* check to see if desired att is null
@ -189,7 +201,8 @@ fastgetiattr(IndexTuple tup,
attnum--;
{
if (att_isnull(attnum, bp)) {
if (att_isnull(attnum, bp))
{
*isnull = true;
return NULL;
}
@ -202,21 +215,27 @@ fastgetiattr(IndexTuple tup,
register int i = 0; /* current offset in bp */
register int mask; /* bit in byte we're looking at */
register char n; /* current byte in bp */
register int byte, finalbit;
register int byte,
finalbit;
byte = attnum >> 3;
finalbit = attnum & 0x07;
for (; i <= byte; i++) {
for (; i <= byte; i++)
{
n = bp[i];
if (i < byte) {
if (i < byte)
{
/* check for nulls in any "earlier" bytes */
if ((~n) != 0) {
if ((~n) != 0)
{
slow++;
break;
}
} else {
/* check for nulls "before" final bit of last byte*/
}
else
{
/* check for nulls "before" final bit of last byte */
mask = (finalbit << 1) - 1;
if ((~n) & mask)
slow++;
@ -228,15 +247,20 @@ fastgetiattr(IndexTuple tup,
/* now check for any non-fixed length attrs before our attribute */
if (!slow) {
if (att[attnum]->attcacheoff > 0) {
return(fetchatt(&(att[attnum]),
if (!slow)
{
if (att[attnum]->attcacheoff > 0)
{
return (fetchatt(&(att[attnum]),
tp + att[attnum]->attcacheoff));
}else if (!IndexTupleAllFixed(tup)) {
}
else if (!IndexTupleAllFixed(tup))
{
register int j = 0;
for (j = 0; j < attnum && !slow; j++)
if (att[j]->attlen < 1) slow = 1;
if (att[j]->attlen < 1)
slow = 1;
}
}
@ -246,7 +270,8 @@ fastgetiattr(IndexTuple tup,
* the attribute cached offset values.
*/
if (!slow) {
if (!slow)
{
register int j = 1;
register long off;
@ -256,22 +281,25 @@ fastgetiattr(IndexTuple tup,
att[0]->attcacheoff = 0;
while (att[j]->attcacheoff > 0) j++;
while (att[j]->attcacheoff > 0)
j++;
off = att[j-1]->attcacheoff +
att[j-1]->attlen;
off = att[j - 1]->attcacheoff +
att[j - 1]->attlen;
for (; j < attnum + 1; j++)
{
for (; j < attnum + 1; j++) {
/*
* Fix me when going to a machine with more than a four-byte
* word!
*/
switch(att[j]->attlen)
switch (att[j]->attlen)
{
case -1:
off = (att[j]->attalign=='d')?
DOUBLEALIGN(off):INTALIGN(off);
off = (att[j]->attalign == 'd') ?
DOUBLEALIGN(off) : INTALIGN(off);
break;
case sizeof(char):
break;
@ -283,7 +311,7 @@ fastgetiattr(IndexTuple tup,
break;
default:
if (att[j]->attlen > sizeof(int32))
off = (att[j]->attalign=='d')?
off = (att[j]->attalign == 'd') ?
DOUBLEALIGN(off) : LONGALIGN(off);
else
elog(WARN, "fastgetiattr: attribute %d has len %d",
@ -296,9 +324,11 @@ fastgetiattr(IndexTuple tup,
off += att[j]->attlen;
}
return(fetchatt( &(att[attnum]),
return (fetchatt(&(att[attnum]),
tp + att[attnum]->attcacheoff));
}else {
}
else
{
register bool usecache = true;
register int off = 0;
register int i;
@ -307,15 +337,19 @@ fastgetiattr(IndexTuple tup,
* Now we know that we have to walk the tuple CAREFULLY.
*/
for (i = 0; i < attnum; i++) {
if (!IndexTupleNoNulls(tup)) {
if (att_isnull(i, bp)) {
for (i = 0; i < attnum; i++)
{
if (!IndexTupleNoNulls(tup))
{
if (att_isnull(i, bp))
{
usecache = false;
continue;
}
}
if (usecache && att[i]->attcacheoff > 0) {
if (usecache && att[i]->attcacheoff > 0)
{
off = att[i]->attcacheoff;
if (att[i]->attlen == -1)
usecache = false;
@ -323,27 +357,28 @@ fastgetiattr(IndexTuple tup,
continue;
}
if (usecache) att[i]->attcacheoff = off;
switch(att[i]->attlen)
if (usecache)
att[i]->attcacheoff = off;
switch (att[i]->attlen)
{
case sizeof(char):
off++;
break;
case sizeof(short):
off = SHORTALIGN(off) + sizeof(short);
off = SHORTALIGN(off) +sizeof(short);
break;
case sizeof(int32):
off = INTALIGN(off) + sizeof(int32);
break;
case -1:
usecache = false;
off = (att[i]->attalign=='d')?
DOUBLEALIGN(off):INTALIGN(off);
off = (att[i]->attalign == 'd') ?
DOUBLEALIGN(off) : INTALIGN(off);
off += VARSIZE(tp + off);
break;
default:
if (att[i]->attlen > sizeof(int32))
off = (att[i]->attalign=='d') ?
off = (att[i]->attalign == 'd') ?
DOUBLEALIGN(off) + att[i]->attlen :
LONGALIGN(off) + att[i]->attlen;
else
@ -353,14 +388,15 @@ fastgetiattr(IndexTuple tup,
break;
}
}
/*
* I don't know why this code was missed here!
* I've got it from heaptuple.c:fastgetattr().
* - vadim 06/12/97
* I don't know why this code was missed here! I've got it from
* heaptuple.c:fastgetattr(). - vadim 06/12/97
*/
switch (att[attnum]->attlen) {
switch (att[attnum]->attlen)
{
case -1:
off = (att[attnum]->attalign=='d')?
off = (att[attnum]->attalign == 'd') ?
DOUBLEALIGN(off) : INTALIGN(off);
break;
case sizeof(char):
@ -382,7 +418,7 @@ fastgetiattr(IndexTuple tup,
break;
}
return(fetchatt(&att[attnum], tp + off));
return (fetchatt(&att[attnum], tp + off));
}
}
@ -394,9 +430,9 @@ Datum
index_getattr(IndexTuple tuple,
AttrNumber attNum,
TupleDesc tupDesc,
bool *isNullOutP)
bool * isNullOutP)
{
Assert (attNum > 0);
Assert(attNum > 0);
return (Datum)
fastgetiattr(tuple, attNum, tupDesc, isNullOutP);
@ -429,11 +465,13 @@ static Size
IndexInfoFindDataOffset(unsigned short t_info)
{
if (!(t_info & INDEX_NULL_MASK))
return((Size) sizeof(IndexTupleData));
else {
return ((Size) sizeof(IndexTupleData));
else
{
Size size = sizeof(IndexTupleData);
if (t_info & INDEX_NULL_MASK) {
if (t_info & INDEX_NULL_MASK)
{
size += sizeof(IndexAttributeBitMapData);
}
return DOUBLEALIGN(size); /* be conservative */
@ -445,17 +483,17 @@ IndexInfoFindDataOffset(unsigned short t_info)
* we assume we have space that is already palloc'ed.
*/
void
CopyIndexTuple(IndexTuple source, IndexTuple *target)
CopyIndexTuple(IndexTuple source, IndexTuple * target)
{
Size size;
IndexTuple ret;
size = IndexTupleSize(source);
if (*target == NULL) {
if (*target == NULL)
{
*target = (IndexTuple) palloc(size);
}
ret = *target;
memmove((char*)ret, (char*)source, size);
memmove((char *) ret, (char *) source, size);
}

View File

@ -7,7 +7,7 @@
*
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/access/common/Attic/indexvalid.c,v 1.14 1997/03/18 18:38:19 scrappy Exp $
* $Header: /cvsroot/pgsql/src/backend/access/common/Attic/indexvalid.c,v 1.15 1997/09/07 04:37:38 momjian Exp $
*
*-------------------------------------------------------------------------
*/
@ -46,32 +46,39 @@ index_keytest(IndexTuple tuple,
IncrIndexProcessed();
while (scanKeySize > 0) {
while (scanKeySize > 0)
{
datum = index_getattr(tuple,
key[0].sk_attno,
tupdesc,
&isNull);
if (isNull) {
if (isNull)
{
/* XXX eventually should check if SK_ISNULL */
return (false);
}
if (key[0].sk_flags & SK_ISNULL) {
if (key[0].sk_flags & SK_ISNULL)
{
return (false);
}
if (key[0].sk_flags & SK_COMMUTE) {
if (key[0].sk_flags & SK_COMMUTE)
{
test = (*(key[0].sk_func))
(DatumGetPointer(key[0].sk_argument),
datum) ? 1 : 0;
} else {
}
else
{
test = (*(key[0].sk_func))
(datum,
DatumGetPointer(key[0].sk_argument)) ? 1 : 0;
}
if (!test == !(key[0].sk_flags & SK_NEGATE)) {
if (!test == !(key[0].sk_flags & SK_NEGATE))
{
return (false);
}
@ -81,4 +88,3 @@ index_keytest(IndexTuple tuple,
return (true);
}

View File

@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/access/common/printtup.c,v 1.15 1997/08/26 23:31:23 momjian Exp $
* $Header: /cvsroot/pgsql/src/backend/access/common/printtup.c,v 1.16 1997/09/07 04:37:39 momjian Exp $
*
*-------------------------------------------------------------------------
*/
@ -42,11 +42,11 @@ typtoout(Oid type)
0, 0, 0);
if (HeapTupleIsValid(typeTuple))
return((Oid)
return ((Oid)
((TypeTupleForm) GETSTRUCT(typeTuple))->typoutput);
elog(WARN, "typtoout: Cache lookup of type %d failed", type);
return(InvalidOid);
return (InvalidOid);
}
Oid
@ -56,14 +56,14 @@ gettypelem(Oid type)
typeTuple = SearchSysCacheTuple(TYPOID,
ObjectIdGetDatum(type),
0,0,0);
0, 0, 0);
if (HeapTupleIsValid(typeTuple))
return((Oid)
return ((Oid)
((TypeTupleForm) GETSTRUCT(typeTuple))->typelem);
elog(WARN, "typtoout: Cache lookup of type %d failed", type);
return(InvalidOid);
return (InvalidOid);
}
/* ----------------
@ -73,8 +73,11 @@ gettypelem(Oid type)
void
printtup(HeapTuple tuple, TupleDesc typeinfo)
{
int i, j, k;
char *outputstr, *attr;
int i,
j,
k;
char *outputstr,
*attr;
bool isnull;
Oid typoutput;
@ -90,13 +93,16 @@ printtup(HeapTuple tuple, TupleDesc typeinfo)
*/
j = 0;
k = 1 << 7;
for (i = 0; i < tuple->t_natts; ) {
i++; /* heap_getattr is a macro, so no increment */
for (i = 0; i < tuple->t_natts;)
{
i++; /* heap_getattr is a macro, so no
* increment */
attr = heap_getattr(tuple, InvalidBuffer, i, typeinfo, &isnull);
if (!isnull)
j |= k;
k >>= 1;
if (!(i & 7)) {
if (!(i & 7))
{
pq_putint(j, 1);
j = 0;
k = 1 << 7;
@ -109,14 +115,16 @@ printtup(HeapTuple tuple, TupleDesc typeinfo)
* send the attributes of this tuple
* ----------------
*/
for (i = 0; i < tuple->t_natts; ++i) {
attr = heap_getattr(tuple, InvalidBuffer, i+1, typeinfo, &isnull);
for (i = 0; i < tuple->t_natts; ++i)
{
attr = heap_getattr(tuple, InvalidBuffer, i + 1, typeinfo, &isnull);
typoutput = typtoout((Oid) typeinfo->attrs[i]->atttypid);
if (!isnull && OidIsValid(typoutput)) {
if (!isnull && OidIsValid(typoutput))
{
outputstr = fmgr(typoutput, attr,
gettypelem(typeinfo->attrs[i]->atttypid));
pq_putint(strlen(outputstr)+4, 4);
pq_putint(strlen(outputstr) + 4, 4);
pq_putnchar(outputstr, strlen(outputstr));
pfree(outputstr);
}
@ -156,7 +164,7 @@ showatts(char *name, TupleDesc tupleDesc)
puts(name);
for (i = 0; i < natts; ++i)
printatt((unsigned) i+1, attinfo[i], (char *) NULL);
printatt((unsigned) i + 1, attinfo[i], (char *) NULL);
printf("\t----\n");
}
@ -168,18 +176,21 @@ void
debugtup(HeapTuple tuple, TupleDesc typeinfo)
{
register int i;
char *attr, *value;
char *attr,
*value;
bool isnull;
Oid typoutput;
for (i = 0; i < tuple->t_natts; ++i) {
attr = heap_getattr(tuple, InvalidBuffer, i+1, typeinfo, &isnull);
for (i = 0; i < tuple->t_natts; ++i)
{
attr = heap_getattr(tuple, InvalidBuffer, i + 1, typeinfo, &isnull);
typoutput = typtoout((Oid) typeinfo->attrs[i]->atttypid);
if (!isnull && OidIsValid(typoutput)) {
if (!isnull && OidIsValid(typoutput))
{
value = fmgr(typoutput, attr,
gettypelem(typeinfo->attrs[i]->atttypid));
printatt((unsigned) i+1, typeinfo->attrs[i], value);
printatt((unsigned) i + 1, typeinfo->attrs[i], value);
pfree(value);
}
}
@ -198,7 +209,9 @@ debugtup(HeapTuple tuple, TupleDesc typeinfo)
void
printtup_internal(HeapTuple tuple, TupleDesc typeinfo)
{
int i, j, k;
int i,
j,
k;
char *attr;
bool isnull;
@ -214,13 +227,16 @@ printtup_internal(HeapTuple tuple, TupleDesc typeinfo)
*/
j = 0;
k = 1 << 7;
for (i = 0; i < tuple->t_natts; ) {
i++; /* heap_getattr is a macro, so no increment */
for (i = 0; i < tuple->t_natts;)
{
i++; /* heap_getattr is a macro, so no
* increment */
attr = heap_getattr(tuple, InvalidBuffer, i, typeinfo, &isnull);
if (!isnull)
j |= k;
k >>= 1;
if (!(i & 7)) {
if (!(i & 7))
{
pq_putint(j, 1);
j = 0;
k = 1 << 7;
@ -236,13 +252,16 @@ printtup_internal(HeapTuple tuple, TupleDesc typeinfo)
#ifdef IPORTAL_DEBUG
fprintf(stderr, "sending tuple with %d atts\n", tuple->t_natts);
#endif
for (i = 0; i < tuple->t_natts; ++i) {
for (i = 0; i < tuple->t_natts; ++i)
{
int32 len = typeinfo->attrs[i]->attlen;
attr = heap_getattr(tuple, InvalidBuffer, i+1, typeinfo, &isnull);
if (!isnull) {
attr = heap_getattr(tuple, InvalidBuffer, i + 1, typeinfo, &isnull);
if (!isnull)
{
/* # of bytes, and opaque data */
if (len == -1) {
if (len == -1)
{
/* variable length, assume a varlena structure */
len = VARSIZE(attr) - VARHDRSZ;
@ -253,18 +272,22 @@ printtup_internal(HeapTuple tuple, TupleDesc typeinfo)
char *d = VARDATA(attr);
fprintf(stderr, "length %d data %x%x%x%x\n",
len, *d, *(d+1), *(d+2), *(d+3));
len, *d, *(d + 1), *(d + 2), *(d + 3));
}
#endif
} else {
}
else
{
/* fixed size */
if (typeinfo->attrs[i]->attbyval) {
if (typeinfo->attrs[i]->attbyval)
{
int8 i8;
int16 i16;
int32 i32;
pq_putint(len, sizeof(int32));
switch (len) {
switch (len)
{
case sizeof(int8):
i8 = DatumGetChar(attr);
pq_putnchar((char *) &i8, len);
@ -281,7 +304,9 @@ printtup_internal(HeapTuple tuple, TupleDesc typeinfo)
#ifdef IPORTAL_DEBUG
fprintf(stderr, "byval length %d data %d\n", len, attr);
#endif
} else {
}
else
{
pq_putint(len, sizeof(int32));
pq_putnchar(attr, len);
#ifdef IPORTAL_DEBUG

View File

@ -7,7 +7,7 @@
*
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/access/common/scankey.c,v 1.9 1996/11/05 07:42:45 scrappy Exp $
* $Header: /cvsroot/pgsql/src/backend/access/common/scankey.c,v 1.10 1997/09/07 04:37:39 momjian Exp $
*
*-------------------------------------------------------------------------
*/

View File

@ -7,7 +7,7 @@
*
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/access/common/tupdesc.c,v 1.19 1997/08/22 02:55:39 vadim Exp $
* $Header: /cvsroot/pgsql/src/backend/access/common/tupdesc.c,v 1.20 1997/09/07 04:37:41 momjian Exp $
*
* NOTES
* some of the executor utility code such as "ExecTypeFromTL" should be
@ -28,9 +28,9 @@
#include <utils/syscache.h>
#ifndef HAVE_MEMMOVE
# include <regex/utils.h>
#include <regex/utils.h>
#else
# include <string.h>
#include <string.h>
#endif
/* ----------------------------------------------------------------
@ -57,9 +57,9 @@ CreateTemplateTupleDesc(int natts)
* is filled with NULL pointers.
* ----------------
*/
size = natts * sizeof (AttributeTupleForm);
size = natts * sizeof(AttributeTupleForm);
desc = (TupleDesc) palloc(sizeof(struct tupleDesc));
desc->attrs = (AttributeTupleForm*) palloc(size);
desc->attrs = (AttributeTupleForm *) palloc(size);
desc->constr = NULL;
memset(desc->attrs, 0, size);
@ -75,7 +75,7 @@ CreateTemplateTupleDesc(int natts)
* ----------------------------------------------------------------
*/
TupleDesc
CreateTupleDesc(int natts, AttributeTupleForm* attrs)
CreateTupleDesc(int natts, AttributeTupleForm * attrs)
{
TupleDesc desc;
@ -106,15 +106,17 @@ TupleDesc
CreateTupleDescCopy(TupleDesc tupdesc)
{
TupleDesc desc;
int i, size;
int i,
size;
desc = (TupleDesc) palloc(sizeof(struct tupleDesc));
desc->natts = tupdesc->natts;
size = desc->natts * sizeof (AttributeTupleForm);
desc->attrs = (AttributeTupleForm*) palloc(size);
for (i=0;i<desc->natts;i++) {
size = desc->natts * sizeof(AttributeTupleForm);
desc->attrs = (AttributeTupleForm *) palloc(size);
for (i = 0; i < desc->natts; i++)
{
desc->attrs[i] =
(AttributeTupleForm)palloc(ATTRIBUTE_TUPLE_SIZE);
(AttributeTupleForm) palloc(ATTRIBUTE_TUPLE_SIZE);
memmove(desc->attrs[i],
tupdesc->attrs[i],
ATTRIBUTE_TUPLE_SIZE);
@ -139,15 +141,17 @@ CreateTupleDescCopyConstr(TupleDesc tupdesc)
{
TupleDesc desc;
TupleConstr *constr = tupdesc->constr;
int i, size;
int i,
size;
desc = (TupleDesc) palloc(sizeof(struct tupleDesc));
desc->natts = tupdesc->natts;
size = desc->natts * sizeof (AttributeTupleForm);
desc->attrs = (AttributeTupleForm*) palloc(size);
for (i=0;i<desc->natts;i++) {
size = desc->natts * sizeof(AttributeTupleForm);
desc->attrs = (AttributeTupleForm *) palloc(size);
for (i = 0; i < desc->natts; i++)
{
desc->attrs[i] =
(AttributeTupleForm)palloc(ATTRIBUTE_TUPLE_SIZE);
(AttributeTupleForm) palloc(ATTRIBUTE_TUPLE_SIZE);
memmove(desc->attrs[i],
tupdesc->attrs[i],
ATTRIBUTE_TUPLE_SIZE);
@ -158,31 +162,31 @@ CreateTupleDescCopyConstr(TupleDesc tupdesc)
cpy->has_not_null = constr->has_not_null;
if ( ( cpy->num_defval = constr->num_defval ) > 0 )
if ((cpy->num_defval = constr->num_defval) > 0)
{
cpy->defval = (AttrDefault *) palloc (cpy->num_defval * sizeof (AttrDefault));
memcpy (cpy->defval, constr->defval, cpy->num_defval * sizeof (AttrDefault));
cpy->defval = (AttrDefault *) palloc(cpy->num_defval * sizeof(AttrDefault));
memcpy(cpy->defval, constr->defval, cpy->num_defval * sizeof(AttrDefault));
for (i = cpy->num_defval - 1; i >= 0; i--)
{
if ( constr->defval[i].adbin )
cpy->defval[i].adbin = pstrdup (constr->defval[i].adbin);
if ( constr->defval[i].adsrc )
cpy->defval[i].adsrc = pstrdup (constr->defval[i].adsrc);
if (constr->defval[i].adbin)
cpy->defval[i].adbin = pstrdup(constr->defval[i].adbin);
if (constr->defval[i].adsrc)
cpy->defval[i].adsrc = pstrdup(constr->defval[i].adsrc);
}
}
if ( ( cpy->num_check = constr->num_check ) > 0 )
if ((cpy->num_check = constr->num_check) > 0)
{
cpy->check = (ConstrCheck *) palloc (cpy->num_check * sizeof (ConstrCheck));
memcpy (cpy->check, constr->check, cpy->num_check * sizeof (ConstrCheck));
cpy->check = (ConstrCheck *) palloc(cpy->num_check * sizeof(ConstrCheck));
memcpy(cpy->check, constr->check, cpy->num_check * sizeof(ConstrCheck));
for (i = cpy->num_check - 1; i >= 0; i--)
{
if ( constr->check[i].ccname )
cpy->check[i].ccname = pstrdup (constr->check[i].ccname);
if ( constr->check[i].ccbin )
cpy->check[i].ccbin = pstrdup (constr->check[i].ccbin);
if ( constr->check[i].ccsrc )
cpy->check[i].ccsrc = pstrdup (constr->check[i].ccsrc);
if (constr->check[i].ccname)
cpy->check[i].ccname = pstrdup(constr->check[i].ccname);
if (constr->check[i].ccbin)
cpy->check[i].ccbin = pstrdup(constr->check[i].ccbin);
if (constr->check[i].ccsrc)
cpy->check[i].ccsrc = pstrdup(constr->check[i].ccsrc);
}
}
@ -195,47 +199,47 @@ CreateTupleDescCopyConstr(TupleDesc tupdesc)
}
void
FreeTupleDesc (TupleDesc tupdesc)
FreeTupleDesc(TupleDesc tupdesc)
{
int i;
for (i = 0; i < tupdesc->natts; i++)
pfree (tupdesc->attrs[i]);
pfree (tupdesc->attrs);
if ( tupdesc->constr )
pfree(tupdesc->attrs[i]);
pfree(tupdesc->attrs);
if (tupdesc->constr)
{
if ( tupdesc->constr->num_defval > 0 )
if (tupdesc->constr->num_defval > 0)
{
AttrDefault *attrdef = tupdesc->constr->defval;
for (i = tupdesc->constr->num_defval - 1; i >= 0; i--)
{
if ( attrdef[i].adbin )
pfree (attrdef[i].adbin);
if ( attrdef[i].adsrc )
pfree (attrdef[i].adsrc);
if (attrdef[i].adbin)
pfree(attrdef[i].adbin);
if (attrdef[i].adsrc)
pfree(attrdef[i].adsrc);
}
pfree (attrdef);
pfree(attrdef);
}
if ( tupdesc->constr->num_check > 0 )
if (tupdesc->constr->num_check > 0)
{
ConstrCheck *check = tupdesc->constr->check;
for (i = tupdesc->constr->num_check - 1; i >= 0; i--)
{
if ( check[i].ccname )
pfree (check[i].ccname);
if ( check[i].ccbin )
pfree (check[i].ccbin);
if ( check[i].ccsrc )
pfree (check[i].ccsrc);
if (check[i].ccname)
pfree(check[i].ccname);
if (check[i].ccbin)
pfree(check[i].ccbin);
if (check[i].ccsrc)
pfree(check[i].ccsrc);
}
pfree (check);
pfree(check);
}
pfree (tupdesc->constr);
pfree(tupdesc->constr);
}
pfree (tupdesc);
pfree(tupdesc);
}
@ -264,8 +268,11 @@ TupleDescInitEntry(TupleDesc desc,
*/
AssertArg(PointerIsValid(desc));
AssertArg(attributeNumber >= 1);
/* attributeName's are sometimes NULL,
from resdom's. I don't know why that is, though -- Jolly */
/*
* attributeName's are sometimes NULL, from resdom's. I don't know
* why that is, though -- Jolly
*/
/* AssertArg(NameIsValid(attributeName));*/
/* AssertArg(NameIsValid(typeName));*/
@ -289,7 +296,7 @@ TupleDescInitEntry(TupleDesc desc,
if (attributeName != NULL)
namestrcpy(&(att->attname), attributeName);
else
memset(att->attname.data,0,NAMEDATALEN);
memset(att->attname.data, 0, NAMEDATALEN);
att->attdisbursion = 0; /* dummy value */
@ -320,8 +327,9 @@ TupleDescInitEntry(TupleDesc desc,
* ----------------
*/
tuple = SearchSysCacheTuple(TYPNAME, PointerGetDatum(typeName),
0,0,0);
if (! HeapTupleIsValid(tuple)) {
0, 0, 0);
if (!HeapTupleIsValid(tuple))
{
/* ----------------
* here type info does not exist yet so we just fill
* the attribute with dummy information and return false.
@ -368,11 +376,15 @@ TupleDescInitEntry(TupleDesc desc,
are considered, etc. Ugh.
-----------------------------------------
*/
if (attisset) {
if (attisset)
{
Type t = type("oid");
att->attlen = tlen(t);
att->attbyval = tbyval(t);
} else {
}
else
{
att->attlen = typeForm->typlen;
att->attbyval = typeForm->typbyval;
}
@ -401,7 +413,7 @@ TupleDescMakeSelfReference(TupleDesc desc,
AttributeTupleForm att;
Type t = type("oid");
att = desc->attrs[attnum-1];
att = desc->attrs[attnum - 1];
att->atttypid = TypeShellMake(relname);
att->attlen = tlen(t);
att->attbyval = tbyval(t);
@ -425,7 +437,7 @@ TupleDescMakeSelfReference(TupleDesc desc,
* ----------------------------------------------------------------
*/
TupleDesc
BuildDescForRelation(List *schema, char *relname)
BuildDescForRelation(List * schema, char *relname)
{
int natts;
AttrNumber attnum;
@ -451,7 +463,8 @@ BuildDescForRelation(List *schema, char *relname)
typename = palloc(NAMEDATALEN);
foreach(p, schema) {
foreach(p, schema)
{
ColumnDef *entry;
List *arry;
@ -468,14 +481,15 @@ BuildDescForRelation(List *schema, char *relname)
arry = entry->typename->arrayBounds;
attisset = entry->typename->setof;
strNcpy(typename, entry->typename->name,NAMEDATALEN-1);
strNcpy(typename, entry->typename->name, NAMEDATALEN - 1);
if (arry != NIL)
attdim = length(arry);
else
attdim = 0;
if (! TupleDescInitEntry(desc, attnum, attname,
typename, attdim, attisset)) {
if (!TupleDescInitEntry(desc, attnum, attname,
typename, attdim, attisset))
{
/* ----------------
* if TupleDescInitEntry() fails, it means there is
* no type in the system catalogs. So now we check if
@ -483,9 +497,11 @@ BuildDescForRelation(List *schema, char *relname)
* have a self reference, otherwise it's an error.
* ----------------
*/
if (!strcmp(typename, relname)) {
if (!strcmp(typename, relname))
{
TupleDescMakeSelfReference(desc, attnum, relname);
} else
}
else
elog(WARN, "DefineRelation: no such type %s",
typename);
}
@ -494,39 +510,40 @@ BuildDescForRelation(List *schema, char *relname)
* this is for char() and varchar(). When an entry is of type
* char() or varchar(), typlen is set to the appropriate length,
* which we'll use here instead. (The catalog lookup only returns
* the length of bpchar and varchar which is not what we want!)
* - ay 6/95
* the length of bpchar and varchar which is not what we want!) -
* ay 6/95
*/
if (entry->typename->typlen > 0) {
if (entry->typename->typlen > 0)
{
desc->attrs[attnum - 1]->attlen = entry->typename->typlen;
}
/* This is for constraints */
if (entry->is_not_null)
constr->has_not_null = true;
desc->attrs[attnum-1]->attnotnull = entry->is_not_null;
desc->attrs[attnum - 1]->attnotnull = entry->is_not_null;
if ( entry->defval != NULL )
if (entry->defval != NULL)
{
if ( attrdef == NULL )
attrdef = (AttrDefault*) palloc (natts * sizeof (AttrDefault));
if (attrdef == NULL)
attrdef = (AttrDefault *) palloc(natts * sizeof(AttrDefault));
attrdef[ndef].adnum = attnum;
attrdef[ndef].adbin = NULL;
attrdef[ndef].adsrc = entry->defval;
ndef++;
desc->attrs[attnum-1]->atthasdef = true;
desc->attrs[attnum - 1]->atthasdef = true;
}
}
if ( constr->has_not_null || ndef > 0 )
if (constr->has_not_null || ndef > 0)
{
desc->constr = constr;
if ( ndef > 0 ) /* DEFAULTs */
if (ndef > 0) /* DEFAULTs */
{
if ( ndef < natts )
constr->defval = (AttrDefault*)
repalloc (attrdef, ndef * sizeof (AttrDefault));
if (ndef < natts)
constr->defval = (AttrDefault *)
repalloc(attrdef, ndef * sizeof(AttrDefault));
else
constr->defval = attrdef;
constr->num_defval = ndef;
@ -537,9 +554,8 @@ BuildDescForRelation(List *schema, char *relname)
}
else
{
pfree (constr);
pfree(constr);
desc->constr = NULL;
}
return desc;
}

File diff suppressed because it is too large Load Diff

View File

@ -22,20 +22,22 @@
#include <storage/bufmgr.h>
#ifndef HAVE_MEMMOVE
# include <regex/utils.h>
#include <regex/utils.h>
#else
# include <string.h>
#include <string.h>
#endif
static OffsetNumber gistfindnext(IndexScanDesc s, Page p, OffsetNumber n,
static OffsetNumber
gistfindnext(IndexScanDesc s, Page p, OffsetNumber n,
ScanDirection dir);
static RetrieveIndexResult gistscancache(IndexScanDesc s, ScanDirection dir);
static RetrieveIndexResult gistfirst(IndexScanDesc s, ScanDirection dir);
static RetrieveIndexResult gistnext(IndexScanDesc s, ScanDirection dir);
static ItemPointer gistheapptr(Relation r, ItemPointer itemp);
static bool gistindex_keytest(IndexTuple tuple, TupleDesc tupdesc,
int scanKeySize, ScanKey key, GISTSTATE *giststate,
static bool
gistindex_keytest(IndexTuple tuple, TupleDesc tupdesc,
int scanKeySize, ScanKey key, GISTSTATE * giststate,
Relation r, Page p, OffsetNumber offset);
@ -49,9 +51,12 @@ gistgettuple(IndexScanDesc s, ScanDirection dir)
return (res);
/* not cached, so we'll have to do some work */
if (ItemPointerIsValid(&(s->currentItemData))) {
if (ItemPointerIsValid(&(s->currentItemData)))
{
res = gistnext(s, dir);
} else {
}
else
{
res = gistfirst(s, dir);
}
return (res);
@ -76,14 +81,16 @@ gistfirst(IndexScanDesc s, ScanDirection dir)
po = (GISTPageOpaque) PageGetSpecialPointer(p);
so = (GISTScanOpaque) s->opaque;
for (;;) {
for (;;)
{
maxoff = PageGetMaxOffsetNumber(p);
if (ScanDirectionIsBackward(dir))
n = gistfindnext(s, p, maxoff, dir);
else
n = gistfindnext(s, p, FirstOffsetNumber, dir);
while (n < FirstOffsetNumber || n > maxoff) {
while (n < FirstOffsetNumber || n > maxoff)
{
ReleaseBuffer(b);
if (so->s_stack == (GISTSTACK *) NULL)
@ -95,9 +102,12 @@ gistfirst(IndexScanDesc s, ScanDirection dir)
po = (GISTPageOpaque) PageGetSpecialPointer(p);
maxoff = PageGetMaxOffsetNumber(p);
if (ScanDirectionIsBackward(dir)) {
if (ScanDirectionIsBackward(dir))
{
n = OffsetNumberPrev(stk->gs_child);
} else {
}
else
{
n = OffsetNumberNext(stk->gs_child);
}
so->s_stack = stk->gs_parent;
@ -105,7 +115,8 @@ gistfirst(IndexScanDesc s, ScanDirection dir)
n = gistfindnext(s, p, n, dir);
}
if (po->flags & F_LEAF) {
if (po->flags & F_LEAF)
{
ItemPointerSet(&(s->currentItemData), BufferGetBlockNumber(b), n);
it = (IndexTuple) PageGetItem(p, PageGetItemId(p, n));
@ -114,7 +125,9 @@ gistfirst(IndexScanDesc s, ScanDirection dir)
ReleaseBuffer(b);
return (res);
} else {
}
else
{
stk = (GISTSTACK *) palloc(sizeof(GISTSTACK));
stk->gs_child = n;
stk->gs_blk = BufferGetBlockNumber(b);
@ -149,9 +162,12 @@ gistnext(IndexScanDesc s, ScanDirection dir)
blk = ItemPointerGetBlockNumber(&(s->currentItemData));
n = ItemPointerGetOffsetNumber(&(s->currentItemData));
if (ScanDirectionIsForward(dir)) {
if (ScanDirectionIsForward(dir))
{
n = OffsetNumberNext(n);
} else {
}
else
{
n = OffsetNumberPrev(n);
}
@ -160,11 +176,13 @@ gistnext(IndexScanDesc s, ScanDirection dir)
po = (GISTPageOpaque) PageGetSpecialPointer(p);
so = (GISTScanOpaque) s->opaque;
for (;;) {
for (;;)
{
maxoff = PageGetMaxOffsetNumber(p);
n = gistfindnext(s, p, n, dir);
while (n < FirstOffsetNumber || n > maxoff) {
while (n < FirstOffsetNumber || n > maxoff)
{
ReleaseBuffer(b);
if (so->s_stack == (GISTSTACK *) NULL)
@ -176,9 +194,12 @@ gistnext(IndexScanDesc s, ScanDirection dir)
maxoff = PageGetMaxOffsetNumber(p);
po = (GISTPageOpaque) PageGetSpecialPointer(p);
if (ScanDirectionIsBackward(dir)) {
if (ScanDirectionIsBackward(dir))
{
n = OffsetNumberPrev(stk->gs_child);
} else {
}
else
{
n = OffsetNumberNext(stk->gs_child);
}
so->s_stack = stk->gs_parent;
@ -186,7 +207,8 @@ gistnext(IndexScanDesc s, ScanDirection dir)
n = gistfindnext(s, p, n, dir);
}
if (po->flags & F_LEAF) {
if (po->flags & F_LEAF)
{
ItemPointerSet(&(s->currentItemData), BufferGetBlockNumber(b), n);
it = (IndexTuple) PageGetItem(p, PageGetItemId(p, n));
@ -195,7 +217,9 @@ gistnext(IndexScanDesc s, ScanDirection dir)
ReleaseBuffer(b);
return (res);
} else {
}
else
{
stk = (GISTSTACK *) palloc(sizeof(GISTSTACK));
stk->gs_child = n;
stk->gs_blk = BufferGetBlockNumber(b);
@ -210,9 +234,12 @@ gistnext(IndexScanDesc s, ScanDirection dir)
p = BufferGetPage(b);
po = (GISTPageOpaque) PageGetSpecialPointer(p);
if (ScanDirectionIsBackward(dir)) {
if (ScanDirectionIsBackward(dir))
{
n = PageGetMaxOffsetNumber(p);
} else {
}
else
{
n = FirstOffsetNumber;
}
}
@ -225,7 +252,7 @@ gistindex_keytest(IndexTuple tuple,
TupleDesc tupdesc,
int scanKeySize,
ScanKey key,
GISTSTATE *giststate,
GISTSTATE * giststate,
Relation r,
Page p,
OffsetNumber offset)
@ -238,32 +265,38 @@ gistindex_keytest(IndexTuple tuple,
IncrIndexProcessed();
while (scanKeySize > 0) {
while (scanKeySize > 0)
{
datum = index_getattr(tuple,
1,
tupdesc,
&isNull);
gistdentryinit(giststate, &de, (char *)datum, r, p, offset,
gistdentryinit(giststate, &de, (char *) datum, r, p, offset,
IndexTupleSize(tuple) - sizeof(IndexTupleData),
FALSE);
if (isNull) {
if (isNull)
{
/* XXX eventually should check if SK_ISNULL */
return (false);
}
if (key[0].sk_flags & SK_COMMUTE) {
if (key[0].sk_flags & SK_COMMUTE)
{
test = (*(key[0].sk_func))
(DatumGetPointer(key[0].sk_argument),
&de, key[0].sk_procedure) ? 1 : 0;
} else {
}
else
{
test = (*(key[0].sk_func))
(&de,
DatumGetPointer(key[0].sk_argument),
key[0].sk_procedure) ? 1 : 0;
}
if (!test == !(key[0].sk_flags & SK_NEGATE)) {
if (!test == !(key[0].sk_flags & SK_NEGATE))
{
return (false);
}
@ -294,12 +327,14 @@ gistfindnext(IndexScanDesc s, Page p, OffsetNumber n, ScanDirection dir)
* a ghost tuple, before the scan. If this is the case, back up one.
*/
if (so->s_flags & GS_CURBEFORE) {
if (so->s_flags & GS_CURBEFORE)
{
so->s_flags &= ~GS_CURBEFORE;
n = OffsetNumberPrev(n);
}
while (n >= FirstOffsetNumber && n <= maxoff) {
while (n >= FirstOffsetNumber && n <= maxoff)
{
it = (char *) PageGetItem(p, PageGetItemId(p, n));
if (gistindex_keytest((IndexTuple) it,
RelationGetTupleDescriptor(s->relation),
@ -307,9 +342,12 @@ gistfindnext(IndexScanDesc s, Page p, OffsetNumber n, ScanDirection dir)
s->relation, p, n))
break;
if (ScanDirectionIsBackward(dir)) {
if (ScanDirectionIsBackward(dir))
{
n = OffsetNumberPrev(n);
} else {
}
else
{
n = OffsetNumberNext(n);
}
}
@ -324,7 +362,8 @@ gistscancache(IndexScanDesc s, ScanDirection dir)
ItemPointer ip;
if (!(ScanDirectionIsNoMovement(dir)
&& ItemPointerIsValid(&(s->currentItemData)))) {
&& ItemPointerIsValid(&(s->currentItemData))))
{
return ((RetrieveIndexResult) NULL);
}
@ -336,7 +375,7 @@ gistscancache(IndexScanDesc s, ScanDirection dir)
else
res = (RetrieveIndexResult) NULL;
pfree (ip);
pfree(ip);
return (res);
}
@ -355,7 +394,8 @@ gistheapptr(Relation r, ItemPointer itemp)
OffsetNumber n;
ip = (ItemPointer) palloc(sizeof(ItemPointerData));
if (ItemPointerIsValid(itemp)) {
if (ItemPointerIsValid(itemp))
{
b = ReadBuffer(r, ItemPointerGetBlockNumber(itemp));
p = BufferGetPage(b);
n = ItemPointerGetOffsetNumber(itemp);
@ -363,7 +403,9 @@ gistheapptr(Relation r, ItemPointer itemp)
memmove((char *) ip, (char *) &(it->t_tid),
sizeof(ItemPointerData));
ReleaseBuffer(b);
} else {
}
else
{
ItemPointerSetInvalid(ip);
}

View File

@ -21,19 +21,22 @@
#include <storage/lmgr.h>
#ifndef HAVE_MEMMOVE
# include <regex/utils.h>
#include <regex/utils.h>
#else
# include <string.h>
#include <string.h>
#endif
/* routines defined and used here */
static void gistregscan(IndexScanDesc s);
static void gistdropscan(IndexScanDesc s);
static void gistadjone(IndexScanDesc s, int op, BlockNumber blkno,
static void
gistadjone(IndexScanDesc s, int op, BlockNumber blkno,
OffsetNumber offnum);
static void adjuststack(GISTSTACK *stk, BlockNumber blkno,
static void
adjuststack(GISTSTACK * stk, BlockNumber blkno,
OffsetNumber offnum);
static void adjustiptr(IndexScanDesc s, ItemPointer iptr,
static void
adjustiptr(IndexScanDesc s, ItemPointer iptr,
int op, BlockNumber blkno, OffsetNumber offnum);
/*
@ -46,7 +49,8 @@ static void adjustiptr(IndexScanDesc s, ItemPointer iptr,
* locks on the same object, so that's why we need to handle this case.
*/
typedef struct GISTScanListData {
typedef struct GISTScanListData
{
IndexScanDesc gsl_scan;
struct GISTScanListData *gsl_next;
} GISTScanListData;
@ -77,7 +81,8 @@ gistrescan(IndexScanDesc s, bool fromEnd, ScanKey key)
GISTScanOpaque p;
int i;
if (!IndexScanIsValid(s)) {
if (!IndexScanIsValid(s))
{
elog(WARN, "gistrescan: invalid scan.");
return;
}
@ -96,24 +101,31 @@ gistrescan(IndexScanDesc s, bool fromEnd, ScanKey key)
/*
* Set flags.
*/
if (RelationGetNumberOfBlocks(s->relation) == 0) {
if (RelationGetNumberOfBlocks(s->relation) == 0)
{
s->flags = ScanUnmarked;
} else if (fromEnd) {
}
else if (fromEnd)
{
s->flags = ScanUnmarked | ScanUncheckedPrevious;
} else {
}
else
{
s->flags = ScanUnmarked | ScanUncheckedNext;
}
s->scanFromEnd = fromEnd;
if (s->numberOfKeys > 0) {
if (s->numberOfKeys > 0)
{
memmove(s->keyData,
key,
s->numberOfKeys * sizeof(ScanKeyData));
}
p = (GISTScanOpaque) s->opaque;
if (p != (GISTScanOpaque) NULL) {
if (p != (GISTScanOpaque) NULL)
{
gistfreestack(p->s_stack);
gistfreestack(p->s_markstk);
p->s_stack = p->s_markstk = (GISTSTACK *) NULL;
@ -125,25 +137,31 @@ gistrescan(IndexScanDesc s, bool fromEnd, ScanKey key)
s->keyData[i].sk_procedure);
s->keyData[i].sk_func = p->giststate->consistentFn;
}
} else {
}
else
{
/* initialize opaque data */
p = (GISTScanOpaque) palloc(sizeof(GISTScanOpaqueData));
p->s_stack = p->s_markstk = (GISTSTACK *) NULL;
p->s_flags = 0x0;
s->opaque = p;
p->giststate = (GISTSTATE *)palloc(sizeof(GISTSTATE));
p->giststate = (GISTSTATE *) palloc(sizeof(GISTSTATE));
initGISTstate(p->giststate, s->relation);
if (s->numberOfKeys > 0)
/*
** Play games here with the scan key to use the Consistent
** function for all comparisons:
** 1) the sk_procedure field will now be used to hold the
** strategy number
** 2) the sk_func field will point to the Consistent function
* * Play games here with the scan key to use the Consistent *
* function for all comparisons: * 1) the sk_procedure field
* will now be used to hold the * strategy number * 2) the
* sk_func field will point to the Consistent function
*/
for (i = 0; i < s->numberOfKeys; i++)
{
/*
* s->keyData[i].sk_procedure =
* index_getprocid(s->relation, 1, GIST_CONSISTENT_PROC);
*/
for (i = 0; i < s->numberOfKeys; i++) {
/* s->keyData[i].sk_procedure
= index_getprocid(s->relation, 1, GIST_CONSISTENT_PROC); */
s->keyData[i].sk_procedure
= RelationGetGISTStrategy(s->relation, s->keyData[i].sk_attno,
s->keyData[i].sk_procedure);
@ -156,7 +174,9 @@ void
gistmarkpos(IndexScanDesc s)
{
GISTScanOpaque p;
GISTSTACK *o, *n, *tmp;
GISTSTACK *o,
*n,
*tmp;
s->currentMarkData = s->currentItemData;
p = (GISTScanOpaque) s->opaque;
@ -169,7 +189,8 @@ gistmarkpos(IndexScanDesc s)
n = p->s_stack;
/* copy the parent stack from the current item data */
while (n != (GISTSTACK *) NULL) {
while (n != (GISTSTACK *) NULL)
{
tmp = (GISTSTACK *) palloc(sizeof(GISTSTACK));
tmp->gs_child = n->gs_child;
tmp->gs_blk = n->gs_blk;
@ -186,7 +207,9 @@ void
gistrestrpos(IndexScanDesc s)
{
GISTScanOpaque p;
GISTSTACK *o, *n, *tmp;
GISTSTACK *o,
*n,
*tmp;
s->currentItemData = s->currentMarkData;
p = (GISTScanOpaque) s->opaque;
@ -199,7 +222,8 @@ gistrestrpos(IndexScanDesc s)
n = p->s_markstk;
/* copy the parent stack from the current item data */
while (n != (GISTSTACK *) NULL) {
while (n != (GISTSTACK *) NULL)
{
tmp = (GISTSTACK *) palloc(sizeof(GISTSTACK));
tmp->gs_child = n->gs_child;
tmp->gs_blk = n->gs_blk;
@ -219,10 +243,11 @@ gistendscan(IndexScanDesc s)
p = (GISTScanOpaque) s->opaque;
if (p != (GISTScanOpaque) NULL) {
if (p != (GISTScanOpaque) NULL)
{
gistfreestack(p->s_stack);
gistfreestack(p->s_markstk);
pfree (s->opaque);
pfree(s->opaque);
}
gistdropscan(s);
@ -250,7 +275,8 @@ gistdropscan(IndexScanDesc s)
for (l = GISTScans;
l != (GISTScanList) NULL && l->gsl_scan != s;
l = l->gsl_next) {
l = l->gsl_next)
{
prev = l;
}
@ -272,7 +298,8 @@ gistadjscans(Relation r, int op, BlockNumber blkno, OffsetNumber offnum)
Oid relid;
relid = r->rd_id;
for (l = GISTScans; l != (GISTScanList) NULL; l = l->gsl_next) {
for (l = GISTScans; l != (GISTScanList) NULL; l = l->gsl_next)
{
if (l->gsl_scan->relation->rd_id == relid)
gistadjone(l->gsl_scan, op, blkno, offnum);
}
@ -301,7 +328,8 @@ gistadjone(IndexScanDesc s,
so = (GISTScanOpaque) s->opaque;
if (op == GISTOP_SPLIT) {
if (op == GISTOP_SPLIT)
{
adjuststack(so->s_stack, blkno, offnum);
adjuststack(so->s_markstk, blkno, offnum);
}
@ -324,20 +352,27 @@ adjustiptr(IndexScanDesc s,
OffsetNumber curoff;
GISTScanOpaque so;
if (ItemPointerIsValid(iptr)) {
if (ItemPointerGetBlockNumber(iptr) == blkno) {
if (ItemPointerIsValid(iptr))
{
if (ItemPointerGetBlockNumber(iptr) == blkno)
{
curoff = ItemPointerGetOffsetNumber(iptr);
so = (GISTScanOpaque) s->opaque;
switch (op) {
switch (op)
{
case GISTOP_DEL:
/* back up one if we need to */
if (curoff >= offnum) {
if (curoff >= offnum)
{
if (curoff > FirstOffsetNumber) {
if (curoff > FirstOffsetNumber)
{
/* just adjust the item pointer */
ItemPointerSet(iptr, blkno, OffsetNumberPrev(curoff));
} else {
}
else
{
/* remember that we're before the current tuple */
ItemPointerSet(iptr, blkno, FirstOffsetNumber);
if (iptr == &(s->currentItemData))
@ -379,11 +414,12 @@ adjustiptr(IndexScanDesc s,
*/
/*ARGSUSED*/
static void
adjuststack(GISTSTACK *stk,
adjuststack(GISTSTACK * stk,
BlockNumber blkno,
OffsetNumber offnum)
{
while (stk != (GISTSTACK *) NULL) {
while (stk != (GISTSTACK *) NULL)
{
if (stk->gs_blk == blkno)
stk->gs_child = FirstOffsetNumber;

View File

@ -48,21 +48,21 @@ static StrategyNumber GISTNegate[GISTNStrategies] = {
InvalidStrategy,
InvalidStrategy,
InvalidStrategy
};
};
/* if a op_1 b, what is the operator op_2 such that b op_2 a? */
static StrategyNumber GISTCommute[GISTNStrategies] = {
InvalidStrategy,
InvalidStrategy,
InvalidStrategy
};
};
/* if a op_1 b, what is the operator op_2 such that (b !op_2 a)? */
static StrategyNumber GISTNegateCommute[GISTNStrategies] = {
InvalidStrategy,
InvalidStrategy,
InvalidStrategy
};
};
/*
* GiSTs do not currently support TermData (see rtree/rtstrat.c for
@ -91,7 +91,7 @@ static StrategyEvaluationData GISTEvaluationData = {
(StrategyTransformMap) GISTNegate, /* how to do (not qual) */
(StrategyTransformMap) GISTCommute, /* how to swap operands */
(StrategyTransformMap) GISTNegateCommute, /* how to do both */
{ NULL }
{NULL}
};
StrategyNumber
@ -113,4 +113,5 @@ RelationInvokeGISTStrategy(Relation r,
return (RelationInvokeStrategy(r, &GISTEvaluationData, attnum, s,
left, right));
}
#endif

View File

@ -7,7 +7,7 @@
*
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/access/hash/hash.c,v 1.12 1997/01/10 09:46:13 vadim Exp $
* $Header: /cvsroot/pgsql/src/backend/access/hash/hash.c,v 1.13 1997/09/07 04:37:49 momjian Exp $
*
* NOTES
* This file contains only the public interface routines.
@ -26,9 +26,9 @@
#include <miscadmin.h>
#ifndef HAVE_MEMMOVE
# include <regex/utils.h>
#include <regex/utils.h>
#else
# include <string.h>
#include <string.h>
#endif
bool BuildingHash = false;
@ -45,31 +45,37 @@ void
hashbuild(Relation heap,
Relation index,
int natts,
AttrNumber *attnum,
AttrNumber * attnum,
IndexStrategy istrat,
uint16 pcount,
Datum *params,
FuncIndexInfo *finfo,
PredInfo *predInfo)
Datum * params,
FuncIndexInfo * finfo,
PredInfo * predInfo)
{
HeapScanDesc hscan;
Buffer buffer;
HeapTuple htup;
IndexTuple itup;
TupleDesc htupdesc, itupdesc;
TupleDesc htupdesc,
itupdesc;
Datum *attdata;
bool *nulls;
InsertIndexResult res;
int nhtups, nitups;
int nhtups,
nitups;
int i;
HashItem hitem;
#ifndef OMIT_PARTIAL_INDEX
ExprContext *econtext;
TupleTable tupleTable;
TupleTableSlot *slot;
#endif
Oid hrelid, irelid;
Node *pred, *oldPred;
Oid hrelid,
irelid;
Node *pred,
*oldPred;
/* note that this is a new btree */
BuildingHash = true;
@ -90,20 +96,23 @@ hashbuild(Relation heap,
nulls = (bool *) palloc(natts * sizeof(bool));
/*
* If this is a predicate (partial) index, we will need to evaluate the
* predicate using ExecQual, which requires the current tuple to be in a
* slot of a TupleTable. In addition, ExecQual must have an ExprContext
* referring to that slot. Here, we initialize dummy TupleTable and
* ExprContext objects for this purpose. --Nels, Feb '92
* If this is a predicate (partial) index, we will need to evaluate
* the predicate using ExecQual, which requires the current tuple to
* be in a slot of a TupleTable. In addition, ExecQual must have an
* ExprContext referring to that slot. Here, we initialize dummy
* TupleTable and ExprContext objects for this purpose. --Nels, Feb
* '92
*/
#ifndef OMIT_PARTIAL_INDEX
if (pred != NULL || oldPred != NULL) {
if (pred != NULL || oldPred != NULL)
{
tupleTable = ExecCreateTupleTable(1);
slot = ExecAllocTableSlot(tupleTable);
econtext = makeNode(ExprContext);
FillDummyExprContext(econtext, slot, htupdesc, buffer);
}
else /* quiet the compiler */
else
/* quiet the compiler */
{
econtext = NULL;
tupleTable = 0;
@ -118,7 +127,8 @@ hashbuild(Relation heap,
/* build the index */
nhtups = nitups = 0;
for (; HeapTupleIsValid(htup); htup = heap_getnext(hscan, 0, &buffer)) {
for (; HeapTupleIsValid(htup); htup = heap_getnext(hscan, 0, &buffer))
{
nhtups++;
@ -126,49 +136,57 @@ hashbuild(Relation heap,
* If oldPred != NULL, this is an EXTEND INDEX command, so skip
* this tuple if it was already in the existing partial index
*/
if (oldPred != NULL) {
/*SetSlotContents(slot, htup); */
if (oldPred != NULL)
{
/* SetSlotContents(slot, htup); */
#ifndef OMIT_PARTIAL_INDEX
slot->val = htup;
if (ExecQual((List*)oldPred, econtext) == true) {
if (ExecQual((List *) oldPred, econtext) == true)
{
nitups++;
continue;
}
#endif /* OMIT_PARTIAL_INDEX */
}
/* Skip this tuple if it doesn't satisfy the partial-index predicate */
if (pred != NULL) {
/*
* Skip this tuple if it doesn't satisfy the partial-index
* predicate
*/
if (pred != NULL)
{
#ifndef OMIT_PARTIAL_INDEX
/*SetSlotContents(slot, htup); */
/* SetSlotContents(slot, htup); */
slot->val = htup;
if (ExecQual((List*)pred, econtext) == false)
if (ExecQual((List *) pred, econtext) == false)
continue;
#endif /* OMIT_PARTIAL_INDEX */
}
}
nitups++;
/*
* For the current heap tuple, extract all the attributes
* we use in this index, and note which are null.
* For the current heap tuple, extract all the attributes we use
* in this index, and note which are null.
*/
for (i = 1; i <= natts; i++) {
for (i = 1; i <= natts; i++)
{
int attoff;
bool attnull;
/*
* Offsets are from the start of the tuple, and are
* zero-based; indices are one-based. The next call
* returns i - 1. That's data hiding for you.
* zero-based; indices are one-based. The next call returns i
* - 1. That's data hiding for you.
*/
/* attoff = i - 1 */
attoff = AttrNumberGetAttrOffset(i);
/* below, attdata[attoff] set to equal some datum &
* attnull is changed to indicate whether or not the attribute
* is null for this tuple
/*
* below, attdata[attoff] set to equal some datum & attnull is
* changed to indicate whether or not the attribute is null
* for this tuple
*/
attdata[attoff] = GetIndexValue(htup,
htupdesc,
@ -184,10 +202,9 @@ hashbuild(Relation heap,
itup = index_formtuple(itupdesc, attdata, nulls);
/*
* If the single index key is null, we don't insert it into
* the index. Hash tables support scans on '='.
* Relational algebra says that A = B
* returns null if either A or B is null. This
* If the single index key is null, we don't insert it into the
* index. Hash tables support scans on '='. Relational algebra
* says that A = B returns null if either A or B is null. This
* means that no qualification used in an index scan could ever
* return true on a null attribute. It also means that indices
* can't be used by ISNULL or NOTNULL scans, but that's an
@ -195,7 +212,8 @@ hashbuild(Relation heap,
* of the way nulls are handled here.
*/
if (itup->t_info & INDEX_NULL_MASK) {
if (itup->t_info & INDEX_NULL_MASK)
{
pfree(itup);
continue;
}
@ -211,7 +229,8 @@ hashbuild(Relation heap,
/* okay, all heap tuples are indexed */
heap_endscan(hscan);
if (pred != NULL || oldPred != NULL) {
if (pred != NULL || oldPred != NULL)
{
#ifndef OMIT_PARTIAL_INDEX
ExecDestroyTupleTable(tupleTable, true);
pfree(econtext);
@ -219,10 +238,10 @@ hashbuild(Relation heap,
}
/*
* Since we just counted the tuples in the heap, we update its
* stats in pg_class to guarantee that the planner takes advantage
* of the index we just created. Finally, only update statistics
* during normal index definitions, not for indices on system catalogs
* Since we just counted the tuples in the heap, we update its stats
* in pg_class to guarantee that the planner takes advantage of the
* index we just created. Finally, only update statistics during
* normal index definitions, not for indices on system catalogs
* created during bootstrap processing. We must close the relations
* before updatings statistics to guarantee that the relcache entries
* are flushed when we increment the command counter in UpdateStats().
@ -235,8 +254,10 @@ hashbuild(Relation heap,
index_close(index);
UpdateStats(hrelid, nhtups, true);
UpdateStats(irelid, nitups, false);
if (oldPred != NULL) {
if (nitups == nhtups) pred = NULL;
if (oldPred != NULL)
{
if (nitups == nhtups)
pred = NULL;
UpdateIndexPredicate(irelid, oldPred, pred);
}
}
@ -257,7 +278,7 @@ hashbuild(Relation heap,
* to the caller.
*/
InsertIndexResult
hashinsert(Relation rel, Datum *datum, char *nulls, ItemPointer ht_ctid, Relation heapRel)
hashinsert(Relation rel, Datum * datum, char *nulls, ItemPointer ht_ctid, Relation heapRel)
{
HashItem hitem;
IndexTuple itup;
@ -291,9 +312,9 @@ hashgettuple(IndexScanDesc scan, ScanDirection dir)
RetrieveIndexResult res;
/*
* If we've already initialized this scan, we can just advance it
* in the appropriate direction. If we haven't done so yet, we
* call a routine to get the first item in the scan.
* If we've already initialized this scan, we can just advance it in
* the appropriate direction. If we haven't done so yet, we call a
* routine to get the first item in the scan.
*/
if (ItemPointerIsValid(&(scan->currentItemData)))
@ -341,19 +362,22 @@ hashrescan(IndexScanDesc scan, bool fromEnd, ScanKey scankey)
so = (HashScanOpaque) scan->opaque;
/* we hold a read lock on the current page in the scan */
if (ItemPointerIsValid(iptr = &(scan->currentItemData))) {
if (ItemPointerIsValid(iptr = &(scan->currentItemData)))
{
_hash_relbuf(scan->relation, so->hashso_curbuf, HASH_READ);
so->hashso_curbuf = InvalidBuffer;
ItemPointerSetInvalid(iptr);
}
if (ItemPointerIsValid(iptr = &(scan->currentMarkData))) {
if (ItemPointerIsValid(iptr = &(scan->currentMarkData)))
{
_hash_relbuf(scan->relation, so->hashso_mrkbuf, HASH_READ);
so->hashso_mrkbuf = InvalidBuffer;
ItemPointerSetInvalid(iptr);
}
/* reset the scan key */
if (scan->numberOfKeys > 0) {
if (scan->numberOfKeys > 0)
{
memmove(scan->keyData,
scankey,
scan->numberOfKeys * sizeof(ScanKeyData));
@ -373,13 +397,15 @@ hashendscan(IndexScanDesc scan)
so = (HashScanOpaque) scan->opaque;
/* release any locks we still hold */
if (ItemPointerIsValid(iptr = &(scan->currentItemData))) {
if (ItemPointerIsValid(iptr = &(scan->currentItemData)))
{
_hash_relbuf(scan->relation, so->hashso_curbuf, HASH_READ);
so->hashso_curbuf = InvalidBuffer;
ItemPointerSetInvalid(iptr);
}
if (ItemPointerIsValid(iptr = &(scan->currentMarkData))) {
if (ItemPointerIsValid(iptr = &(scan->currentMarkData)))
{
if (BufferIsValid(so->hashso_mrkbuf))
_hash_relbuf(scan->relation, so->hashso_mrkbuf, HASH_READ);
so->hashso_mrkbuf = InvalidBuffer;
@ -390,7 +416,7 @@ hashendscan(IndexScanDesc scan)
_hash_dropscan(scan);
/* be tidy */
pfree (scan->opaque);
pfree(scan->opaque);
}
/*
@ -403,9 +429,10 @@ hashmarkpos(IndexScanDesc scan)
ItemPointer iptr;
HashScanOpaque so;
/* see if we ever call this code. if we do, then so_mrkbuf a
* useful element in the scan->opaque structure. if this procedure
* is never called, so_mrkbuf should be removed from the scan->opaque
/*
* see if we ever call this code. if we do, then so_mrkbuf a useful
* element in the scan->opaque structure. if this procedure is never
* called, so_mrkbuf should be removed from the scan->opaque
* structure.
*/
elog(NOTICE, "Hashmarkpos() called.");
@ -413,14 +440,16 @@ hashmarkpos(IndexScanDesc scan)
so = (HashScanOpaque) scan->opaque;
/* release lock on old marked data, if any */
if (ItemPointerIsValid(iptr = &(scan->currentMarkData))) {
if (ItemPointerIsValid(iptr = &(scan->currentMarkData)))
{
_hash_relbuf(scan->relation, so->hashso_mrkbuf, HASH_READ);
so->hashso_mrkbuf = InvalidBuffer;
ItemPointerSetInvalid(iptr);
}
/* bump lock on currentItemData and copy to currentMarkData */
if (ItemPointerIsValid(&(scan->currentItemData))) {
if (ItemPointerIsValid(&(scan->currentItemData)))
{
so->hashso_mrkbuf = _hash_getbuf(scan->relation,
BufferGetBlockNumber(so->hashso_curbuf),
HASH_READ);
@ -437,9 +466,10 @@ hashrestrpos(IndexScanDesc scan)
ItemPointer iptr;
HashScanOpaque so;
/* see if we ever call this code. if we do, then so_mrkbuf a
* useful element in the scan->opaque structure. if this procedure
* is never called, so_mrkbuf should be removed from the scan->opaque
/*
* see if we ever call this code. if we do, then so_mrkbuf a useful
* element in the scan->opaque structure. if this procedure is never
* called, so_mrkbuf should be removed from the scan->opaque
* structure.
*/
elog(NOTICE, "Hashrestrpos() called.");
@ -447,14 +477,16 @@ hashrestrpos(IndexScanDesc scan)
so = (HashScanOpaque) scan->opaque;
/* release lock on current data, if any */
if (ItemPointerIsValid(iptr = &(scan->currentItemData))) {
if (ItemPointerIsValid(iptr = &(scan->currentItemData)))
{
_hash_relbuf(scan->relation, so->hashso_curbuf, HASH_READ);
so->hashso_curbuf = InvalidBuffer;
ItemPointerSetInvalid(iptr);
}
/* bump lock on currentMarkData and copy to currentItemData */
if (ItemPointerIsValid(&(scan->currentMarkData))) {
if (ItemPointerIsValid(&(scan->currentMarkData)))
{
so->hashso_curbuf =
_hash_getbuf(scan->relation,
BufferGetBlockNumber(so->hashso_mrkbuf),
@ -474,4 +506,3 @@ hashdelete(Relation rel, ItemPointer tid)
/* delete the data from the page */
_hash_pagedel(rel, tid);
}

View File

@ -7,7 +7,7 @@
*
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/access/hash/hashfunc.c,v 1.3 1996/11/10 02:57:40 momjian Exp $
* $Header: /cvsroot/pgsql/src/backend/access/hash/hashfunc.c,v 1.4 1997/09/07 04:37:53 momjian Exp $
*
* NOTES
* These functions are stored in pg_amproc. For each operator class
@ -20,18 +20,21 @@
#include "access/hash.h"
uint32 hashint2(int16 key)
uint32
hashint2(int16 key)
{
return ((uint32) ~key);
return ((uint32) ~ key);
}
uint32 hashint4(uint32 key)
uint32
hashint4(uint32 key)
{
return (~key);
}
/* Hash function from Chris Torek. */
uint32 hashfloat4(float32 keyp)
uint32
hashfloat4(float32 keyp)
{
int len;
int loop;
@ -46,12 +49,15 @@ uint32 hashfloat4(float32 keyp)
h = 0;
if (len > 0) {
if (len > 0)
{
loop = (len + 8 - 1) >> 3;
switch (len & (8 - 1)) {
switch (len & (8 - 1))
{
case 0:
do { /* All fall throughs */
do
{ /* All fall throughs */
HASH4;
case 7:
HASH4;
@ -74,7 +80,8 @@ uint32 hashfloat4(float32 keyp)
}
uint32 hashfloat8(float64 keyp)
uint32
hashfloat8(float64 keyp)
{
int len;
int loop;
@ -89,12 +96,15 @@ uint32 hashfloat8(float64 keyp)
h = 0;
if (len > 0) {
if (len > 0)
{
loop = (len + 8 - 1) >> 3;
switch (len & (8 - 1)) {
switch (len & (8 - 1))
{
case 0:
do { /* All fall throughs */
do
{ /* All fall throughs */
HASH4;
case 7:
HASH4;
@ -117,13 +127,15 @@ uint32 hashfloat8(float64 keyp)
}
uint32 hashoid(Oid key)
uint32
hashoid(Oid key)
{
return ((uint32) ~key);
return ((uint32) ~ key);
}
uint32 hashchar(char key)
uint32
hashchar(char key)
{
int len;
uint32 h;
@ -141,7 +153,8 @@ uint32 hashchar(char key)
return (h);
}
uint32 hashchar2(uint16 intkey)
uint32
hashchar2(uint16 intkey)
{
uint32 h;
int len;
@ -157,7 +170,8 @@ uint32 hashchar2(uint16 intkey)
return (h);
}
uint32 hashchar4(uint32 intkey)
uint32
hashchar4(uint32 intkey)
{
uint32 h;
int len;
@ -173,7 +187,8 @@ uint32 hashchar4(uint32 intkey)
return (h);
}
uint32 hashchar8(char *key)
uint32
hashchar8(char *key)
{
uint32 h;
int len;
@ -188,7 +203,8 @@ uint32 hashchar8(char *key)
return (h);
}
uint32 hashname(NameData *n)
uint32
hashname(NameData * n)
{
uint32 h;
int len;
@ -207,7 +223,8 @@ uint32 hashname(NameData *n)
}
uint32 hashchar16(char *key)
uint32
hashchar16(char *key)
{
uint32 h;
int len;
@ -234,7 +251,8 @@ uint32 hashchar16(char *key)
*
* "OZ's original sdbm hash"
*/
uint32 hashtext(struct varlena *key)
uint32
hashtext(struct varlena * key)
{
int keylen;
char *keydata;
@ -250,12 +268,15 @@ uint32 hashtext(struct varlena *key)
#define HASHC n = *keydata++ + 65599 * n
n = 0;
if (keylen > 0) {
if (keylen > 0)
{
loop = (keylen + 8 - 1) >> 3;
switch (keylen & (8 - 1)) {
switch (keylen & (8 - 1))
{
case 0:
do { /* All fall throughs */
do
{ /* All fall throughs */
HASHC;
case 7:
HASHC;

View File

@ -7,7 +7,7 @@
*
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/access/hash/hashinsert.c,v 1.8 1997/08/12 22:51:30 momjian Exp $
* $Header: /cvsroot/pgsql/src/backend/access/hash/hashinsert.c,v 1.9 1997/09/07 04:37:56 momjian Exp $
*
*-------------------------------------------------------------------------
*/
@ -70,12 +70,12 @@ _hash_doinsert(Relation rel, HashItem hitem)
/*
* XXX btree comment (haven't decided what to do in hash): don't
* think the bucket can be split while we're reading the metapage.
* XXX btree comment (haven't decided what to do in hash): don't think
* the bucket can be split while we're reading the metapage.
*
* If the page was split between the time that we surrendered our
* read lock and acquired our write lock, then this page may no
* longer be the right place for the key we want to insert.
* If the page was split between the time that we surrendered our read
* lock and acquired our write lock, then this page may no longer be
* the right place for the key we want to insert.
*/
/* do the insertion */
@ -124,7 +124,7 @@ _hash_insertonpg(Relation rel,
_hash_checkpage((Page) metap, LH_META_PAGE);
page = BufferGetPage(buf);
_hash_checkpage(page, LH_BUCKET_PAGE|LH_OVERFLOW_PAGE);
_hash_checkpage(page, LH_BUCKET_PAGE | LH_OVERFLOW_PAGE);
pageopaque = (HashPageOpaque) PageGetSpecialPointer(page);
bucket = pageopaque->hasho_bucket;
@ -132,11 +132,15 @@ _hash_insertonpg(Relation rel,
+ (sizeof(HashItemData) - sizeof(IndexTupleData));
itemsz = DOUBLEALIGN(itemsz);
while (PageGetFreeSpace(page) < itemsz) {
while (PageGetFreeSpace(page) < itemsz)
{
/*
* no space on this page; check for an overflow page
*/
if (BlockNumberIsValid(pageopaque->hasho_nextblkno)) {
if (BlockNumberIsValid(pageopaque->hasho_nextblkno))
{
/*
* ovfl page exists; go get it. if it doesn't have room,
* we'll find out next pass through the loop test above.
@ -146,11 +150,13 @@ _hash_insertonpg(Relation rel,
_hash_relbuf(rel, buf, HASH_WRITE);
buf = ovflbuf;
page = BufferGetPage(buf);
} else {
}
else
{
/*
* we're at the end of the bucket chain and we haven't
* found a page with enough room. allocate a new overflow
* page.
* we're at the end of the bucket chain and we haven't found a
* page with enough room. allocate a new overflow page.
*/
do_expand = true;
ovflbuf = _hash_addovflpage(rel, &metabuf, buf);
@ -158,7 +164,8 @@ _hash_insertonpg(Relation rel,
buf = ovflbuf;
page = BufferGetPage(buf);
if (PageGetFreeSpace(page) < itemsz) {
if (PageGetFreeSpace(page) < itemsz)
{
/* it doesn't fit on an empty page -- give up */
elog(WARN, "hash item too large");
}
@ -176,11 +183,13 @@ _hash_insertonpg(Relation rel,
ItemPointerSet(&(res->pointerData), itup_blkno, itup_off);
if (res != NULL) {
if (res != NULL)
{
/*
* Increment the number of keys in the table.
* We switch lock access type just for a moment
* to allow greater accessibility to the metapage.
* Increment the number of keys in the table. We switch lock
* access type just for a moment to allow greater accessibility to
* the metapage.
*/
metap = (HashMetaPage) _hash_chgbufaccess(rel, &metabuf,
HASH_READ, HASH_WRITE);
@ -194,7 +203,8 @@ _hash_insertonpg(Relation rel,
if (do_expand ||
(metap->hashm_nkeys / (metap->hashm_maxbucket + 1))
> metap->hashm_ffactor) {
> metap->hashm_ffactor)
{
_hash_expandtable(rel, metabuf);
}
_hash_relbuf(rel, metabuf, HASH_READ);
@ -220,7 +230,7 @@ _hash_pgaddtup(Relation rel,
Page page;
page = BufferGetPage(buf);
_hash_checkpage(page, LH_BUCKET_PAGE|LH_OVERFLOW_PAGE);
_hash_checkpage(page, LH_BUCKET_PAGE | LH_OVERFLOW_PAGE);
itup_off = OffsetNumberNext(PageGetMaxOffsetNumber(page));
PageAddItem(page, (Item) hitem, itemsize, itup_off, LP_USED);

View File

@ -7,7 +7,7 @@
*
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/access/hash/hashovfl.c,v 1.9 1997/08/12 22:51:34 momjian Exp $
* $Header: /cvsroot/pgsql/src/backend/access/hash/hashovfl.c,v 1.10 1997/09/07 04:37:57 momjian Exp $
*
* NOTES
* Overflow pages look like ordinary relation pages.
@ -21,12 +21,12 @@
#include <utils/memutils.h>
#ifndef HAVE_MEMMOVE
# include <regex/utils.h>
#include <regex/utils.h>
#else
# include <string.h>
#include <string.h>
#endif
static OverflowPageAddress _hash_getovfladdr(Relation rel, Buffer *metabufp);
static OverflowPageAddress _hash_getovfladdr(Relation rel, Buffer * metabufp);
static uint32 _hash_firstfreebit(uint32 map);
/*
@ -40,7 +40,7 @@ static uint32 _hash_firstfreebit(uint32 map);
*
*/
Buffer
_hash_addovflpage(Relation rel, Buffer *metabufp, Buffer buf)
_hash_addovflpage(Relation rel, Buffer * metabufp, Buffer buf)
{
OverflowPageAddress oaddr;
@ -54,7 +54,7 @@ _hash_addovflpage(Relation rel, Buffer *metabufp, Buffer buf)
/* this had better be the last page in a bucket chain */
page = BufferGetPage(buf);
_hash_checkpage(page, LH_BUCKET_PAGE|LH_OVERFLOW_PAGE);
_hash_checkpage(page, LH_BUCKET_PAGE | LH_OVERFLOW_PAGE);
pageopaque = (HashPageOpaque) PageGetSpecialPointer(page);
Assert(!BlockNumberIsValid(pageopaque->hasho_nextblkno));
@ -63,7 +63,8 @@ _hash_addovflpage(Relation rel, Buffer *metabufp, Buffer buf)
/* allocate an empty overflow page */
oaddr = _hash_getovfladdr(rel, metabufp);
if (oaddr == InvalidOvflAddress) {
if (oaddr == InvalidOvflAddress)
{
elog(WARN, "_hash_addovflpage: problem with _hash_getovfladdr.");
}
ovflblkno = OADDR_TO_BLKNO(OADDR_OF(SPLITNUM(oaddr), OPAGENUM(oaddr)));
@ -99,7 +100,7 @@ _hash_addovflpage(Relation rel, Buffer *metabufp, Buffer buf)
*
*/
static OverflowPageAddress
_hash_getovfladdr(Relation rel, Buffer *metabufp)
_hash_getovfladdr(Relation rel, Buffer * metabufp)
{
HashMetaPage metap;
Buffer mapbuf = 0;
@ -114,7 +115,8 @@ _hash_getovfladdr(Relation rel, Buffer *metabufp)
uint32 free_bit;
uint32 free_page;
uint32 in_use_bits;
uint32 i, j;
uint32 i,
j;
metap = (HashMetaPage) _hash_chgbufaccess(rel, metabufp, HASH_READ, HASH_WRITE);
@ -126,7 +128,8 @@ _hash_getovfladdr(Relation rel, Buffer *metabufp)
/* Look through all the free maps to find the first free block */
first_page = metap->LAST_FREED >> (metap->BSHIFT + BYTE_TO_BIT);
for ( i = first_page; i <= free_page; i++ ) {
for (i = first_page; i <= free_page; i++)
{
Page mappage;
blkno = metap->hashm_mapp[i];
@ -141,11 +144,14 @@ _hash_getovfladdr(Relation rel, Buffer *metabufp)
else
in_use_bits = BMPGSZ_BIT(metap) - 1;
if (i == first_page) {
if (i == first_page)
{
bit = metap->LAST_FREED & (BMPGSZ_BIT(metap) - 1);
j = bit / BITS_PER_MAP;
bit = bit & ~(BITS_PER_MAP - 1);
} else {
}
else
{
bit = 0;
j = 0;
}
@ -162,58 +168,66 @@ _hash_getovfladdr(Relation rel, Buffer *metabufp)
#define OVMSG "HASH: Out of overflow pages. Out of luck.\n"
if (offset > SPLITMASK) {
if (++splitnum >= NCACHED) {
if (offset > SPLITMASK)
{
if (++splitnum >= NCACHED)
{
elog(WARN, OVMSG);
}
metap->OVFL_POINT = splitnum;
metap->SPARES[splitnum] = metap->SPARES[splitnum-1];
metap->SPARES[splitnum-1]--;
metap->SPARES[splitnum] = metap->SPARES[splitnum - 1];
metap->SPARES[splitnum - 1]--;
offset = 0;
}
/* Check if we need to allocate a new bitmap page */
if (free_bit == BMPGSZ_BIT(metap) - 1) {
if (free_bit == BMPGSZ_BIT(metap) - 1)
{
/* won't be needing old map page */
_hash_relbuf(rel, mapbuf, HASH_WRITE);
free_page++;
if (free_page >= NCACHED) {
if (free_page >= NCACHED)
{
elog(WARN, OVMSG);
}
/*
* This is tricky. The 1 indicates that you want the new page
* allocated with 1 clear bit. Actually, you are going to
* allocate 2 pages from this map. The first is going to be
* the map page, the second is the overflow page we were
* looking for. The init_bitmap routine automatically, sets
* the first bit of itself to indicate that the bitmap itself
* is in use. We would explicitly set the second bit, but
* don't have to if we tell init_bitmap not to leave it clear
* in the first place.
* allocate 2 pages from this map. The first is going to be the
* map page, the second is the overflow page we were looking for.
* The init_bitmap routine automatically, sets the first bit of
* itself to indicate that the bitmap itself is in use. We would
* explicitly set the second bit, but don't have to if we tell
* init_bitmap not to leave it clear in the first place.
*/
if (_hash_initbitmap(rel, metap, OADDR_OF(splitnum, offset),
1, free_page)) {
1, free_page))
{
elog(WARN, "overflow_page: problem with _hash_initbitmap.");
}
metap->SPARES[splitnum]++;
offset++;
if (offset > SPLITMASK) {
if (++splitnum >= NCACHED) {
if (offset > SPLITMASK)
{
if (++splitnum >= NCACHED)
{
elog(WARN, OVMSG);
}
metap->OVFL_POINT = splitnum;
metap->SPARES[splitnum] = metap->SPARES[splitnum-1];
metap->SPARES[splitnum-1]--;
metap->SPARES[splitnum] = metap->SPARES[splitnum - 1];
metap->SPARES[splitnum - 1]--;
offset = 0;
}
} else {
}
else
{
/*
* Free_bit addresses the last used bit. Bump it to address
* the first available bit.
* Free_bit addresses the last used bit. Bump it to address the
* first available bit.
*/
free_bit++;
SETBIT(freep, free_bit);
@ -225,19 +239,20 @@ _hash_getovfladdr(Relation rel, Buffer *metabufp)
_hash_chgbufaccess(rel, metabufp, HASH_WRITE, HASH_READ);
return (oaddr);
found:
found:
bit = bit + _hash_firstfreebit(freep[j]);
SETBIT(freep, bit);
_hash_wrtbuf(rel, mapbuf);
/*
* Bits are addressed starting with 0, but overflow pages are addressed
* beginning at 1. Bit is a bit addressnumber, so we need to increment
* it to convert it to a page number.
* Bits are addressed starting with 0, but overflow pages are
* addressed beginning at 1. Bit is a bit addressnumber, so we need to
* increment it to convert it to a page number.
*/
bit = 1 + bit + (i * BMPGSZ_BIT(metap));
if (bit >= metap->LAST_FREED) {
if (bit >= metap->LAST_FREED)
{
metap->LAST_FREED = bit - 1;
}
@ -245,7 +260,8 @@ _hash_getovfladdr(Relation rel, Buffer *metabufp)
for (i = 0; (i < splitnum) && (bit > metap->SPARES[i]); i++)
;
offset = (i ? bit - metap->SPARES[i - 1] : bit);
if (offset >= SPLITMASK) {
if (offset >= SPLITMASK)
{
elog(WARN, OVMSG);
}
@ -266,10 +282,12 @@ _hash_getovfladdr(Relation rel, Buffer *metabufp)
static uint32
_hash_firstfreebit(uint32 map)
{
uint32 i, mask;
uint32 i,
mask;
mask = 0x1;
for (i = 0; i < BITS_PER_MAP; i++) {
for (i = 0; i < BITS_PER_MAP; i++)
{
if (!(mask & map))
return (i);
mask = mask << 1;
@ -301,7 +319,8 @@ _hash_freeovflpage(Relation rel, Buffer ovflbuf)
SplitNumber splitnum;
uint32 *freep;
uint32 ovflpgno;
int32 bitmappage, bitmapbit;
int32 bitmappage,
bitmapbit;
Bucket bucket;
metabuf = _hash_getbuf(rel, HASH_METAPAGE, HASH_WRITE);
@ -319,28 +338,28 @@ _hash_freeovflpage(Relation rel, Buffer ovflbuf)
_hash_wrtbuf(rel, ovflbuf);
/*
* fix up the bucket chain. this is a doubly-linked list, so we
* must fix up the bucket chain members behind and ahead of the
* overflow page being deleted.
* fix up the bucket chain. this is a doubly-linked list, so we must
* fix up the bucket chain members behind and ahead of the overflow
* page being deleted.
*
* XXX this should look like:
* - lock prev/next
* - modify/write prev/next (how to do write ordering with a
* doubly-linked list?)
* - unlock prev/next
* XXX this should look like: - lock prev/next - modify/write prev/next
* (how to do write ordering with a doubly-linked list?) - unlock
* prev/next
*/
if (BlockNumberIsValid(prevblkno)) {
if (BlockNumberIsValid(prevblkno))
{
Buffer prevbuf = _hash_getbuf(rel, prevblkno, HASH_WRITE);
Page prevpage = BufferGetPage(prevbuf);
HashPageOpaque prevopaque =
(HashPageOpaque) PageGetSpecialPointer(prevpage);
_hash_checkpage(prevpage, LH_BUCKET_PAGE|LH_OVERFLOW_PAGE);
_hash_checkpage(prevpage, LH_BUCKET_PAGE | LH_OVERFLOW_PAGE);
Assert(prevopaque->hasho_bucket == bucket);
prevopaque->hasho_nextblkno = nextblkno;
_hash_wrtbuf(rel, prevbuf);
}
if (BlockNumberIsValid(nextblkno)) {
if (BlockNumberIsValid(nextblkno))
{
Buffer nextbuf = _hash_getbuf(rel, nextblkno, HASH_WRITE);
Page nextpage = BufferGetPage(nextbuf);
HashPageOpaque nextopaque =
@ -354,14 +373,15 @@ _hash_freeovflpage(Relation rel, Buffer ovflbuf)
/*
* Fix up the overflow page bitmap that tracks this particular
* overflow page. The bitmap can be found in the MetaPageData
* array element hashm_mapp[bitmappage].
* overflow page. The bitmap can be found in the MetaPageData array
* element hashm_mapp[bitmappage].
*/
splitnum = (addr >> SPLITSHIFT);
ovflpgno =
(splitnum ? metap->SPARES[splitnum - 1] : 0) + (addr & SPLITMASK) - 1;
if (ovflpgno < metap->LAST_FREED) {
if (ovflpgno < metap->LAST_FREED)
{
metap->LAST_FREED = ovflpgno;
}
@ -379,12 +399,15 @@ _hash_freeovflpage(Relation rel, Buffer ovflbuf)
_hash_relbuf(rel, metabuf, HASH_WRITE);
/*
* now instantiate the page that replaced this one,
* if it exists, and return that buffer with a write lock.
* now instantiate the page that replaced this one, if it exists, and
* return that buffer with a write lock.
*/
if (BlockNumberIsValid(nextblkno)) {
if (BlockNumberIsValid(nextblkno))
{
return (_hash_getbuf(rel, nextblkno, HASH_WRITE));
} else {
}
else
{
return (InvalidBuffer);
}
}
@ -418,7 +441,8 @@ _hash_initbitmap(Relation rel,
Page pg;
HashPageOpaque op;
uint32 *freep;
int clearbytes, clearints;
int clearbytes,
clearints;
blkno = OADDR_TO_BLKNO(pnum);
buf = _hash_getbuf(rel, blkno, HASH_WRITE);
@ -499,7 +523,8 @@ _hash_squeezebucket(Relation rel,
/*
* if there aren't any overflow pages, there's nothing to squeeze.
*/
if (!BlockNumberIsValid(wopaque->hasho_nextblkno)) {
if (!BlockNumberIsValid(wopaque->hasho_nextblkno))
{
_hash_relbuf(rel, wbuf, HASH_WRITE);
return;
}
@ -508,16 +533,17 @@ _hash_squeezebucket(Relation rel,
* find the last page in the bucket chain by starting at the base
* bucket page and working forward.
*
* XXX if chains tend to be long, we should probably move forward
* using HASH_READ and then _hash_chgbufaccess to HASH_WRITE when
* we reach the end. if they are short we probably don't care
* very much. if the hash function is working at all, they had
* better be short..
* XXX if chains tend to be long, we should probably move forward using
* HASH_READ and then _hash_chgbufaccess to HASH_WRITE when we reach
* the end. if they are short we probably don't care very much. if
* the hash function is working at all, they had better be short..
*/
ropaque = wopaque;
do {
do
{
rblkno = ropaque->hasho_nextblkno;
if (ropaque != wopaque) {
if (ropaque != wopaque)
{
_hash_relbuf(rel, rbuf, HASH_WRITE);
}
rbuf = _hash_getbuf(rel, rblkno, HASH_WRITE);
@ -532,7 +558,8 @@ _hash_squeezebucket(Relation rel,
* squeeze the tuples.
*/
roffnum = FirstOffsetNumber;
for(;;) {
for (;;)
{
hitem = (HashItem) PageGetItem(rpage, PageGetItemId(rpage, roffnum));
itemsz = IndexTupleDSize(hitem->hash_itup)
+ (sizeof(HashItemData) - sizeof(IndexTupleData));
@ -542,12 +569,14 @@ _hash_squeezebucket(Relation rel,
* walk up the bucket chain, looking for a page big enough for
* this item.
*/
while (PageGetFreeSpace(wpage) < itemsz) {
while (PageGetFreeSpace(wpage) < itemsz)
{
wblkno = wopaque->hasho_nextblkno;
_hash_wrtbuf(rel, wbuf);
if (!BlockNumberIsValid(wblkno) || (rblkno == wblkno)) {
if (!BlockNumberIsValid(wblkno) || (rblkno == wblkno))
{
_hash_wrtbuf(rel, rbuf);
/* wbuf is already released */
return;
@ -569,33 +598,35 @@ _hash_squeezebucket(Relation rel,
PageAddItem(wpage, (Item) hitem, itemsz, woffnum, LP_USED);
/*
* delete the tuple from the "read" page.
* PageIndexTupleDelete repacks the ItemId array, so 'roffnum'
* will be "advanced" to the "next" ItemId.
* delete the tuple from the "read" page. PageIndexTupleDelete
* repacks the ItemId array, so 'roffnum' will be "advanced" to
* the "next" ItemId.
*/
PageIndexTupleDelete(rpage, roffnum);
_hash_wrtnorelbuf(rel, rbuf);
/*
* if the "read" page is now empty because of the deletion,
* free it.
* if the "read" page is now empty because of the deletion, free
* it.
*/
if (PageIsEmpty(rpage) && (ropaque->hasho_flag & LH_OVERFLOW_PAGE)) {
if (PageIsEmpty(rpage) && (ropaque->hasho_flag & LH_OVERFLOW_PAGE))
{
rblkno = ropaque->hasho_prevblkno;
Assert(BlockNumberIsValid(rblkno));
/*
* free this overflow page. the extra _hash_relbuf is
* because _hash_freeovflpage gratuitously returns the
* next page (we want the previous page and will get it
* ourselves later).
* free this overflow page. the extra _hash_relbuf is because
* _hash_freeovflpage gratuitously returns the next page (we
* want the previous page and will get it ourselves later).
*/
rbuf = _hash_freeovflpage(rel, rbuf);
if (BufferIsValid(rbuf)) {
if (BufferIsValid(rbuf))
{
_hash_relbuf(rel, rbuf, HASH_WRITE);
}
if (rblkno == wblkno) {
if (rblkno == wblkno)
{
/* rbuf is already released */
_hash_wrtbuf(rel, wbuf);
return;

View File

@ -7,7 +7,7 @@
*
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/access/hash/hashpage.c,v 1.9 1997/08/18 20:51:34 momjian Exp $
* $Header: /cvsroot/pgsql/src/backend/access/hash/hashpage.c,v 1.10 1997/09/07 04:38:00 momjian Exp $
*
* NOTES
* Postgres hash pages look like ordinary relation pages. The opaque
@ -33,9 +33,9 @@
#include <access/genam.h>
#ifndef HAVE_MEMMOVE
# include <regex/utils.h>
#include <regex/utils.h>
#else
# include <string.h>
#include <string.h>
#endif
static void _hash_setpagelock(Relation rel, BlockNumber blkno, int access);
@ -83,7 +83,8 @@ _hash_metapinit(Relation rel)
if (USELOCKING)
RelationSetLockForWrite(rel);
if ((nblocks = RelationGetNumberOfBlocks(rel)) != 0) {
if ((nblocks = RelationGetNumberOfBlocks(rel)) != 0)
{
elog(WARN, "Cannot initialize non-empty hash table %s",
RelationGetRelationName(rel));
}
@ -100,10 +101,12 @@ _hash_metapinit(Relation rel)
metap->hashm_ffactor = DEFAULT_FFACTOR;
metap->hashm_bsize = BufferGetPageSize(metabuf);
metap->hashm_bshift = _hash_log2(metap->hashm_bsize);
for (i = metap->hashm_bshift; i > 0; --i) {
for (i = metap->hashm_bshift; i > 0; --i)
{
if ((1 << i) < (metap->hashm_bsize -
(DOUBLEALIGN(sizeof(PageHeaderData)) +
DOUBLEALIGN(sizeof(HashPageOpaqueData))))) {
DOUBLEALIGN(sizeof(HashPageOpaqueData)))))
{
break;
}
}
@ -112,12 +115,12 @@ _hash_metapinit(Relation rel)
metap->hashm_procid = index_getprocid(rel, 1, HASHPROC);
/*
* Make nelem = 2 rather than 0 so that we end up allocating space
* for the next greater power of two number of buckets.
* Make nelem = 2 rather than 0 so that we end up allocating space for
* the next greater power of two number of buckets.
*/
nelem = 2;
lg2nelem = 1; /*_hash_log2(MAX(nelem, 2)) */
nbuckets = 2; /*1 << lg2nelem */
lg2nelem = 1; /* _hash_log2(MAX(nelem, 2)) */
nbuckets = 2; /* 1 << lg2nelem */
memset((char *) metap->hashm_spares, 0, sizeof(metap->hashm_spares));
memset((char *) metap->hashm_mapp, 0, sizeof(metap->hashm_mapp));
@ -139,8 +142,8 @@ _hash_metapinit(Relation rel)
/*
* First bitmap page is at: splitpoint lg2nelem page offset 1 which
* turns out to be page 3. Couldn't initialize page 3 until we created
* the first two buckets above.
* turns out to be page 3. Couldn't initialize page 3 until we
* created the first two buckets above.
*/
if (_hash_initbitmap(rel, metap, OADDR_OF(lg2nelem, 1), lg2nelem + 1, 0))
elog(WARN, "Problem with _hash_initbitmap.");
@ -151,7 +154,8 @@ _hash_metapinit(Relation rel)
/*
* initialize the first two buckets
*/
for (i = 0; i <= 1; i++) {
for (i = 0; i <= 1; i++)
{
buf = _hash_getbuf(rel, BUCKET_TO_BLKNO(i), HASH_WRITE);
pg = BufferGetPage(buf);
_hash_pageinit(pg, BufferGetPageSize(buf));
@ -186,10 +190,12 @@ _hash_getbuf(Relation rel, BlockNumber blkno, int access)
{
Buffer buf;
if (blkno == P_NEW) {
if (blkno == P_NEW)
{
elog(WARN, "_hash_getbuf: internal error: hash AM does not use P_NEW");
}
switch (access) {
switch (access)
{
case HASH_WRITE:
case HASH_READ:
_hash_setpagelock(rel, blkno, access);
@ -215,7 +221,8 @@ _hash_relbuf(Relation rel, Buffer buf, int access)
blkno = BufferGetBlockNumber(buf);
switch (access) {
switch (access)
{
case HASH_WRITE:
case HASH_READ:
_hash_unsetpagelock(rel, blkno, access);
@ -263,7 +270,7 @@ _hash_wrtnorelbuf(Relation rel, Buffer buf)
Page
_hash_chgbufaccess(Relation rel,
Buffer *bufp,
Buffer * bufp,
int from_access,
int to_access)
{
@ -271,7 +278,8 @@ _hash_chgbufaccess(Relation rel,
blkno = BufferGetBlockNumber(*bufp);
switch (from_access) {
switch (from_access)
{
case HASH_WRITE:
_hash_wrtbuf(rel, *bufp);
break;
@ -314,10 +322,12 @@ _hash_setpagelock(Relation rel,
{
ItemPointerData iptr;
if (USELOCKING) {
if (USELOCKING)
{
ItemPointerSet(&iptr, blkno, 1);
switch (access) {
switch (access)
{
case HASH_WRITE:
RelationSetSingleWLockPage(rel, &iptr);
break;
@ -339,10 +349,12 @@ _hash_unsetpagelock(Relation rel,
{
ItemPointerData iptr;
if (USELOCKING) {
if (USELOCKING)
{
ItemPointerSet(&iptr, blkno, 1);
switch (access) {
switch (access)
{
case HASH_WRITE:
RelationUnsetSingleWLockPage(rel, &iptr);
break;
@ -373,18 +385,22 @@ _hash_pagedel(Relation rel, ItemPointer tid)
buf = _hash_getbuf(rel, blkno, HASH_WRITE);
page = BufferGetPage(buf);
_hash_checkpage(page, LH_BUCKET_PAGE|LH_OVERFLOW_PAGE);
_hash_checkpage(page, LH_BUCKET_PAGE | LH_OVERFLOW_PAGE);
opaque = (HashPageOpaque) PageGetSpecialPointer(page);
PageIndexTupleDelete(page, offno);
_hash_wrtnorelbuf(rel, buf);
if (PageIsEmpty(page) && (opaque->hasho_flag & LH_OVERFLOW_PAGE)) {
if (PageIsEmpty(page) && (opaque->hasho_flag & LH_OVERFLOW_PAGE))
{
buf = _hash_freeovflpage(rel, buf);
if (BufferIsValid(buf)) {
if (BufferIsValid(buf))
{
_hash_relbuf(rel, buf, HASH_WRITE);
}
} else {
}
else
{
_hash_relbuf(rel, buf, HASH_WRITE);
}
@ -414,12 +430,13 @@ _hash_expandtable(Relation rel, Buffer metabuf)
old_bucket = (metap->MAX_BUCKET & metap->LOW_MASK);
/*
* If the split point is increasing (MAX_BUCKET's log base 2
* * increases), we need to copy the current contents of the spare
* split bucket to the next bucket.
* If the split point is increasing (MAX_BUCKET's log base 2 *
* increases), we need to copy the current contents of the spare split
* bucket to the next bucket.
*/
spare_ndx = _hash_log2(metap->MAX_BUCKET + 1);
if (spare_ndx > metap->OVFL_POINT) {
if (spare_ndx > metap->OVFL_POINT)
{
metap = (HashMetaPage) _hash_chgbufaccess(rel, &metabuf, HASH_READ, HASH_WRITE);
metap->SPARES[spare_ndx] = metap->SPARES[metap->OVFL_POINT];
@ -427,7 +444,8 @@ _hash_expandtable(Relation rel, Buffer metabuf)
metap = (HashMetaPage) _hash_chgbufaccess(rel, &metabuf, HASH_WRITE, HASH_READ);
}
if (new_bucket > metap->HIGH_MASK) {
if (new_bucket > metap->HIGH_MASK)
{
/* Starting a new doubling */
metap = (HashMetaPage) _hash_chgbufaccess(rel, &metabuf, HASH_READ, HASH_WRITE);
@ -500,23 +518,25 @@ _hash_splitpage(Relation rel,
_hash_wrtnorelbuf(rel, nbuf);
/*
* make sure the old bucket isn't empty. advance 'opage' and
* friends through the overflow bucket chain until we find a
* non-empty page.
* make sure the old bucket isn't empty. advance 'opage' and friends
* through the overflow bucket chain until we find a non-empty page.
*
* XXX we should only need this once, if we are careful to
* preserve the invariant that overflow pages are never empty.
* XXX we should only need this once, if we are careful to preserve the
* invariant that overflow pages are never empty.
*/
_hash_checkpage(opage, LH_BUCKET_PAGE);
oopaque = (HashPageOpaque) PageGetSpecialPointer(opage);
if (PageIsEmpty(opage)) {
if (PageIsEmpty(opage))
{
oblkno = oopaque->hasho_nextblkno;
_hash_relbuf(rel, obuf, HASH_WRITE);
if (!BlockNumberIsValid(oblkno)) {
if (!BlockNumberIsValid(oblkno))
{
/*
* the old bucket is completely empty; of course, the new
* bucket will be as well, but since it's a base bucket
* page we don't care.
* bucket will be as well, but since it's a base bucket page
* we don't care.
*/
_hash_relbuf(rel, nbuf, HASH_WRITE);
return;
@ -524,7 +544,8 @@ _hash_splitpage(Relation rel,
obuf = _hash_getbuf(rel, oblkno, HASH_WRITE);
opage = BufferGetPage(obuf);
_hash_checkpage(opage, LH_OVERFLOW_PAGE);
if (PageIsEmpty(opage)) {
if (PageIsEmpty(opage))
{
elog(WARN, "_hash_splitpage: empty overflow page %d", oblkno);
}
oopaque = (HashPageOpaque) PageGetSpecialPointer(opage);
@ -532,26 +553,31 @@ _hash_splitpage(Relation rel,
/*
* we are now guaranteed that 'opage' is not empty. partition the
* tuples in the old bucket between the old bucket and the new
* bucket, advancing along their respective overflow bucket chains
* and adding overflow pages as needed.
* tuples in the old bucket between the old bucket and the new bucket,
* advancing along their respective overflow bucket chains and adding
* overflow pages as needed.
*/
ooffnum = FirstOffsetNumber;
omaxoffnum = PageGetMaxOffsetNumber(opage);
for (;;) {
for (;;)
{
/*
* at each iteration through this loop, each of these variables
* should be up-to-date: obuf opage oopaque ooffnum omaxoffnum
*/
/* check if we're at the end of the page */
if (ooffnum > omaxoffnum) {
if (ooffnum > omaxoffnum)
{
/* at end of page, but check for overflow page */
oblkno = oopaque->hasho_nextblkno;
if (BlockNumberIsValid(oblkno)) {
if (BlockNumberIsValid(oblkno))
{
/*
* we ran out of tuples on this particular page, but
* we have more overflow pages; re-init values.
* we ran out of tuples on this particular page, but we
* have more overflow pages; re-init values.
*/
_hash_wrtbuf(rel, obuf);
obuf = _hash_getbuf(rel, oblkno, HASH_WRITE);
@ -560,19 +586,23 @@ _hash_splitpage(Relation rel,
oopaque = (HashPageOpaque) PageGetSpecialPointer(opage);
/* we're guaranteed that an ovfl page has at least 1 tuple */
if (PageIsEmpty(opage)) {
if (PageIsEmpty(opage))
{
elog(WARN, "_hash_splitpage: empty ovfl page %d!",
oblkno);
}
ooffnum = FirstOffsetNumber;
omaxoffnum = PageGetMaxOffsetNumber(opage);
} else {
}
else
{
/*
* we're at the end of the bucket chain, so now we're
* really done with everything. before quitting, call
* _hash_squeezebucket to ensure the tuples in the
* bucket (including the overflow pages) are packed as
* tightly as possible.
* _hash_squeezebucket to ensure the tuples in the bucket
* (including the overflow pages) are packed as tightly as
* possible.
*/
_hash_wrtbuf(rel, obuf);
_hash_wrtbuf(rel, nbuf);
@ -588,24 +618,26 @@ _hash_splitpage(Relation rel,
datum = index_getattr(itup, 1, itupdesc, &null);
bucket = _hash_call(rel, metap, datum);
if (bucket == nbucket) {
if (bucket == nbucket)
{
/*
* insert the tuple into the new bucket. if it doesn't
* fit on the current page in the new bucket, we must
* allocate a new overflow page and place the tuple on
* that page instead.
* insert the tuple into the new bucket. if it doesn't fit on
* the current page in the new bucket, we must allocate a new
* overflow page and place the tuple on that page instead.
*/
itemsz = IndexTupleDSize(hitem->hash_itup)
+ (sizeof(HashItemData) - sizeof(IndexTupleData));
itemsz = DOUBLEALIGN(itemsz);
if (PageGetFreeSpace(npage) < itemsz) {
if (PageGetFreeSpace(npage) < itemsz)
{
ovflbuf = _hash_addovflpage(rel, &metabuf, nbuf);
_hash_wrtbuf(rel, nbuf);
nbuf = ovflbuf;
npage = BufferGetPage(nbuf);
_hash_checkpage(npage, LH_BUCKET_PAGE|LH_OVERFLOW_PAGE);
_hash_checkpage(npage, LH_BUCKET_PAGE | LH_OVERFLOW_PAGE);
}
noffnum = OffsetNumberNext(PageGetMaxOffsetNumber(npage));
@ -615,53 +647,58 @@ _hash_splitpage(Relation rel,
/*
* now delete the tuple from the old bucket. after this
* section of code, 'ooffnum' will actually point to the
* ItemId to which we would point if we had advanced it
* before the deletion (PageIndexTupleDelete repacks the
* ItemId array). this also means that 'omaxoffnum' is
* exactly one less than it used to be, so we really can
* just decrement it instead of calling
* PageGetMaxOffsetNumber.
* ItemId to which we would point if we had advanced it before
* the deletion (PageIndexTupleDelete repacks the ItemId
* array). this also means that 'omaxoffnum' is exactly one
* less than it used to be, so we really can just decrement it
* instead of calling PageGetMaxOffsetNumber.
*/
PageIndexTupleDelete(opage, ooffnum);
_hash_wrtnorelbuf(rel, obuf);
omaxoffnum = OffsetNumberPrev(omaxoffnum);
/*
* tidy up. if the old page was an overflow page and it
* is now empty, we must free it (we want to preserve the
* tidy up. if the old page was an overflow page and it is
* now empty, we must free it (we want to preserve the
* invariant that overflow pages cannot be empty).
*/
if (PageIsEmpty(opage) &&
(oopaque->hasho_flag & LH_OVERFLOW_PAGE)) {
(oopaque->hasho_flag & LH_OVERFLOW_PAGE))
{
obuf = _hash_freeovflpage(rel, obuf);
/* check that we're not through the bucket chain */
if (BufferIsInvalid(obuf)) {
if (BufferIsInvalid(obuf))
{
_hash_wrtbuf(rel, nbuf);
_hash_squeezebucket(rel, metap, obucket);
return;
}
/*
* re-init. again, we're guaranteed that an ovfl page
* has at least one tuple.
* re-init. again, we're guaranteed that an ovfl page has
* at least one tuple.
*/
opage = BufferGetPage(obuf);
_hash_checkpage(opage, LH_OVERFLOW_PAGE);
oblkno = BufferGetBlockNumber(obuf);
oopaque = (HashPageOpaque) PageGetSpecialPointer(opage);
if (PageIsEmpty(opage)) {
if (PageIsEmpty(opage))
{
elog(WARN, "_hash_splitpage: empty overflow page %d",
oblkno);
}
ooffnum = FirstOffsetNumber;
omaxoffnum = PageGetMaxOffsetNumber(opage);
}
} else {
}
else
{
/*
* the tuple stays on this page. we didn't move anything,
* so we didn't delete anything and therefore we don't
* have to change 'omaxoffnum'.
* the tuple stays on this page. we didn't move anything, so
* we didn't delete anything and therefore we don't have to
* change 'omaxoffnum'.
*
* XXX any hash value from [0, nbucket-1] will map to this
* bucket, which doesn't make sense to me.
@ -669,5 +706,5 @@ _hash_splitpage(Relation rel,
ooffnum = OffsetNumberNext(ooffnum);
}
}
/*NOTREACHED*/
/* NOTREACHED */
}

View File

@ -7,7 +7,7 @@
*
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/access/hash/hashscan.c,v 1.8 1996/11/15 18:36:31 momjian Exp $
* $Header: /cvsroot/pgsql/src/backend/access/hash/hashscan.c,v 1.9 1997/09/07 04:38:01 momjian Exp $
*
* NOTES
* Because we can be doing an index scan on a relation while we
@ -34,7 +34,8 @@
static void _hash_scandel(IndexScanDesc scan, BlockNumber blkno, OffsetNumber offno);
static bool _hash_scantouched(IndexScanDesc scan, BlockNumber blkno, OffsetNumber offno);
typedef struct HashScanListData {
typedef struct HashScanListData
{
IndexScanDesc hashsl_scan;
struct HashScanListData *hashsl_next;
} HashScanListData;
@ -63,12 +64,14 @@ _hash_regscan(IndexScanDesc scan)
void
_hash_dropscan(IndexScanDesc scan)
{
HashScanList chk, last;
HashScanList chk,
last;
last = (HashScanList) NULL;
for (chk = HashScans;
chk != (HashScanList) NULL && chk->hashsl_scan != scan;
chk = chk->hashsl_next) {
chk = chk->hashsl_next)
{
last = chk;
}
@ -80,7 +83,7 @@ _hash_dropscan(IndexScanDesc scan)
else
last->hashsl_next = chk->hashsl_next;
pfree (chk);
pfree(chk);
}
void
@ -90,7 +93,8 @@ _hash_adjscans(Relation rel, ItemPointer tid)
Oid relid;
relid = rel->rd_id;
for (l = HashScans; l != (HashScanList) NULL; l = l->hashsl_next) {
for (l = HashScans; l != (HashScanList) NULL; l = l->hashsl_next)
{
if (relid == l->hashsl_scan->relation->rd_id)
_hash_scandel(l->hashsl_scan, ItemPointerGetBlockNumber(tid),
ItemPointerGetOffsetNumber(tid));
@ -116,7 +120,8 @@ _hash_scandel(IndexScanDesc scan, BlockNumber blkno, OffsetNumber offno)
current = &(scan->currentItemData);
if (ItemPointerIsValid(current)
&& ItemPointerGetBlockNumber(current) == blkno
&& ItemPointerGetOffsetNumber(current) >= offno) {
&& ItemPointerGetOffsetNumber(current) >= offno)
{
_hash_step(scan, &buf, BackwardScanDirection, metabuf);
so->hashso_curbuf = buf;
}
@ -124,8 +129,10 @@ _hash_scandel(IndexScanDesc scan, BlockNumber blkno, OffsetNumber offno)
current = &(scan->currentMarkData);
if (ItemPointerIsValid(current)
&& ItemPointerGetBlockNumber(current) == blkno
&& ItemPointerGetOffsetNumber(current) >= offno) {
&& ItemPointerGetOffsetNumber(current) >= offno)
{
ItemPointerData tmp;
tmp = *current;
*current = scan->currentItemData;
scan->currentItemData = tmp;

View File

@ -7,7 +7,7 @@
*
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/access/hash/hashsearch.c,v 1.10 1997/06/28 05:45:40 vadim Exp $
* $Header: /cvsroot/pgsql/src/backend/access/hash/hashsearch.c,v 1.11 1997/09/07 04:38:02 momjian Exp $
*
*-------------------------------------------------------------------------
*/
@ -18,9 +18,9 @@
#include <storage/bufmgr.h>
#ifndef HAVE_MEMMOVE
# include "regex/utils.h"
#include "regex/utils.h"
#else
# include <string.h>
#include <string.h>
#endif
/*
@ -31,7 +31,7 @@ void
_hash_search(Relation rel,
int keysz,
ScanKey scankey,
Buffer *bufP,
Buffer * bufP,
HashMetaPage metap)
{
BlockNumber blkno;
@ -39,14 +39,17 @@ _hash_search(Relation rel,
Bucket bucket;
if (scankey == (ScanKey) NULL ||
(keyDatum = scankey[0].sk_argument) == (Datum) NULL) {
(keyDatum = scankey[0].sk_argument) == (Datum) NULL)
{
/*
* If the scankey argument is NULL, all tuples will satisfy
* the scan so we start the scan at the first bucket (bucket
* 0).
* If the scankey argument is NULL, all tuples will satisfy the
* scan so we start the scan at the first bucket (bucket 0).
*/
bucket = 0;
} else {
}
else
{
bucket = _hash_call(rel, metap, keyDatum);
}
@ -86,11 +89,12 @@ _hash_next(IndexScanDesc scan, ScanDirection dir)
/*
* XXX 10 may 91: somewhere there's a bug in our management of the
* cached buffer for this scan. wei discovered it. the following
* is a workaround so he can work until i figure out what's going on.
* cached buffer for this scan. wei discovered it. the following is
* a workaround so he can work until i figure out what's going on.
*/
if (!BufferIsValid(so->hashso_curbuf)) {
if (!BufferIsValid(so->hashso_curbuf))
{
so->hashso_curbuf = _hash_getbuf(rel,
ItemPointerGetBlockNumber(current),
HASH_READ);
@ -100,11 +104,12 @@ _hash_next(IndexScanDesc scan, ScanDirection dir)
buf = so->hashso_curbuf;
/*
* step to next valid tuple. note that _hash_step releases our
* lock on 'metabuf'; if we switch to a new 'buf' while looking
* for the next tuple, we come back with a lock on that buffer.
* step to next valid tuple. note that _hash_step releases our lock
* on 'metabuf'; if we switch to a new 'buf' while looking for the
* next tuple, we come back with a lock on that buffer.
*/
if (!_hash_step(scan, &buf, dir, metabuf)) {
if (!_hash_step(scan, &buf, dir, metabuf))
{
return ((RetrieveIndexResult) NULL);
}
@ -112,7 +117,7 @@ _hash_next(IndexScanDesc scan, ScanDirection dir)
current = &(scan->currentItemData);
offnum = ItemPointerGetOffsetNumber(current);
page = BufferGetPage(buf);
_hash_checkpage(page, LH_BUCKET_PAGE|LH_OVERFLOW_PAGE);
_hash_checkpage(page, LH_BUCKET_PAGE | LH_OVERFLOW_PAGE);
hitem = (HashItem) PageGetItem(page, PageGetItemId(page, offnum));
itup = &hitem->hash_itup;
res = FormRetrieveIndexResult(current, &(itup->t_tid));
@ -122,14 +127,15 @@ _hash_next(IndexScanDesc scan, ScanDirection dir)
static void
_hash_readnext(Relation rel,
Buffer *bufp, Page *pagep, HashPageOpaque *opaquep)
Buffer * bufp, Page * pagep, HashPageOpaque * opaquep)
{
BlockNumber blkno;
blkno = (*opaquep)->hasho_nextblkno;
_hash_relbuf(rel, *bufp, HASH_READ);
*bufp = InvalidBuffer;
if (BlockNumberIsValid(blkno)) {
if (BlockNumberIsValid(blkno))
{
*bufp = _hash_getbuf(rel, blkno, HASH_READ);
*pagep = BufferGetPage(*bufp);
_hash_checkpage(*pagep, LH_OVERFLOW_PAGE);
@ -140,19 +146,21 @@ _hash_readnext(Relation rel,
static void
_hash_readprev(Relation rel,
Buffer *bufp, Page *pagep, HashPageOpaque *opaquep)
Buffer * bufp, Page * pagep, HashPageOpaque * opaquep)
{
BlockNumber blkno;
blkno = (*opaquep)->hasho_prevblkno;
_hash_relbuf(rel, *bufp, HASH_READ);
*bufp = InvalidBuffer;
if (BlockNumberIsValid(blkno)) {
if (BlockNumberIsValid(blkno))
{
*bufp = _hash_getbuf(rel, blkno, HASH_READ);
*pagep = BufferGetPage(*bufp);
_hash_checkpage(*pagep, LH_BUCKET_PAGE|LH_OVERFLOW_PAGE);
_hash_checkpage(*pagep, LH_BUCKET_PAGE | LH_OVERFLOW_PAGE);
*opaquep = (HashPageOpaque) PageGetSpecialPointer(*pagep);
if (PageIsEmpty(*pagep)) {
if (PageIsEmpty(*pagep))
{
Assert((*opaquep)->hasho_flag & LH_BUCKET_PAGE);
_hash_relbuf(rel, *bufp, HASH_READ);
*bufp = InvalidBuffer;
@ -194,10 +202,9 @@ _hash_first(IndexScanDesc scan, ScanDirection dir)
_hash_checkpage((Page) metap, LH_META_PAGE);
/*
* XXX -- The attribute number stored in the scan key is the attno
* in the heap relation. We need to transmogrify this into
* the index relation attno here. For the moment, we have
* hardwired attno == 1.
* XXX -- The attribute number stored in the scan key is the attno in
* the heap relation. We need to transmogrify this into the index
* relation attno here. For the moment, we have hardwired attno == 1.
*/
/* find the correct bucket page and load it into buf */
@ -208,25 +215,30 @@ _hash_first(IndexScanDesc scan, ScanDirection dir)
/*
* if we are scanning forward, we need to find the first non-empty
* page (if any) in the bucket chain. since overflow pages are
* never empty, this had better be either the bucket page or the
* first overflow page.
* page (if any) in the bucket chain. since overflow pages are never
* empty, this had better be either the bucket page or the first
* overflow page.
*
* if we are scanning backward, we always go all the way to the
* end of the bucket chain.
* if we are scanning backward, we always go all the way to the end of
* the bucket chain.
*/
if (PageIsEmpty(page)) {
if (BlockNumberIsValid(opaque->hasho_nextblkno)) {
if (PageIsEmpty(page))
{
if (BlockNumberIsValid(opaque->hasho_nextblkno))
{
_hash_readnext(rel, &buf, &page, &opaque);
} else {
}
else
{
ItemPointerSetInvalid(current);
so->hashso_curbuf = InvalidBuffer;
/*
* If there is no scankeys, all tuples will satisfy
* the scan - so we continue in _hash_step to get
* tuples from all buckets. - vadim 04/29/97
* If there is no scankeys, all tuples will satisfy the scan -
* so we continue in _hash_step to get tuples from all
* buckets. - vadim 04/29/97
*/
if ( scan->numberOfKeys >= 1 )
if (scan->numberOfKeys >= 1)
{
_hash_relbuf(rel, buf, HASH_READ);
_hash_relbuf(rel, metabuf, HASH_READ);
@ -234,13 +246,16 @@ _hash_first(IndexScanDesc scan, ScanDirection dir)
}
}
}
if (ScanDirectionIsBackward(dir)) {
while (BlockNumberIsValid(opaque->hasho_nextblkno)) {
if (ScanDirectionIsBackward(dir))
{
while (BlockNumberIsValid(opaque->hasho_nextblkno))
{
_hash_readnext(rel, &buf, &page, &opaque);
}
}
if (!_hash_step(scan, &buf, dir, metabuf)) {
if (!_hash_step(scan, &buf, dir, metabuf))
{
return ((RetrieveIndexResult) NULL);
}
@ -248,7 +263,7 @@ _hash_first(IndexScanDesc scan, ScanDirection dir)
current = &(scan->currentItemData);
offnum = ItemPointerGetOffsetNumber(current);
page = BufferGetPage(buf);
_hash_checkpage(page, LH_BUCKET_PAGE|LH_OVERFLOW_PAGE);
_hash_checkpage(page, LH_BUCKET_PAGE | LH_OVERFLOW_PAGE);
hitem = (HashItem) PageGetItem(page, PageGetItemId(page, offnum));
itup = &hitem->hash_itup;
res = FormRetrieveIndexResult(current, &(itup->t_tid));
@ -269,7 +284,7 @@ _hash_first(IndexScanDesc scan, ScanDirection dir)
* 'metabuf' is released when this returns.
*/
bool
_hash_step(IndexScanDesc scan, Buffer *bufP, ScanDirection dir, Buffer metabuf)
_hash_step(IndexScanDesc scan, Buffer * bufP, ScanDirection dir, Buffer metabuf)
{
Relation rel;
ItemPointer current;
@ -296,7 +311,7 @@ _hash_step(IndexScanDesc scan, Buffer *bufP, ScanDirection dir, Buffer metabuf)
buf = *bufP;
page = BufferGetPage(buf);
_hash_checkpage(page, LH_BUCKET_PAGE|LH_OVERFLOW_PAGE);
_hash_checkpage(page, LH_BUCKET_PAGE | LH_OVERFLOW_PAGE);
opaque = (HashPageOpaque) PageGetSpecialPointer(page);
/*
@ -305,37 +320,48 @@ _hash_step(IndexScanDesc scan, Buffer *bufP, ScanDirection dir, Buffer metabuf)
* presumably want to start at the beginning/end of the page...
*/
maxoff = PageGetMaxOffsetNumber(page);
if (ItemPointerIsValid(current)) {
if (ItemPointerIsValid(current))
{
offnum = ItemPointerGetOffsetNumber(current);
} else {
}
else
{
offnum = InvalidOffsetNumber;
}
/*
* 'offnum' now points to the last tuple we have seen (if any).
*
* continue to step through tuples until:
* 1) we get to the end of the bucket chain or
* 2) we find a valid tuple.
* continue to step through tuples until: 1) we get to the end of the
* bucket chain or 2) we find a valid tuple.
*/
do {
do
{
bucket = opaque->hasho_bucket;
switch (dir) {
switch (dir)
{
case ForwardScanDirection:
if (offnum != InvalidOffsetNumber) {
if (offnum != InvalidOffsetNumber)
{
offnum = OffsetNumberNext(offnum); /* move forward */
} else {
}
else
{
offnum = FirstOffsetNumber; /* new page */
}
while (offnum > maxoff) {
while (offnum > maxoff)
{
/*
* either this page is empty (maxoff ==
* InvalidOffsetNumber) or we ran off the end.
*/
_hash_readnext(rel, &buf, &page, &opaque);
if (BufferIsInvalid(buf)) { /* end of chain */
if (allbuckets && bucket < metap->hashm_maxbucket) {
if (BufferIsInvalid(buf))
{ /* end of chain */
if (allbuckets && bucket < metap->hashm_maxbucket)
{
++bucket;
blkno = BUCKET_TO_BLKNO(bucket);
buf = _hash_getbuf(rel, blkno, HASH_READ);
@ -344,16 +370,21 @@ _hash_step(IndexScanDesc scan, Buffer *bufP, ScanDirection dir, Buffer metabuf)
opaque = (HashPageOpaque) PageGetSpecialPointer(page);
Assert(opaque->hasho_bucket == bucket);
while (PageIsEmpty(page) &&
BlockNumberIsValid(opaque->hasho_nextblkno)) {
BlockNumberIsValid(opaque->hasho_nextblkno))
{
_hash_readnext(rel, &buf, &page, &opaque);
}
maxoff = PageGetMaxOffsetNumber(page);
offnum = FirstOffsetNumber;
} else {
}
else
{
maxoff = offnum = InvalidOffsetNumber;
break; /* while */
}
} else {
}
else
{
/* _hash_readnext never returns an empty page */
maxoff = PageGetMaxOffsetNumber(page);
offnum = FirstOffsetNumber;
@ -361,19 +392,26 @@ _hash_step(IndexScanDesc scan, Buffer *bufP, ScanDirection dir, Buffer metabuf)
}
break;
case BackwardScanDirection:
if (offnum != InvalidOffsetNumber) {
if (offnum != InvalidOffsetNumber)
{
offnum = OffsetNumberPrev(offnum); /* move back */
} else {
offnum = maxoff; /* new page */
}
while (offnum < FirstOffsetNumber) {
else
{
offnum = maxoff;/* new page */
}
while (offnum < FirstOffsetNumber)
{
/*
* either this page is empty (offnum ==
* InvalidOffsetNumber) or we ran off the end.
*/
_hash_readprev(rel, &buf, &page, &opaque);
if (BufferIsInvalid(buf)) { /* end of chain */
if (allbuckets && bucket > 0) {
if (BufferIsInvalid(buf))
{ /* end of chain */
if (allbuckets && bucket > 0)
{
--bucket;
blkno = BUCKET_TO_BLKNO(bucket);
buf = _hash_getbuf(rel, blkno, HASH_READ);
@ -381,15 +419,20 @@ _hash_step(IndexScanDesc scan, Buffer *bufP, ScanDirection dir, Buffer metabuf)
_hash_checkpage(page, LH_BUCKET_PAGE);
opaque = (HashPageOpaque) PageGetSpecialPointer(page);
Assert(opaque->hasho_bucket == bucket);
while (BlockNumberIsValid(opaque->hasho_nextblkno)) {
while (BlockNumberIsValid(opaque->hasho_nextblkno))
{
_hash_readnext(rel, &buf, &page, &opaque);
}
maxoff = offnum = PageGetMaxOffsetNumber(page);
} else {
}
else
{
maxoff = offnum = InvalidOffsetNumber;
break; /* while */
}
} else {
}
else
{
/* _hash_readprev never returns an empty page */
maxoff = offnum = PageGetMaxOffsetNumber(page);
}
@ -402,11 +445,12 @@ _hash_step(IndexScanDesc scan, Buffer *bufP, ScanDirection dir, Buffer metabuf)
}
/* we ran off the end of the world without finding a match */
if (offnum == InvalidOffsetNumber) {
if (offnum == InvalidOffsetNumber)
{
_hash_relbuf(rel, metabuf, HASH_READ);
*bufP = so->hashso_curbuf = InvalidBuffer;
ItemPointerSetInvalid(current);
return(false);
return (false);
}
/* get ready to check this tuple */
@ -419,5 +463,5 @@ _hash_step(IndexScanDesc scan, Buffer *bufP, ScanDirection dir, Buffer metabuf)
blkno = BufferGetBlockNumber(buf);
*bufP = so->hashso_curbuf = buf;
ItemPointerSet(current, blkno, offnum);
return(true);
return (true);
}

View File

@ -7,7 +7,7 @@
*
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/access/hash/Attic/hashstrat.c,v 1.9 1997/08/20 02:01:42 vadim Exp $
* $Header: /cvsroot/pgsql/src/backend/access/hash/Attic/hashstrat.c,v 1.10 1997/09/07 04:38:03 momjian Exp $
*
*-------------------------------------------------------------------------
*/
@ -38,11 +38,12 @@ static StrategyEvaluationData HTEvaluationData = {
/* XXX static for simplicity */
HTMaxStrategyNumber,
(StrategyTransformMap)HTNegate,
(StrategyTransformMap)HTCommute,
(StrategyTransformMap)HTNegateCommute,
{NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL}
(StrategyTransformMap) HTNegate,
(StrategyTransformMap) HTCommute,
(StrategyTransformMap) HTNegateCommute,
{NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL}
};
#endif
/* ----------------------------------------------------------------
@ -64,6 +65,7 @@ _hash_getstrat(Relation rel,
return (strat);
}
#endif
#ifdef NOT_USED
@ -77,4 +79,5 @@ _hash_invokestrat(Relation rel,
return (RelationInvokeStrategy(rel, &HTEvaluationData, attno, strat,
left, right));
}
#endif

View File

@ -7,7 +7,7 @@
*
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/access/hash/hashutil.c,v 1.9 1997/08/14 05:01:32 vadim Exp $
* $Header: /cvsroot/pgsql/src/backend/access/hash/hashutil.c,v 1.10 1997/09/07 04:38:04 momjian Exp $
*
*-------------------------------------------------------------------------
*/
@ -20,9 +20,9 @@
#include <access/iqual.h>
#ifndef HAVE_MEMMOVE
# include <regex/utils.h>
#include <regex/utils.h>
#else
# include <string.h>
#include <string.h>
#endif
ScanKey
@ -41,7 +41,8 @@ _hash_mkscankey(Relation rel, IndexTuple itup, HashMetaPage metap)
skey = (ScanKey) palloc(natts * sizeof(ScanKeyData));
for (i = 0; i < natts; i++) {
for (i = 0; i < natts; i++)
{
arg = index_getattr(itup, i + 1, itupdesc, &null);
proc = metap->hashm_procid;
ScanKeyEntryInitialize(&skey[i],
@ -112,7 +113,8 @@ _hash_call(Relation rel, HashMetaPage metap, Datum key)
uint32
_hash_log2(uint32 num)
{
uint32 i, limit;
uint32 i,
limit;
limit = 1;
for (i = 0; limit < num; limit = limit << 1, i++)
@ -129,15 +131,16 @@ _hash_checkpage(Page page, int flags)
HashPageOpaque opaque;
Assert(page);
Assert(((PageHeader)(page))->pd_lower >= (sizeof(PageHeaderData) - sizeof(ItemIdData)));
Assert(((PageHeader) (page))->pd_lower >= (sizeof(PageHeaderData) - sizeof(ItemIdData)));
#if 1
Assert(((PageHeader)(page))->pd_upper <=
Assert(((PageHeader) (page))->pd_upper <=
(BLCKSZ - DOUBLEALIGN(sizeof(HashPageOpaqueData))));
Assert(((PageHeader)(page))->pd_special ==
Assert(((PageHeader) (page))->pd_special ==
(BLCKSZ - DOUBLEALIGN(sizeof(HashPageOpaqueData))));
Assert(((PageHeader)(page))->pd_opaque.od_pagesize == BLCKSZ);
Assert(((PageHeader) (page))->pd_opaque.od_pagesize == BLCKSZ);
#endif
if (flags) {
if (flags)
{
opaque = (HashPageOpaque) PageGetSpecialPointer(page);
Assert(opaque->hasho_flag & flags);
}

View File

@ -7,7 +7,7 @@
*
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/access/heap/heapam.c,v 1.15 1997/08/27 09:00:20 vadim Exp $
* $Header: /cvsroot/pgsql/src/backend/access/heap/heapam.c,v 1.16 1997/09/07 04:38:09 momjian Exp $
*
*
* INTERFACE ROUTINES
@ -91,9 +91,9 @@
#ifndef HAVE_MEMMOVE
# include <regex/utils.h>
#include <regex/utils.h>
#else
# include <string.h>
#include <string.h>
#endif
static bool ImmediateInvalidation;
@ -114,14 +114,17 @@ initsdesc(HeapScanDesc sdesc,
unsigned nkeys,
ScanKey key)
{
if (!RelationGetNumberOfBlocks(relation)) {
if (!RelationGetNumberOfBlocks(relation))
{
/* ----------------
* relation is empty
* ----------------
*/
sdesc->rs_ntup = sdesc->rs_ctup = sdesc->rs_ptup = NULL;
sdesc->rs_nbuf = sdesc->rs_cbuf = sdesc->rs_pbuf = InvalidBuffer;
} else if (atend) {
}
else if (atend)
{
/* ----------------
* reverse scan
* ----------------
@ -130,7 +133,9 @@ initsdesc(HeapScanDesc sdesc,
sdesc->rs_nbuf = sdesc->rs_cbuf = InvalidBuffer;
sdesc->rs_ptup = NULL;
sdesc->rs_pbuf = UnknownBuffer;
} else {
}
else
{
/* ----------------
* forward scan
* ----------------
@ -162,7 +167,8 @@ initsdesc(HeapScanDesc sdesc,
static void
unpinsdesc(HeapScanDesc sdesc)
{
if (BufferIsValid(sdesc->rs_pbuf)) {
if (BufferIsValid(sdesc->rs_pbuf))
{
ReleaseBuffer(sdesc->rs_pbuf);
}
@ -172,11 +178,13 @@ unpinsdesc(HeapScanDesc sdesc)
* times.
* ------------------------------------
*/
if (BufferIsValid(sdesc->rs_cbuf)) {
if (BufferIsValid(sdesc->rs_cbuf))
{
ReleaseBuffer(sdesc->rs_cbuf);
}
if (BufferIsValid(sdesc->rs_nbuf)) {
if (BufferIsValid(sdesc->rs_nbuf))
{
ReleaseBuffer(sdesc->rs_nbuf);
}
}
@ -192,7 +200,7 @@ unpinsdesc(HeapScanDesc sdesc)
static int
nextpage(int page, int dir)
{
return((dir<0)?page-1:page+1);
return ((dir < 0) ? page - 1 : page + 1);
}
/* ----------------
@ -206,7 +214,7 @@ static HeapTuple
heapgettup(Relation relation,
ItemPointer tid,
int dir,
Buffer *b,
Buffer * b,
TimeQual timeQual,
int nkeys,
ScanKey key)
@ -235,27 +243,34 @@ heapgettup(Relation relation,
* ----------------
*/
#ifdef HEAPDEBUGALL
if (ItemPointerIsValid(tid)) {
if (ItemPointerIsValid(tid))
{
elog(DEBUG, "heapgettup(%.16s, tid=0x%x[%d,%d], dir=%d, ...)",
RelationGetRelationName(relation), tid, tid->ip_blkid,
tid->ip_posid, dir);
} else {
}
else
{
elog(DEBUG, "heapgettup(%.16s, tid=0x%x, dir=%d, ...)",
RelationGetRelationName(relation), tid, dir);
}
elog(DEBUG, "heapgettup(..., b=0x%x, timeQ=0x%x, nkeys=%d, key=0x%x",
b, timeQual, nkeys, key);
if (timeQual == SelfTimeQual) {
if (timeQual == SelfTimeQual)
{
elog(DEBUG, "heapgettup: relation(%c)=`%.16s', SelfTimeQual",
relation->rd_rel->relkind, &relation->rd_rel->relname);
} else {
}
else
{
elog(DEBUG, "heapgettup: relation(%c)=`%.16s', timeQual=%d",
relation->rd_rel->relkind, &relation->rd_rel->relname,
timeQual);
}
#endif /* !defined(HEAPDEBUGALL) */
if (!ItemPointerIsValid(tid)) {
if (!ItemPointerIsValid(tid))
{
Assert(!PointerIsValid(tid));
}
@ -270,13 +285,15 @@ heapgettup(Relation relation,
* calculate next starting lineoff, given scan direction
* ----------------
*/
if (!dir) {
if (!dir)
{
/* ----------------
* ``no movement'' scan direction
* ----------------
*/
/* assume it is a valid TID XXX */
if (ItemPointerIsValid(tid) == false) {
if (ItemPointerIsValid(tid) == false)
{
*b = InvalidBuffer;
return (NULL);
}
@ -285,7 +302,8 @@ heapgettup(Relation relation,
*b);
#ifndef NO_BUFFERISVALID
if (!BufferIsValid(*b)) {
if (!BufferIsValid(*b))
{
elog(WARN, "heapgettup: failed ReadBuffer");
}
#endif
@ -294,59 +312,76 @@ heapgettup(Relation relation,
lineoff = ItemPointerGetOffsetNumber(tid);
lpp = PageGetItemId(dp, lineoff);
rtup = (HeapTuple)PageGetItem((Page) dp, lpp);
rtup = (HeapTuple) PageGetItem((Page) dp, lpp);
return (rtup);
} else if (dir < 0) {
}
else if (dir < 0)
{
/* ----------------
* reverse scan direction
* ----------------
*/
if (ItemPointerIsValid(tid) == false) {
if (ItemPointerIsValid(tid) == false)
{
tid = NULL;
}
if (tid == NULL) {
if (tid == NULL)
{
page = pages - 1; /* final page */
} else {
}
else
{
page = ItemPointerGetBlockNumber(tid); /* current page */
}
if (page < 0) {
if (page < 0)
{
*b = InvalidBuffer;
return (NULL);
}
*b = RelationGetBufferWithBuffer(relation, page, *b);
#ifndef NO_BUFFERISVALID
if (!BufferIsValid(*b)) {
if (!BufferIsValid(*b))
{
elog(WARN, "heapgettup: failed ReadBuffer");
}
#endif
dp = (Page) BufferGetPage(*b);
lines = PageGetMaxOffsetNumber(dp);
if (tid == NULL) {
if (tid == NULL)
{
lineoff = lines; /* final offnum */
} else {
}
else
{
lineoff = /* previous offnum */
OffsetNumberPrev(ItemPointerGetOffsetNumber(tid));
}
/* page and lineoff now reference the physically previous tid */
} else {
}
else
{
/* ----------------
* forward scan direction
* ----------------
*/
if (ItemPointerIsValid(tid) == false) {
if (ItemPointerIsValid(tid) == false)
{
page = 0; /* first page */
lineoff = FirstOffsetNumber; /* first offnum */
} else {
}
else
{
page = ItemPointerGetBlockNumber(tid); /* current page */
lineoff = /* next offnum */
OffsetNumberNext(ItemPointerGetOffsetNumber(tid));
}
if (page >= pages) {
if (page >= pages)
{
*b = InvalidBuffer;
return (NULL);
}
@ -354,7 +389,8 @@ heapgettup(Relation relation,
*b = RelationGetBufferWithBuffer(relation, page, *b);
#ifndef NO_BUFFERISVALID
if (!BufferIsValid(*b)) {
if (!BufferIsValid(*b))
{
elog(WARN, "heapgettup: failed ReadBuffer");
}
#endif
@ -371,9 +407,12 @@ heapgettup(Relation relation,
* ----------------
*/
lpp = PageGetItemId(dp, lineoff);
if (dir < 0) {
if (dir < 0)
{
linesleft = lineoff - 1;
} else {
}
else
{
linesleft = lines - lineoff;
}
@ -382,20 +421,25 @@ heapgettup(Relation relation,
* run out of stuff to scan
* ----------------
*/
for (;;) {
while (linesleft >= 0) {
for (;;)
{
while (linesleft >= 0)
{
/* ----------------
* if current tuple qualifies, return it.
* ----------------
*/
if ((rtup = heap_tuple_satisfies(lpp, relation, *b, (PageHeader) dp,
timeQual, nkeys, key)) != NULL) {
timeQual, nkeys, key)) != NULL)
{
ItemPointer iptr = &(rtup->t_ctid);
if (ItemPointerGetBlockNumber(iptr) != page) {
if (ItemPointerGetBlockNumber(iptr) != page)
{
/*
* set block id to the correct page number
* --- this is a hack to support the virtual fragment
* concept
* set block id to the correct page number --- this is
* a hack to support the virtual fragment concept
*/
ItemPointerSetBlockNumber(iptr, page);
}
@ -407,10 +451,14 @@ heapgettup(Relation relation,
* ----------------
*/
--linesleft;
if (dir < 0) {
if (dir < 0)
{
--lpp; /* move back in this page's ItemId array */
} else {
++lpp; /* move forward in this page's ItemId array */
}
else
{
++lpp; /* move forward in this page's ItemId
* array */
}
}
@ -425,7 +473,8 @@ heapgettup(Relation relation,
* return NULL if we've exhausted all the pages..
* ----------------
*/
if (page < 0 || page >= pages) {
if (page < 0 || page >= pages)
{
if (BufferIsValid(*b))
ReleaseBuffer(*b);
*b = InvalidBuffer;
@ -435,16 +484,20 @@ heapgettup(Relation relation,
*b = ReleaseAndReadBuffer(*b, relation, page);
#ifndef NO_BUFFERISVALID
if (!BufferIsValid(*b)) {
if (!BufferIsValid(*b))
{
elog(WARN, "heapgettup: failed ReadBuffer");
}
#endif
dp = (Page) BufferGetPage(*b);
lines = lineoff = PageGetMaxOffsetNumber((Page) dp);
linesleft = lines - 1;
if (dir < 0) {
if (dir < 0)
{
lpp = PageGetItemId(dp, lineoff);
} else {
}
else
{
lpp = PageGetItemId(dp, FirstOffsetNumber);
}
}
@ -471,6 +524,7 @@ SetHeapAccessMethodImmediateInvalidation(bool on)
{
ImmediateInvalidation = on;
}
#endif
/* ----------------------------------------------------------------
@ -498,7 +552,8 @@ heap_open(Oid relationId)
r = (Relation) RelationIdGetRelation(relationId);
if (RelationIsValid(r) && r->rd_rel->relkind == RELKIND_INDEX) {
if (RelationIsValid(r) && r->rd_rel->relkind == RELKIND_INDEX)
{
elog(WARN, "%s is an index relation", r->rd_rel->relname.data);
}
@ -526,7 +581,8 @@ heap_openr(char *relationName)
r = RelationNameGetRelation(relationName);
if (RelationIsValid(r) && r->rd_rel->relkind == RELKIND_INDEX) {
if (RelationIsValid(r) && r->rd_rel->relkind == RELKIND_INDEX)
{
elog(WARN, "%s is an index relation", r->rd_rel->relname.data);
}
@ -588,7 +644,8 @@ heap_beginscan(Relation relation,
RelationSetLockForRead(relation);
/* XXX someday assert SelfTimeQual if relkind == RELKIND_UNCATALOGED */
if (relation->rd_rel->relkind == RELKIND_UNCATALOGED) {
if (relation->rd_rel->relkind == RELKIND_UNCATALOGED)
{
timeQual = SelfTimeQual;
}
@ -607,13 +664,18 @@ heap_beginscan(Relation relation,
relation->rd_nblocks = smgrnblocks(relation->rd_rel->relsmgr, relation);
sdesc->rs_rd = relation;
if (nkeys) {
if (nkeys)
{
/*
* we do this here instead of in initsdesc() because heap_rescan also
* calls initsdesc() and we don't want to allocate memory again
* we do this here instead of in initsdesc() because heap_rescan
* also calls initsdesc() and we don't want to allocate memory
* again
*/
sdesc->rs_key = (ScanKey) palloc(sizeof(ScanKeyData) * nkeys);
} else {
}
else
{
sdesc->rs_key = NULL;
}
@ -621,7 +683,7 @@ heap_beginscan(Relation relation,
sdesc->rs_atend = atend;
sdesc->rs_tr = timeQual;
sdesc->rs_nkeys = (short)nkeys;
sdesc->rs_nkeys = (short) nkeys;
return (sdesc);
}
@ -693,7 +755,7 @@ heap_endscan(HeapScanDesc sdesc)
* Non 2-phase read locks on catalog relations
* ----------------
*/
if ( IsSystemRelationName(RelationGetRelationName(sdesc->rs_rd)->data) )
if (IsSystemRelationName(RelationGetRelationName(sdesc->rs_rd)->data))
RelationUnsetLockForRead(sdesc->rs_rd);
@ -743,7 +805,7 @@ elog(DEBUG, "heap_getnext([%s,nkeys=%d],backw=%d,0x%x) called", \
HeapTuple
heap_getnext(HeapScanDesc scandesc,
int backw,
Buffer *b)
Buffer * b)
{
register HeapScanDesc sdesc = scandesc;
Buffer localb;
@ -768,12 +830,14 @@ heap_getnext(HeapScanDesc scandesc,
* initialize return buffer to InvalidBuffer
* ----------------
*/
if (! PointerIsValid(b)) b = &localb;
if (!PointerIsValid(b))
b = &localb;
(*b) = InvalidBuffer;
HEAPDEBUG_1; /* heap_getnext( info ) */
if (backw) {
if (backw)
{
/* ----------------
* handle reverse scan
* ----------------
@ -789,11 +853,11 @@ heap_getnext(HeapScanDesc scandesc,
}
/*
* Copy the "current" tuple/buffer
* to "next". Pin/unpin the buffers
* accordingly
* Copy the "current" tuple/buffer to "next". Pin/unpin the
* buffers accordingly
*/
if (sdesc->rs_nbuf != sdesc->rs_cbuf) {
if (sdesc->rs_nbuf != sdesc->rs_cbuf)
{
if (BufferIsValid(sdesc->rs_nbuf))
ReleaseBuffer(sdesc->rs_nbuf);
if (BufferIsValid(sdesc->rs_cbuf))
@ -802,8 +866,10 @@ heap_getnext(HeapScanDesc scandesc,
sdesc->rs_ntup = sdesc->rs_ctup;
sdesc->rs_nbuf = sdesc->rs_cbuf;
if (sdesc->rs_ptup != NULL) {
if (sdesc->rs_cbuf != sdesc->rs_pbuf) {
if (sdesc->rs_ptup != NULL)
{
if (sdesc->rs_cbuf != sdesc->rs_pbuf)
{
if (BufferIsValid(sdesc->rs_cbuf))
ReleaseBuffer(sdesc->rs_cbuf);
if (BufferIsValid(sdesc->rs_pbuf))
@ -811,18 +877,22 @@ heap_getnext(HeapScanDesc scandesc,
}
sdesc->rs_ctup = sdesc->rs_ptup;
sdesc->rs_cbuf = sdesc->rs_pbuf;
} else { /* NONTUP */
}
else
{ /* NONTUP */
ItemPointer iptr;
iptr = (sdesc->rs_ctup != NULL) ?
&(sdesc->rs_ctup->t_ctid) : (ItemPointer) NULL;
/* Don't release sdesc->rs_cbuf at this point, because
heapgettup doesn't increase PrivateRefCount if it
is already set. On a backward scan, both rs_ctup and rs_ntup
usually point to the same buffer page, so
PrivateRefCount[rs_cbuf] should be 2 (or more, if for instance
ctup is stored in a TupleTableSlot). - 01/09/94 */
/*
* Don't release sdesc->rs_cbuf at this point, because
* heapgettup doesn't increase PrivateRefCount if it is
* already set. On a backward scan, both rs_ctup and rs_ntup
* usually point to the same buffer page, so
* PrivateRefCount[rs_cbuf] should be 2 (or more, if for
* instance ctup is stored in a TupleTableSlot). - 01/09/94
*/
sdesc->rs_ctup = (HeapTuple)
heapgettup(sdesc->rs_rd,
@ -852,13 +922,16 @@ heap_getnext(HeapScanDesc scandesc,
sdesc->rs_ptup = NULL;
sdesc->rs_pbuf = UnknownBuffer;
} else {
}
else
{
/* ----------------
* handle forward scan
* ----------------
*/
if (sdesc->rs_ctup == sdesc->rs_ntup &&
BufferIsInvalid(sdesc->rs_nbuf)) {
BufferIsInvalid(sdesc->rs_nbuf))
{
if (BufferIsValid(sdesc->rs_pbuf))
ReleaseBuffer(sdesc->rs_pbuf);
HEAPDEBUG_3; /* heap_getnext returns NULL at end */
@ -866,11 +939,11 @@ heap_getnext(HeapScanDesc scandesc,
}
/*
* Copy the "current" tuple/buffer
* to "previous". Pin/unpin the buffers
* accordingly
* Copy the "current" tuple/buffer to "previous". Pin/unpin the
* buffers accordingly
*/
if (sdesc->rs_pbuf != sdesc->rs_cbuf) {
if (sdesc->rs_pbuf != sdesc->rs_cbuf)
{
if (BufferIsValid(sdesc->rs_pbuf))
ReleaseBuffer(sdesc->rs_pbuf);
if (BufferIsValid(sdesc->rs_cbuf))
@ -879,8 +952,10 @@ heap_getnext(HeapScanDesc scandesc,
sdesc->rs_ptup = sdesc->rs_ctup;
sdesc->rs_pbuf = sdesc->rs_cbuf;
if (sdesc->rs_ntup != NULL) {
if (sdesc->rs_cbuf != sdesc->rs_nbuf) {
if (sdesc->rs_ntup != NULL)
{
if (sdesc->rs_cbuf != sdesc->rs_nbuf)
{
if (BufferIsValid(sdesc->rs_cbuf))
ReleaseBuffer(sdesc->rs_cbuf);
if (BufferIsValid(sdesc->rs_nbuf))
@ -889,18 +964,22 @@ heap_getnext(HeapScanDesc scandesc,
sdesc->rs_ctup = sdesc->rs_ntup;
sdesc->rs_cbuf = sdesc->rs_nbuf;
HEAPDEBUG_5; /* heap_getnext next tuple was cached */
} else { /* NONTUP */
}
else
{ /* NONTUP */
ItemPointer iptr;
iptr = (sdesc->rs_ctup != NULL) ?
&sdesc->rs_ctup->t_ctid : (ItemPointer) NULL;
/* Don't release sdesc->rs_cbuf at this point, because
heapgettup doesn't increase PrivateRefCount if it
is already set. On a forward scan, both rs_ctup and rs_ptup
usually point to the same buffer page, so
PrivateRefCount[rs_cbuf] should be 2 (or more, if for instance
ctup is stored in a TupleTableSlot). - 01/09/93 */
/*
* Don't release sdesc->rs_cbuf at this point, because
* heapgettup doesn't increase PrivateRefCount if it is
* already set. On a forward scan, both rs_ctup and rs_ptup
* usually point to the same buffer page, so
* PrivateRefCount[rs_cbuf] should be 2 (or more, if for
* instance ctup is stored in a TupleTableSlot). - 01/09/93
*/
sdesc->rs_ctup = (HeapTuple)
heapgettup(sdesc->rs_rd,
@ -912,7 +991,8 @@ heap_getnext(HeapScanDesc scandesc,
sdesc->rs_key);
}
if (sdesc->rs_ctup == NULL && !BufferIsValid(sdesc->rs_cbuf)) {
if (sdesc->rs_ctup == NULL && !BufferIsValid(sdesc->rs_cbuf))
{
if (BufferIsValid(sdesc->rs_nbuf))
ReleaseBuffer(sdesc->rs_nbuf);
sdesc->rs_ntup = NULL;
@ -953,7 +1033,7 @@ HeapTuple
heap_fetch(Relation relation,
TimeQual timeQual,
ItemPointer tid,
Buffer *b)
Buffer * b)
{
ItemId lp;
Buffer buffer;
@ -970,8 +1050,8 @@ heap_fetch(Relation relation,
/*
* Note: This is collosally expensive - does two system calls per
* indexscan tuple fetch. Not good, and since we should be doing
* page level locking by the scanner anyway, it is commented out.
* indexscan tuple fetch. Not good, and since we should be doing page
* level locking by the scanner anyway, it is commented out.
*/
/* RelationSetLockForTupleRead(relation, tid); */
@ -985,9 +1065,10 @@ heap_fetch(Relation relation,
buffer = ReadBuffer(relation, ItemPointerGetBlockNumber(tid));
#ifndef NO_BUFFERISVALID
if (!BufferIsValid(buffer)) {
if (!BufferIsValid(buffer))
{
elog(WARN, "heap_fetch: %s relation: ReadBuffer(%lx) failed",
&relation->rd_rel->relname, (long)tid);
&relation->rd_rel->relname, (long) tid);
}
#endif
@ -1012,7 +1093,7 @@ heap_fetch(Relation relation,
*/
tuple = heap_tuple_satisfies(lp, relation, buffer, dp,
timeQual, 0,(ScanKey)NULL);
timeQual, 0, (ScanKey) NULL);
if (tuple == NULL)
{
@ -1027,9 +1108,12 @@ heap_fetch(Relation relation,
* ----------------
*/
if (PointerIsValid(b)) {
if (PointerIsValid(b))
{
*b = buffer;
} else {
}
else
{
tuple = heap_copytuple(tuple);
ReleaseBuffer(buffer);
}
@ -1078,7 +1162,8 @@ heap_insert(Relation relation, HeapTuple tup)
* another).
* ----------------
*/
if (!OidIsValid(tup->t_oid)) {
if (!OidIsValid(tup->t_oid))
{
tup->t_oid = newoid();
LastOidProcessed = tup->t_oid;
}
@ -1093,7 +1178,8 @@ heap_insert(Relation relation, HeapTuple tup)
doinsert(relation, tup);
if ( IsSystemRelationName(RelationGetRelationName(relation)->data)) {
if (IsSystemRelationName(RelationGetRelationName(relation)->data))
{
RelationUnsetLockForWrite(relation);
/* ----------------
@ -1102,10 +1188,10 @@ heap_insert(Relation relation, HeapTuple tup)
*/
SetRefreshWhenInvalidate(ImmediateInvalidation);
RelationInvalidateHeapTuple(relation, tup);
SetRefreshWhenInvalidate((bool)!ImmediateInvalidation);
SetRefreshWhenInvalidate((bool) ! ImmediateInvalidation);
}
return(tup->t_oid);
return (tup->t_oid);
}
/* ----------------
@ -1144,7 +1230,8 @@ heap_delete(Relation relation, ItemPointer tid)
b = ReadBuffer(relation, ItemPointerGetBlockNumber(tid));
#ifndef NO_BUFFERISVALID
if (!BufferIsValid(b)) { /* XXX L_SH better ??? */
if (!BufferIsValid(b))
{ /* XXX L_SH better ??? */
elog(WARN, "heap_delete: failed ReadBuffer");
}
#endif /* NO_BUFFERISVALID */
@ -1156,11 +1243,12 @@ heap_delete(Relation relation, ItemPointer tid)
* Just like test against non-functional updates we try to catch
* non-functional delete attempts. - vadim 05/05/97
*/
tp = (HeapTuple) PageGetItem((Page)dp, lp);
tp = (HeapTuple) PageGetItem((Page) dp, lp);
Assert(HeapTupleIsValid(tp));
if (TupleUpdatedByCurXactAndCmd(tp)) {
if (TupleUpdatedByCurXactAndCmd(tp))
{
elog(NOTICE, "Non-functional delete, tuple already deleted");
if ( IsSystemRelationName(RelationGetRelationName(relation)->data) )
if (IsSystemRelationName(RelationGetRelationName(relation)->data))
RelationUnsetLockForWrite(relation);
ReleaseBuffer(b);
return (1);
@ -1170,7 +1258,8 @@ heap_delete(Relation relation, ItemPointer tid)
* ----------------
*/
if (!(tp = heap_tuple_satisfies(lp, relation, b, dp,
NowTimeQual, 0, (ScanKey) NULL))) {
NowTimeQual, 0, (ScanKey) NULL)))
{
/* XXX call something else */
ReleaseBuffer(b);
@ -1198,13 +1287,13 @@ heap_delete(Relation relation, ItemPointer tid)
*/
SetRefreshWhenInvalidate(ImmediateInvalidation);
RelationInvalidateHeapTuple(relation, tp);
SetRefreshWhenInvalidate((bool)!ImmediateInvalidation);
SetRefreshWhenInvalidate((bool) ! ImmediateInvalidation);
WriteBuffer(b);
if ( IsSystemRelationName(RelationGetRelationName(relation)->data) )
if (IsSystemRelationName(RelationGetRelationName(relation)->data))
RelationUnsetLockForWrite(relation);
return(0);
return (0);
}
/* ----------------
@ -1251,7 +1340,8 @@ heap_replace(Relation relation, ItemPointer otid, HeapTuple tup)
buffer = ReadBuffer(relation, ItemPointerGetBlockNumber(otid));
#ifndef NO_BUFFERISVALID
if (!BufferIsValid(buffer)) {
if (!BufferIsValid(buffer))
{
/* XXX L_SH better ??? */
elog(WARN, "amreplace: failed ReadBuffer");
}
@ -1279,12 +1369,13 @@ heap_replace(Relation relation, ItemPointer otid, HeapTuple tup)
* -----------------
*/
if (TupleUpdatedByCurXactAndCmd(tp)) {
if (TupleUpdatedByCurXactAndCmd(tp))
{
elog(NOTICE, "Non-functional update, only first update is performed");
if ( IsSystemRelationName(RelationGetRelationName(relation)->data) )
if (IsSystemRelationName(RelationGetRelationName(relation)->data))
RelationUnsetLockForWrite(relation);
ReleaseBuffer(buffer);
return(1);
return (1);
}
/* ----------------
@ -1300,10 +1391,10 @@ heap_replace(Relation relation, ItemPointer otid, HeapTuple tup)
if (!heap_tuple_satisfies(lp,
relation,
buffer,
(PageHeader)dp,
(PageHeader) dp,
NowTimeQual,
0,
(ScanKey)NULL))
(ScanKey) NULL))
{
ReleaseBuffer(buffer);
elog(WARN, "heap_replace: (am)invalid otid");
@ -1322,9 +1413,12 @@ heap_replace(Relation relation, ItemPointer otid, HeapTuple tup)
* insert new item
* ----------------
*/
if ((unsigned)DOUBLEALIGN(tup->t_len) <= PageGetFreeSpace((Page) dp)) {
if ((unsigned) DOUBLEALIGN(tup->t_len) <= PageGetFreeSpace((Page) dp))
{
RelationPutHeapTuple(relation, BufferGetBlockNumber(buffer), tup);
} else {
}
else
{
/* ----------------
* new item won't fit on same page as old item, have to look
* for a new place to put it.
@ -1347,14 +1441,14 @@ heap_replace(Relation relation, ItemPointer otid, HeapTuple tup)
*/
SetRefreshWhenInvalidate(ImmediateInvalidation);
RelationInvalidateHeapTuple(relation, tp);
SetRefreshWhenInvalidate((bool)!ImmediateInvalidation);
SetRefreshWhenInvalidate((bool) ! ImmediateInvalidation);
WriteBuffer(buffer);
if ( IsSystemRelationName(RelationGetRelationName(relation)->data) )
if (IsSystemRelationName(RelationGetRelationName(relation)->data))
RelationUnsetLockForWrite(relation);
return(0);
return (0);
}
/* ----------------
@ -1386,23 +1480,26 @@ heap_markpos(HeapScanDesc sdesc)
/* Note: no locking manipulations needed */
if (sdesc->rs_ptup == NULL &&
BufferIsUnknown(sdesc->rs_pbuf)) { /* == NONTUP */
BufferIsUnknown(sdesc->rs_pbuf))
{ /* == NONTUP */
sdesc->rs_ptup = (HeapTuple)
heapgettup(sdesc->rs_rd,
(sdesc->rs_ctup == NULL) ?
(ItemPointer)NULL : &sdesc->rs_ctup->t_ctid,
(ItemPointer) NULL : &sdesc->rs_ctup->t_ctid,
-1,
&sdesc->rs_pbuf,
sdesc->rs_tr,
sdesc->rs_nkeys,
sdesc->rs_key);
} else if (sdesc->rs_ntup == NULL &&
BufferIsUnknown(sdesc->rs_nbuf)) { /* == NONTUP */
}
else if (sdesc->rs_ntup == NULL &&
BufferIsUnknown(sdesc->rs_nbuf))
{ /* == NONTUP */
sdesc->rs_ntup = (HeapTuple)
heapgettup(sdesc->rs_rd,
(sdesc->rs_ctup == NULL) ?
(ItemPointer)NULL : &sdesc->rs_ctup->t_ctid,
(ItemPointer) NULL : &sdesc->rs_ctup->t_ctid,
1,
&sdesc->rs_nbuf,
sdesc->rs_tr,
@ -1414,19 +1511,28 @@ heap_markpos(HeapScanDesc sdesc)
* Should not unpin the buffer pages. They may still be in use.
* ----------------
*/
if (sdesc->rs_ptup != NULL) {
if (sdesc->rs_ptup != NULL)
{
sdesc->rs_mptid = sdesc->rs_ptup->t_ctid;
} else {
}
else
{
ItemPointerSetInvalid(&sdesc->rs_mptid);
}
if (sdesc->rs_ctup != NULL) {
if (sdesc->rs_ctup != NULL)
{
sdesc->rs_mctid = sdesc->rs_ctup->t_ctid;
} else {
}
else
{
ItemPointerSetInvalid(&sdesc->rs_mctid);
}
if (sdesc->rs_ntup != NULL) {
if (sdesc->rs_ntup != NULL)
{
sdesc->rs_mntid = sdesc->rs_ntup->t_ctid;
} else {
}
else
{
ItemPointerSetInvalid(&sdesc->rs_mntid);
}
}
@ -1473,9 +1579,12 @@ heap_restrpos(HeapScanDesc sdesc)
sdesc->rs_cbuf = InvalidBuffer;
sdesc->rs_nbuf = InvalidBuffer;
if (!ItemPointerIsValid(&sdesc->rs_mptid)) {
if (!ItemPointerIsValid(&sdesc->rs_mptid))
{
sdesc->rs_ptup = NULL;
} else {
}
else
{
sdesc->rs_ptup = (HeapTuple)
heapgettup(sdesc->rs_rd,
&sdesc->rs_mptid,
@ -1486,9 +1595,12 @@ heap_restrpos(HeapScanDesc sdesc)
(ScanKey) NULL);
}
if (!ItemPointerIsValid(&sdesc->rs_mctid)) {
if (!ItemPointerIsValid(&sdesc->rs_mctid))
{
sdesc->rs_ctup = NULL;
} else {
}
else
{
sdesc->rs_ctup = (HeapTuple)
heapgettup(sdesc->rs_rd,
&sdesc->rs_mctid,
@ -1499,9 +1611,12 @@ heap_restrpos(HeapScanDesc sdesc)
(ScanKey) NULL);
}
if (!ItemPointerIsValid(&sdesc->rs_mntid)) {
if (!ItemPointerIsValid(&sdesc->rs_mntid))
{
sdesc->rs_ntup = NULL;
} else {
}
else
{
sdesc->rs_ntup = (HeapTuple)
heapgettup(sdesc->rs_rd,
&sdesc->rs_mntid,

View File

@ -7,7 +7,7 @@
*
*
* IDENTIFICATION
* $Id: hio.c,v 1.9 1996/11/05 09:53:02 scrappy Exp $
* $Id: hio.c,v 1.10 1997/09/07 04:38:11 momjian Exp $
*
*-------------------------------------------------------------------------
*/
@ -58,23 +58,24 @@ RelationPutHeapTuple(Relation relation,
buffer = ReadBuffer(relation, blockIndex);
#ifndef NO_BUFFERISVALID
if (!BufferIsValid(buffer)) {
if (!BufferIsValid(buffer))
{
elog(WARN, "RelationPutHeapTuple: no buffer for %ld in %s",
blockIndex, &relation->rd_rel->relname);
}
#endif
pageHeader = (Page)BufferGetPage(buffer);
len = (unsigned)DOUBLEALIGN(tuple->t_len); /* be conservative */
Assert((int)len <= PageGetFreeSpace(pageHeader));
pageHeader = (Page) BufferGetPage(buffer);
len = (unsigned) DOUBLEALIGN(tuple->t_len); /* be conservative */
Assert((int) len <= PageGetFreeSpace(pageHeader));
offnum = PageAddItem((Page)pageHeader, (Item)tuple,
offnum = PageAddItem((Page) pageHeader, (Item) tuple,
tuple->t_len, InvalidOffsetNumber, LP_USED);
itemId = PageGetItemId((Page)pageHeader, offnum);
item = PageGetItem((Page)pageHeader, itemId);
itemId = PageGetItemId((Page) pageHeader, offnum);
item = PageGetItem((Page) pageHeader, itemId);
ItemPointerSet(&((HeapTuple)item)->t_ctid, blockIndex, offnum);
ItemPointerSet(&((HeapTuple) item)->t_ctid, blockIndex, offnum);
WriteBuffer(buffer);
/* return an accurate tuple */
@ -119,9 +120,9 @@ RelationPutHeapTupleAtEnd(Relation relation, HeapTuple tuple)
Assert(HeapTupleIsValid(tuple));
/*
* XXX This does an lseek - VERY expensive - but at the moment it
* is the only way to accurately determine how many blocks are in
* a relation. A good optimization would be to get this to actually
* XXX This does an lseek - VERY expensive - but at the moment it is
* the only way to accurately determine how many blocks are in a
* relation. A good optimization would be to get this to actually
* work properly.
*/
@ -130,44 +131,44 @@ RelationPutHeapTupleAtEnd(Relation relation, HeapTuple tuple)
if (lastblock == 0)
{
buffer = ReadBuffer(relation, lastblock);
pageHeader = (Page)BufferGetPage(buffer);
pageHeader = (Page) BufferGetPage(buffer);
if (PageIsNew((PageHeader) pageHeader))
{
buffer = ReleaseAndReadBuffer(buffer, relation, P_NEW);
pageHeader = (Page)BufferGetPage(buffer);
pageHeader = (Page) BufferGetPage(buffer);
PageInit(pageHeader, BufferGetPageSize(buffer), 0);
}
}
else
buffer = ReadBuffer(relation, lastblock - 1);
pageHeader = (Page)BufferGetPage(buffer);
len = (unsigned)DOUBLEALIGN(tuple->t_len); /* be conservative */
pageHeader = (Page) BufferGetPage(buffer);
len = (unsigned) DOUBLEALIGN(tuple->t_len); /* be conservative */
/*
* Note that this is true if the above returned a bogus page, which
* it will do for a completely empty relation.
* Note that this is true if the above returned a bogus page, which it
* will do for a completely empty relation.
*/
if (len > PageGetFreeSpace(pageHeader))
{
buffer = ReleaseAndReadBuffer(buffer, relation, P_NEW);
pageHeader = (Page)BufferGetPage(buffer);
pageHeader = (Page) BufferGetPage(buffer);
PageInit(pageHeader, BufferGetPageSize(buffer), 0);
if (len > PageGetFreeSpace(pageHeader))
elog(WARN, "Tuple is too big: size %d", len);
}
offnum = PageAddItem((Page)pageHeader, (Item)tuple,
offnum = PageAddItem((Page) pageHeader, (Item) tuple,
tuple->t_len, InvalidOffsetNumber, LP_USED);
itemId = PageGetItemId((Page)pageHeader, offnum);
item = PageGetItem((Page)pageHeader, itemId);
itemId = PageGetItemId((Page) pageHeader, offnum);
item = PageGetItem((Page) pageHeader, itemId);
lastblock = BufferGetBlockNumber(buffer);
ItemPointerSet(&((HeapTuple)item)->t_ctid, lastblock, offnum);
ItemPointerSet(&((HeapTuple) item)->t_ctid, lastblock, offnum);
/* return an accurate tuple */
ItemPointerSet(&tuple->t_ctid, lastblock, offnum);

View File

@ -7,7 +7,7 @@
*
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/access/heap/Attic/stats.c,v 1.11 1997/08/19 21:29:21 momjian Exp $
* $Header: /cvsroot/pgsql/src/backend/access/heap/Attic/stats.c,v 1.12 1997/09/07 04:38:13 momjian Exp $
*
* NOTES
* initam should be moved someplace else.
@ -23,9 +23,9 @@
#include <utils/mcxt.h>
#ifndef HAVE_MEMMOVE
# include <regex/utils.h>
#include <regex/utils.h>
#else
# include <string.h>
#include <string.h>
#endif
static void InitHeapAccessStatistics(void);
@ -174,6 +174,7 @@ ResetHeapAccessStatistics()
time(&stats->local_reset_timestamp);
time(&stats->last_request_timestamp);
}
#endif
#ifdef NOT_USED
@ -181,7 +182,8 @@ ResetHeapAccessStatistics()
* GetHeapAccessStatistics
* ----------------
*/
HeapAccessStatistics GetHeapAccessStatistics()
HeapAccessStatistics
GetHeapAccessStatistics()
{
HeapAccessStatistics stats;
@ -211,6 +213,7 @@ HeapAccessStatistics GetHeapAccessStatistics()
return stats;
}
#endif
#ifdef NOT_USED
@ -309,6 +312,7 @@ PrintHeapAccessStatistics(HeapAccessStatistics stats)
printf("\n");
}
#endif
#ifdef NOT_USED
@ -323,6 +327,7 @@ PrintAndFreeHeapAccessStatistics(HeapAccessStatistics stats)
if (stats != NULL)
pfree(stats);
}
#endif
/* ----------------------------------------------------------------

View File

@ -7,7 +7,7 @@
*
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/access/index/genam.c,v 1.7 1997/08/19 21:29:26 momjian Exp $
* $Header: /cvsroot/pgsql/src/backend/access/index/genam.c,v 1.8 1997/09/07 04:38:17 momjian Exp $
*
* NOTES
* many of the old access method routines have been turned into
@ -51,9 +51,9 @@
#include <storage/bufmgr.h>
#ifndef HAVE_MEMMOVE
# include <regex/utils.h>
#include <regex/utils.h>
#else
# include <string.h>
#include <string.h>
#endif
/* ----------------------------------------------------------------
@ -100,7 +100,7 @@ RelationGetIndexScan(Relation relation,
{
IndexScanDesc scan;
if (! RelationIsValid(relation))
if (!RelationIsValid(relation))
elog(WARN, "RelationGetIndexScan: relation invalid");
scan = (IndexScanDesc) palloc(sizeof(IndexScanDescData));
@ -116,9 +116,12 @@ RelationGetIndexScan(Relation relation,
ItemPointerSetInvalid(&scan->currentMarkData);
ItemPointerSetInvalid(&scan->nextMarkData);
if (numberOfKeys > 0) {
if (numberOfKeys > 0)
{
scan->keyData = (ScanKey) palloc(sizeof(ScanKeyData) * numberOfKeys);
} else {
}
else
{
scan->keyData = NULL;
}
@ -146,7 +149,7 @@ IndexScanRestart(IndexScanDesc scan,
bool scanFromEnd,
ScanKey key)
{
if (! IndexScanIsValid(scan))
if (!IndexScanIsValid(scan))
elog(WARN, "IndexScanRestart: invalid scan");
ItemPointerSetInvalid(&scan->previousItemData);
@ -167,6 +170,7 @@ IndexScanRestart(IndexScanDesc scan,
key,
scan->numberOfKeys * sizeof(ScanKeyData));
}
#endif
#ifdef NOT_USED
@ -186,11 +190,12 @@ IndexScanRestart(IndexScanDesc scan,
void
IndexScanEnd(IndexScanDesc scan)
{
if (! IndexScanIsValid(scan))
if (!IndexScanIsValid(scan))
elog(WARN, "IndexScanEnd: invalid scan");
pfree(scan);
}
#endif
/* ----------------
@ -213,23 +218,32 @@ IndexScanMarkPosition(IndexScanDesc scan)
{
RetrieveIndexResult result;
if (scan->flags & ScanUncheckedPrevious) {
if (scan->flags & ScanUncheckedPrevious)
{
result =
index_getnext(scan, BackwardScanDirection);
if (result != NULL) {
if (result != NULL)
{
scan->previousItemData = result->index_iptr;
} else {
}
else
{
ItemPointerSetInvalid(&scan->previousItemData);
}
} else if (scan->flags & ScanUncheckedNext) {
}
else if (scan->flags & ScanUncheckedNext)
{
result = (RetrieveIndexResult)
index_getnext(scan, ForwardScanDirection);
if (result != NULL) {
if (result != NULL)
{
scan->nextItemData = result->index_iptr;
} else {
}
else
{
ItemPointerSetInvalid(&scan->nextItemData);
}
}

View File

@ -7,7 +7,7 @@
*
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/access/index/indexam.c,v 1.13 1997/08/26 23:31:28 momjian Exp $
* $Header: /cvsroot/pgsql/src/backend/access/index/indexam.c,v 1.14 1997/09/07 04:38:26 momjian Exp $
*
* INTERFACE ROUTINES
* index_open - open an index relation by relationId
@ -162,7 +162,7 @@ index_close(Relation relation)
*/
InsertIndexResult
index_insert(Relation relation,
Datum *datum,
Datum * datum,
char *nulls,
ItemPointer heap_t_ctid,
Relation heapRel)
@ -171,7 +171,7 @@ index_insert(Relation relation,
InsertIndexResult specificResult;
RELATION_CHECKS;
GET_REL_PROCEDURE(insert,aminsert);
GET_REL_PROCEDURE(insert, aminsert);
/* ----------------
* have the am's insert proc do all the work.
@ -210,7 +210,7 @@ index_delete(Relation relation, ItemPointer indexItem)
RegProcedure procedure;
RELATION_CHECKS;
GET_REL_PROCEDURE(delete,amdelete);
GET_REL_PROCEDURE(delete, amdelete);
fmgr(procedure, relation, indexItem);
}
@ -229,7 +229,7 @@ index_beginscan(Relation relation,
RegProcedure procedure;
RELATION_CHECKS;
GET_REL_PROCEDURE(beginscan,ambeginscan);
GET_REL_PROCEDURE(beginscan, ambeginscan);
RelationSetRIntentLock(relation);
@ -249,7 +249,7 @@ index_rescan(IndexScanDesc scan, bool scanFromEnd, ScanKey key)
RegProcedure procedure;
SCAN_CHECKS;
GET_SCAN_PROCEDURE(rescan,amrescan);
GET_SCAN_PROCEDURE(rescan, amrescan);
fmgr(procedure, scan, scanFromEnd, key);
}
@ -264,7 +264,7 @@ index_endscan(IndexScanDesc scan)
RegProcedure procedure;
SCAN_CHECKS;
GET_SCAN_PROCEDURE(endscan,amendscan);
GET_SCAN_PROCEDURE(endscan, amendscan);
fmgr(procedure, scan);
@ -282,10 +282,11 @@ index_markpos(IndexScanDesc scan)
RegProcedure procedure;
SCAN_CHECKS;
GET_SCAN_PROCEDURE(markpos,ammarkpos);
GET_SCAN_PROCEDURE(markpos, ammarkpos);
fmgr(procedure, scan);
}
#endif
#ifdef NOT_USED
@ -299,10 +300,11 @@ index_restrpos(IndexScanDesc scan)
RegProcedure procedure;
SCAN_CHECKS;
GET_SCAN_PROCEDURE(restrpos,amrestrpos);
GET_SCAN_PROCEDURE(restrpos, amrestrpos);
fmgr(procedure, scan);
}
#endif
/* ----------------
@ -319,7 +321,7 @@ index_getnext(IndexScanDesc scan,
RetrieveIndexResult result;
SCAN_CHECKS;
GET_SCAN_PROCEDURE(getnext,amgettuple);
GET_SCAN_PROCEDURE(getnext, amgettuple);
/* ----------------
* have the am's gettuple proc do all the work.
@ -369,31 +371,35 @@ GetIndexValue(HeapTuple tuple,
TupleDesc hTupDesc,
int attOff,
AttrNumber attrNums[],
FuncIndexInfo *fInfo,
bool *attNull,
FuncIndexInfo * fInfo,
bool * attNull,
Buffer buffer)
{
Datum returnVal;
bool isNull;
if (PointerIsValid(fInfo) && FIgetProcOid(fInfo) != InvalidOid) {
if (PointerIsValid(fInfo) && FIgetProcOid(fInfo) != InvalidOid)
{
int i;
Datum *attData = (Datum *)palloc(FIgetnArgs(fInfo)*sizeof(Datum));
Datum *attData = (Datum *) palloc(FIgetnArgs(fInfo) * sizeof(Datum));
for (i = 0; i < FIgetnArgs(fInfo); i++) {
for (i = 0; i < FIgetnArgs(fInfo); i++)
{
attData[i] = (Datum) heap_getattr(tuple,
buffer,
attrNums[i],
hTupDesc,
attNull);
}
returnVal = (Datum)fmgr_array_args(FIgetProcOid(fInfo),
returnVal = (Datum) fmgr_array_args(FIgetProcOid(fInfo),
FIgetnArgs(fInfo),
(char **) attData,
&isNull);
pfree(attData);
*attNull = FALSE;
}else {
}
else
{
returnVal = (Datum) heap_getattr(tuple, buffer, attrNums[attOff],
hTupDesc, attNull);
}

View File

@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/access/index/Attic/istrat.c,v 1.9 1997/08/22 16:48:14 momjian Exp $
* $Header: /cvsroot/pgsql/src/backend/access/index/Attic/istrat.c,v 1.10 1997/09/07 04:38:32 momjian Exp $
*
*-------------------------------------------------------------------------
*/
@ -28,14 +28,19 @@
#ifndef NO_ASSERT_CHECKING
static bool StrategyEvaluationIsValid(StrategyEvaluation evaluation);
static bool StrategyExpressionIsValid(StrategyExpression expression,
static bool
StrategyExpressionIsValid(StrategyExpression expression,
StrategyNumber maxStrategy);
static ScanKey StrategyMapGetScanKeyEntry(StrategyMap map,
static ScanKey
StrategyMapGetScanKeyEntry(StrategyMap map,
StrategyNumber strategyNumber);
static bool StrategyOperatorIsValid(StrategyOperator operator,
static bool
StrategyOperatorIsValid(StrategyOperator operator,
StrategyNumber maxStrategy);
static bool StrategyTermIsValid(StrategyTerm term,
static bool
StrategyTermIsValid(StrategyTerm term,
StrategyNumber maxStrategy);
#endif
@ -105,7 +110,7 @@ AttributeNumberGetIndexStrategySize(AttrNumber maxAttributeNumber,
{
maxStrategyNumber = AMStrategies(maxStrategyNumber); /* XXX */
return
maxAttributeNumber * maxStrategyNumber * sizeof (ScanKeyData);
maxAttributeNumber * maxStrategyNumber * sizeof(ScanKeyData);
}
#ifndef NO_ASSERT_CHECKING
@ -137,12 +142,14 @@ StrategyTermIsValid(StrategyTerm term,
{
Index index;
if (! PointerIsValid(term) || term->degree == 0)
if (!PointerIsValid(term) || term->degree == 0)
return false;
for (index = 0; index < term->degree; index += 1) {
if (! StrategyOperatorIsValid(&term->operatorData[index],
maxStrategy)) {
for (index = 0; index < term->degree; index += 1)
{
if (!StrategyOperatorIsValid(&term->operatorData[index],
maxStrategy))
{
return false;
}
@ -172,7 +179,7 @@ StrategyExpressionIsValid(StrategyExpression expression,
termP += 1;
return (bool)
(! PointerIsValid(*termP));
(!PointerIsValid(*termP));
}
/* ----------------
@ -184,24 +191,28 @@ StrategyEvaluationIsValid(StrategyEvaluation evaluation)
{
Index index;
if (! PointerIsValid(evaluation) ||
! StrategyNumberIsValid(evaluation->maxStrategy) ||
! StrategyTransformMapIsValid(evaluation->negateTransform) ||
! StrategyTransformMapIsValid(evaluation->commuteTransform) ||
! StrategyTransformMapIsValid(evaluation->negateCommuteTransform)) {
if (!PointerIsValid(evaluation) ||
!StrategyNumberIsValid(evaluation->maxStrategy) ||
!StrategyTransformMapIsValid(evaluation->negateTransform) ||
!StrategyTransformMapIsValid(evaluation->commuteTransform) ||
!StrategyTransformMapIsValid(evaluation->negateCommuteTransform))
{
return false;
}
for (index = 0; index < evaluation->maxStrategy; index += 1) {
if (! StrategyExpressionIsValid(evaluation->expression[index],
evaluation->maxStrategy)) {
for (index = 0; index < evaluation->maxStrategy; index += 1)
{
if (!StrategyExpressionIsValid(evaluation->expression[index],
evaluation->maxStrategy))
{
return false;
}
}
return true;
}
#endif
/* ----------------
@ -221,13 +232,15 @@ StrategyTermEvaluate(StrategyTerm term,
ScanKey entry;
for (index = 0, operator = &term->operatorData[0];
index < term->degree; index += 1, operator += 1) {
index < term->degree; index += 1, operator += 1)
{
entry = &map->entry[operator->strategy - 1];
Assert(RegProcedureIsValid(entry->sk_procedure));
switch (operator->flags ^ entry->sk_flags) {
switch (operator->flags ^ entry->sk_flags)
{
case 0x0:
tmpres = (long) FMGR_PTR2(entry->sk_func, entry->sk_procedure,
left, right);
@ -283,7 +296,7 @@ RelationGetStrategy(Relation relation,
Assert(relation->rd_rel->relkind == RELKIND_INDEX); /* XXX use accessor */
Assert(AttributeNumberIsValid(attributeNumber));
Assert( (attributeNumber >= 1) && (attributeNumber < 1 + numattrs));
Assert((attributeNumber >= 1) && (attributeNumber < 1 + numattrs));
Assert(StrategyEvaluationIsValid(evaluation));
Assert(RegProcedureIsValid(procedure));
@ -294,8 +307,10 @@ RelationGetStrategy(Relation relation,
attributeNumber);
/* get a strategy number for the procedure ignoring flags for now */
for (index = 0; index < evaluation->maxStrategy; index += 1) {
if (strategyMap->entry[index].sk_procedure == procedure) {
for (index = 0; index < evaluation->maxStrategy; index += 1)
{
if (strategyMap->entry[index].sk_procedure == procedure)
{
break;
}
}
@ -308,7 +323,8 @@ RelationGetStrategy(Relation relation,
Assert(!(entry->sk_flags & ~(SK_NEGATE | SK_COMMUTE)));
switch (entry->sk_flags & (SK_NEGATE | SK_COMMUTE)) {
switch (entry->sk_flags & (SK_NEGATE | SK_COMMUTE))
{
case 0x0:
return strategy;
@ -329,8 +345,10 @@ RelationGetStrategy(Relation relation,
}
if (! StrategyNumberIsInBounds(strategy, evaluation->maxStrategy)) {
if (! StrategyNumberIsValid(strategy)) {
if (!StrategyNumberIsInBounds(strategy, evaluation->maxStrategy))
{
if (!StrategyNumberIsValid(strategy))
{
elog(WARN, "RelationGetStrategy: corrupted evaluation");
}
}
@ -362,7 +380,7 @@ RelationInvokeStrategy(Relation relation,
Assert(StrategyEvaluationIsValid(evaluation));
Assert(AttributeNumberIsValid(attributeNumber));
Assert( (attributeNumber >= 1) && (attributeNumber < 1 + numattrs));
Assert((attributeNumber >= 1) && (attributeNumber < 1 + numattrs));
Assert(StrategyNumberIsInBounds(strategy, evaluation->maxStrategy));
@ -375,7 +393,8 @@ RelationInvokeStrategy(Relation relation,
entry = StrategyMapGetScanKeyEntry(strategyMap, strategy);
if (RegProcedureIsValid(entry->sk_procedure)) {
if (RegProcedureIsValid(entry->sk_procedure))
{
termData.operatorData[0].strategy = strategy;
termData.operatorData[0].flags = 0x0;
@ -385,11 +404,13 @@ RelationInvokeStrategy(Relation relation,
newStrategy = evaluation->negateTransform->strategy[strategy - 1];
if (newStrategy != strategy && StrategyNumberIsValid(newStrategy)) {
if (newStrategy != strategy && StrategyNumberIsValid(newStrategy))
{
entry = StrategyMapGetScanKeyEntry(strategyMap, newStrategy);
if (RegProcedureIsValid(entry->sk_procedure)) {
if (RegProcedureIsValid(entry->sk_procedure))
{
termData.operatorData[0].strategy = newStrategy;
termData.operatorData[0].flags = SK_NEGATE;
@ -399,11 +420,13 @@ RelationInvokeStrategy(Relation relation,
}
newStrategy = evaluation->commuteTransform->strategy[strategy - 1];
if (newStrategy != strategy && StrategyNumberIsValid(newStrategy)) {
if (newStrategy != strategy && StrategyNumberIsValid(newStrategy))
{
entry = StrategyMapGetScanKeyEntry(strategyMap, newStrategy);
if (RegProcedureIsValid(entry->sk_procedure)) {
if (RegProcedureIsValid(entry->sk_procedure))
{
termData.operatorData[0].strategy = newStrategy;
termData.operatorData[0].flags = SK_COMMUTE;
@ -413,11 +436,13 @@ RelationInvokeStrategy(Relation relation,
}
newStrategy = evaluation->negateCommuteTransform->strategy[strategy - 1];
if (newStrategy != strategy && StrategyNumberIsValid(newStrategy)) {
if (newStrategy != strategy && StrategyNumberIsValid(newStrategy))
{
entry = StrategyMapGetScanKeyEntry(strategyMap, newStrategy);
if (RegProcedureIsValid(entry->sk_procedure)) {
if (RegProcedureIsValid(entry->sk_procedure))
{
termData.operatorData[0].strategy = newStrategy;
termData.operatorData[0].flags = SK_NEGATE | SK_COMMUTE;
@ -426,23 +451,28 @@ RelationInvokeStrategy(Relation relation,
}
}
if (PointerIsValid(evaluation->expression[strategy - 1])) {
if (PointerIsValid(evaluation->expression[strategy - 1]))
{
StrategyTerm *termP;
termP = &evaluation->expression[strategy - 1]->term[0];
while (PointerIsValid(*termP)) {
while (PointerIsValid(*termP))
{
Index index;
for (index = 0; index < (*termP)->degree; index += 1) {
for (index = 0; index < (*termP)->degree; index += 1)
{
entry = StrategyMapGetScanKeyEntry(strategyMap,
(*termP)->operatorData[index].strategy);
if (! RegProcedureIsValid(entry->sk_procedure)) {
if (!RegProcedureIsValid(entry->sk_procedure))
{
break;
}
}
if (index == (*termP)->degree) {
if (index == (*termP)->degree)
{
return
StrategyTermEvaluate(*termP, strategyMap, left, right);
}
@ -481,8 +511,9 @@ OperatorRelationFillScanKeyEntry(Relation operatorRelation,
scan = heap_beginscan(operatorRelation, false, NowTimeQual,
1, &scanKeyData);
tuple = heap_getnext(scan, false, (Buffer *)NULL);
if (! HeapTupleIsValid(tuple)) {
tuple = heap_getnext(scan, false, (Buffer *) NULL);
if (!HeapTupleIsValid(tuple))
{
elog(WARN, "OperatorObjectIdFillScanKeyEntry: unknown operator %lu",
(uint32) operatorObjectId);
}
@ -492,7 +523,8 @@ OperatorRelationFillScanKeyEntry(Relation operatorRelation,
((OperatorTupleForm) GETSTRUCT(tuple))->oprcode;
fmgr_info(entry->sk_procedure, &entry->sk_func, &entry->sk_nargs);
if (! RegProcedureIsValid(entry->sk_procedure)) {
if (!RegProcedureIsValid(entry->sk_procedure))
{
elog(WARN,
"OperatorObjectIdFillScanKeyEntry: no procedure for operator %lu",
(uint32) operatorObjectId);
@ -508,7 +540,7 @@ OperatorRelationFillScanKeyEntry(Relation operatorRelation,
*/
void
IndexSupportInitialize(IndexStrategy indexStrategy,
RegProcedure *indexSupport,
RegProcedure * indexSupport,
Oid indexObjectId,
Oid accessMethodObjectId,
StrategyNumber maxStrategyNumber,
@ -523,7 +555,7 @@ IndexSupportInitialize(IndexStrategy indexStrategy,
StrategyMap map;
AttrNumber attributeNumber;
int attributeIndex;
Oid operatorClassObjectId[ MaxIndexAttributeNumber ];
Oid operatorClassObjectId[MaxIndexAttributeNumber];
maxStrategyNumber = AMStrategies(maxStrategyNumber);
@ -533,22 +565,24 @@ IndexSupportInitialize(IndexStrategy indexStrategy,
relation = heap_openr(IndexRelationName);
scan = heap_beginscan(relation, false, NowTimeQual, 1, entry);
tuple = heap_getnext(scan, 0, (Buffer *)NULL);
if (! HeapTupleIsValid(tuple))
tuple = heap_getnext(scan, 0, (Buffer *) NULL);
if (!HeapTupleIsValid(tuple))
elog(WARN, "IndexSupportInitialize: corrupted catalogs");
/*
* XXX note that the following assumes the INDEX tuple is well formed and
* that the key[] and class[] are 0 terminated.
* XXX note that the following assumes the INDEX tuple is well formed
* and that the key[] and class[] are 0 terminated.
*/
for (attributeIndex=0; attributeIndex<maxAttributeNumber; attributeIndex++)
for (attributeIndex = 0; attributeIndex < maxAttributeNumber; attributeIndex++)
{
IndexTupleForm iform;
iform = (IndexTupleForm) GETSTRUCT(tuple);
if (!OidIsValid(iform->indkey[attributeIndex])) {
if (attributeIndex == 0) {
if (!OidIsValid(iform->indkey[attributeIndex]))
{
if (attributeIndex == 0)
{
elog(WARN, "IndexSupportInitialize: no pg_index tuple");
}
break;
@ -562,7 +596,8 @@ IndexSupportInitialize(IndexStrategy indexStrategy,
heap_close(relation);
/* if support routines exist for this access method, load them */
if (maxSupportNumber > 0) {
if (maxSupportNumber > 0)
{
ScanKeyEntryInitialize(&entry[0], 0, Anum_pg_amproc_amid,
ObjectIdEqualRegProcedure,
@ -576,7 +611,8 @@ IndexSupportInitialize(IndexStrategy indexStrategy,
for (attributeNumber = maxAttributeNumber; attributeNumber > 0;
attributeNumber--) {
attributeNumber--)
{
int16 support;
Form_pg_amproc form;
@ -584,7 +620,8 @@ IndexSupportInitialize(IndexStrategy indexStrategy,
loc = &indexSupport[((attributeNumber - 1) * maxSupportNumber)];
for (support = maxSupportNumber; --support >= 0; ) {
for (support = maxSupportNumber; --support >= 0;)
{
loc[support] = InvalidOid;
}
@ -593,8 +630,9 @@ IndexSupportInitialize(IndexStrategy indexStrategy,
scan = heap_beginscan(relation, false, NowTimeQual, 2, entry);
while (tuple = heap_getnext(scan, 0, (Buffer *)NULL),
HeapTupleIsValid(tuple)) {
while (tuple = heap_getnext(scan, 0, (Buffer *) NULL),
HeapTupleIsValid(tuple))
{
form = (Form_pg_amproc) GETSTRUCT(tuple);
loc[(form->amprocnum - 1)] = form->amproc;
@ -618,7 +656,8 @@ IndexSupportInitialize(IndexStrategy indexStrategy,
operatorRelation = heap_openr(OperatorRelationName);
for (attributeNumber = maxAttributeNumber; attributeNumber > 0;
attributeNumber--) {
attributeNumber--)
{
StrategyNumber strategy;
@ -634,8 +673,9 @@ IndexSupportInitialize(IndexStrategy indexStrategy,
scan = heap_beginscan(relation, false, NowTimeQual, 2, entry);
while (tuple = heap_getnext(scan, 0, (Buffer *)NULL),
HeapTupleIsValid(tuple)) {
while (tuple = heap_getnext(scan, 0, (Buffer *) NULL),
HeapTupleIsValid(tuple))
{
Form_pg_amop form;
form = (Form_pg_amop) GETSTRUCT(tuple);
@ -667,7 +707,8 @@ IndexStrategyDisplay(IndexStrategy indexStrategy,
StrategyNumber strategyNumber;
for (attributeNumber = 1; attributeNumber <= numberOfAttributes;
attributeNumber += 1) {
attributeNumber += 1)
{
strategyMap = IndexStrategyGetStrategyMap(indexStrategy,
numberOfStrategies,
@ -675,7 +716,8 @@ IndexStrategyDisplay(IndexStrategy indexStrategy,
for (strategyNumber = 1;
strategyNumber <= AMStrategies(numberOfStrategies);
strategyNumber += 1) {
strategyNumber += 1)
{
printf(":att %d\t:str %d\t:opr 0x%x(%d)\n",
attributeNumber, strategyNumber,
@ -684,6 +726,5 @@ IndexStrategyDisplay(IndexStrategy indexStrategy,
}
}
}
#endif /* defined(ISTRATDEBUG) */

View File

@ -7,7 +7,7 @@
*
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/access/nbtree/nbtcompare.c,v 1.10 1997/06/11 05:20:05 vadim Exp $
* $Header: /cvsroot/pgsql/src/backend/access/nbtree/nbtcompare.c,v 1.11 1997/09/07 04:38:39 momjian Exp $
*
* NOTES
* These functions are stored in pg_amproc. For each operator class
@ -98,7 +98,7 @@ btabstimecmp(AbsoluteTime a, AbsoluteTime b)
int32
btcharcmp(char a, char b)
{
return ((int32) ((uint8)a - (uint8)b));
return ((int32) ((uint8) a - (uint8) b));
}
int32
@ -126,39 +126,40 @@ btchar16cmp(char *a, char *b)
}
int32
btnamecmp(NameData *a, NameData *b)
btnamecmp(NameData * a, NameData * b)
{
return (strncmp(a->data, b->data, NAMEDATALEN));
}
int32
bttextcmp(struct varlena *a, struct varlena *b)
bttextcmp(struct varlena * a, struct varlena * b)
{
int res;
unsigned char *ap, *bp;
unsigned char *ap,
*bp;
#ifdef USE_LOCALE
int la = VARSIZE(a) - VARHDRSZ;
int lb = VARSIZE(b) - VARHDRSZ;
ap = (unsigned char *) palloc (la + 1);
bp = (unsigned char *) palloc (lb + 1);
ap = (unsigned char *) palloc(la + 1);
bp = (unsigned char *) palloc(lb + 1);
memcpy(ap, VARDATA(a), la);
*(ap + la) = '\0';
memcpy(bp, VARDATA(b), lb);
*(bp + lb) = '\0';
res = strcoll (ap, bp);
res = strcoll(ap, bp);
pfree (ap);
pfree (bp);
pfree(ap);
pfree(bp);
#else
int len = VARSIZE(a);
/* len is the length of the shorter of the two strings */
if ( len > VARSIZE(b) )
if (len > VARSIZE(b))
len = VARSIZE(b);
len -= VARHDRSZ;
@ -167,14 +168,16 @@ bttextcmp(struct varlena *a, struct varlena *b)
bp = (unsigned char *) VARDATA(b);
/*
* If the two strings differ in the first len bytes, or if they're
* the same in the first len bytes and they're both len bytes long,
* we're done.
* If the two strings differ in the first len bytes, or if they're the
* same in the first len bytes and they're both len bytes long, we're
* done.
*/
res = 0;
if (len > 0) {
do {
if (len > 0)
{
do
{
res = (int) (*ap++ - *bp++);
len--;
} while (res == 0 && len != 0);
@ -186,8 +189,8 @@ bttextcmp(struct varlena *a, struct varlena *b)
return (res);
/*
* The two strings are the same in the first len bytes, and they
* are of different lengths.
* The two strings are the same in the first len bytes, and they are
* of different lengths.
*/
if (VARSIZE(a) < VARSIZE(b))

File diff suppressed because it is too large Load Diff

View File

@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/access/nbtree/nbtpage.c,v 1.9 1997/08/19 21:29:36 momjian Exp $
* $Header: /cvsroot/pgsql/src/backend/access/nbtree/nbtpage.c,v 1.10 1997/09/07 04:38:52 momjian Exp $
*
* NOTES
* Postgres btree pages look like ordinary relation pages. The opaque
@ -31,9 +31,9 @@
#include <storage/lmgr.h>
#ifndef HAVE_MEMMOVE
# include <regex/utils.h>
#include <regex/utils.h>
#else
# include <string.h>
#include <string.h>
#endif
static void _bt_setpagelock(Relation rel, BlockNumber blkno, int access);
@ -48,7 +48,8 @@ static void _bt_unsetpagelock(Relation rel, BlockNumber blkno, int access);
#define BTREE_VERSION 0
#endif
typedef struct BTMetaPageData {
typedef struct BTMetaPageData
{
uint32 btm_magic;
uint32 btm_version;
BlockNumber btm_root;
@ -94,7 +95,8 @@ _bt_metapinit(Relation rel)
if (USELOCKING)
RelationSetLockForWrite(rel);
if ((nblocks = RelationGetNumberOfBlocks(rel)) != 0) {
if ((nblocks = RelationGetNumberOfBlocks(rel)) != 0)
{
elog(WARN, "Cannot initialize non-empty btree %s",
RelationGetRelationName(rel));
}
@ -142,18 +144,21 @@ _bt_checkmeta(Relation rel)
metabuf = _bt_getbuf(rel, BTREE_METAPAGE, BT_READ);
metap = BufferGetPage(metabuf);
op = (BTPageOpaque) PageGetSpecialPointer(metap);
if (!(op->btpo_flags & BTP_META)) {
if (!(op->btpo_flags & BTP_META))
{
elog(WARN, "Invalid metapage for index %s",
RelationGetRelationName(rel));
}
metad = BTPageGetMeta(metap);
if (metad->btm_magic != BTREE_MAGIC) {
if (metad->btm_magic != BTREE_MAGIC)
{
elog(WARN, "Index %s is not a btree",
RelationGetRelationName(rel));
}
if (metad->btm_version != BTREE_VERSION) {
if (metad->btm_version != BTREE_VERSION)
{
elog(WARN, "Version mismatch on %s: version %d file, version %d code",
RelationGetRelationName(rel),
metad->btm_version, BTREE_VERSION);
@ -161,6 +166,7 @@ _bt_checkmeta(Relation rel)
_bt_relbuf(rel, metabuf, BT_READ);
}
#endif
/*
@ -196,19 +202,22 @@ _bt_getroot(Relation rel, int access)
Assert(metaopaque->btpo_flags & BTP_META);
metad = BTPageGetMeta(metapg);
if (metad->btm_magic != BTREE_MAGIC) {
if (metad->btm_magic != BTREE_MAGIC)
{
elog(WARN, "Index %s is not a btree",
RelationGetRelationName(rel));
}
if (metad->btm_version != BTREE_VERSION) {
if (metad->btm_version != BTREE_VERSION)
{
elog(WARN, "Version mismatch on %s: version %d file, version %d code",
RelationGetRelationName(rel),
metad->btm_version, BTREE_VERSION);
}
/* if no root page initialized yet, do it */
if (metad->btm_root == P_NONE) {
if (metad->btm_root == P_NONE)
{
/* turn our read lock in for a write lock */
_bt_relbuf(rel, metabuf, BT_READ);
@ -219,12 +228,13 @@ _bt_getroot(Relation rel, int access)
metad = BTPageGetMeta(metapg);
/*
* Race condition: if someone else initialized the metadata between
* the time we released the read lock and acquired the write lock,
* above, we want to avoid doing it again.
* Race condition: if someone else initialized the metadata
* between the time we released the read lock and acquired the
* write lock, above, we want to avoid doing it again.
*/
if (metad->btm_root == P_NONE) {
if (metad->btm_root == P_NONE)
{
/*
* Get, initialize, write, and leave a lock of the appropriate
@ -245,25 +255,30 @@ _bt_getroot(Relation rel, int access)
_bt_wrtnorelbuf(rel, rootbuf);
/* swap write lock for read lock, if appropriate */
if (access != BT_WRITE) {
if (access != BT_WRITE)
{
_bt_setpagelock(rel, rootblkno, BT_READ);
_bt_unsetpagelock(rel, rootblkno, BT_WRITE);
}
/* okay, metadata is correct */
_bt_wrtbuf(rel, metabuf);
} else {
}
else
{
/*
* Metadata initialized by someone else. In order to guarantee
* no deadlocks, we have to release the metadata page and start
* all over again.
* Metadata initialized by someone else. In order to
* guarantee no deadlocks, we have to release the metadata
* page and start all over again.
*/
_bt_relbuf(rel, metabuf, BT_WRITE);
return (_bt_getroot(rel, access));
}
} else {
}
else
{
rootbuf = _bt_getbuf(rel, metad->btm_root, access);
/* done with the meta page */
@ -278,7 +293,8 @@ _bt_getroot(Relation rel, int access)
rootpg = BufferGetPage(rootbuf);
rootopaque = (BTPageOpaque) PageGetSpecialPointer(rootpg);
if (!(rootopaque->btpo_flags & BTP_ROOT)) {
if (!(rootopaque->btpo_flags & BTP_ROOT))
{
/* it happened, try again */
_bt_relbuf(rel, rootbuf, access);
@ -311,14 +327,17 @@ _bt_getbuf(Relation rel, BlockNumber blkno, int access)
* until we've instantiated the buffer.
*/
if (blkno != P_NEW) {
if (blkno != P_NEW)
{
if (access == BT_WRITE)
_bt_setpagelock(rel, blkno, BT_WRITE);
else
_bt_setpagelock(rel, blkno, BT_READ);
buf = ReadBuffer(rel, blkno);
} else {
}
else
{
buf = ReadBuffer(rel, blkno);
blkno = BufferGetBlockNumber(buf);
page = BufferGetPage(buf);
@ -392,6 +411,7 @@ _bt_wrtnorelbuf(Relation rel, Buffer buf)
void
_bt_pageinit(Page page, Size size)
{
/*
* Cargo-cult programming -- don't really need this to be zero, but
* creating new pages is an infrequent occurrence and it makes me feel
@ -431,7 +451,7 @@ _bt_metaproot(Relation rel, BlockNumber rootbknum, int level)
metad = BTPageGetMeta(metap);
metad->btm_root = rootbknum;
#ifdef BTREE_VERSION_1
if ( level == 0 ) /* called from _do_insert */
if (level == 0) /* called from _do_insert */
metad->btm_level += 1;
else
metad->btm_level = level; /* called from btsort */
@ -455,7 +475,9 @@ _bt_getstackbuf(Relation rel, BTStack stack, int access)
{
Buffer buf;
BlockNumber blkno;
OffsetNumber start, offnum, maxoff;
OffsetNumber start,
offnum,
maxoff;
OffsetNumber i;
Page page;
ItemId itemid;
@ -470,12 +492,13 @@ _bt_getstackbuf(Relation rel, BTStack stack, int access)
opaque = (BTPageOpaque) PageGetSpecialPointer(page);
maxoff = PageGetMaxOffsetNumber(page);
if (maxoff >= stack->bts_offset) {
if (maxoff >= stack->bts_offset)
{
itemid = PageGetItemId(page, stack->bts_offset);
item = (BTItem) PageGetItem(page, itemid);
/* if the item is where we left it, we're done */
if ( BTItemSame (item, stack->bts_btitem) )
if (BTItemSame(item, stack->bts_btitem))
{
pfree(stack->bts_btitem);
item_nbytes = ItemIdGetLength(itemid);
@ -488,12 +511,13 @@ _bt_getstackbuf(Relation rel, BTStack stack, int access)
/* if the item has just moved right on this page, we're done */
for (i = OffsetNumberNext(stack->bts_offset);
i <= maxoff;
i = OffsetNumberNext(i)) {
i = OffsetNumberNext(i))
{
itemid = PageGetItemId(page, i);
item = (BTItem) PageGetItem(page, itemid);
/* if the item is where we left it, we're done */
if ( BTItemSame (item, stack->bts_btitem) )
if (BTItemSame(item, stack->bts_btitem))
{
stack->bts_offset = i;
pfree(stack->bts_btitem);
@ -507,7 +531,8 @@ _bt_getstackbuf(Relation rel, BTStack stack, int access)
}
/* by here, the item we're looking for moved right at least one page */
for (;;) {
for (;;)
{
blkno = opaque->btpo_next;
if (P_RIGHTMOST(opaque))
elog(FATAL, "my bits moved right off the end of the world!");
@ -524,10 +549,11 @@ _bt_getstackbuf(Relation rel, BTStack stack, int access)
/* see if it's on this page */
for (offnum = start;
offnum <= maxoff;
offnum = OffsetNumberNext(offnum)) {
offnum = OffsetNumberNext(offnum))
{
itemid = PageGetItemId(page, offnum);
item = (BTItem) PageGetItem(page, itemid);
if ( BTItemSame (item, stack->bts_btitem) )
if (BTItemSame(item, stack->bts_btitem))
{
stack->bts_offset = offnum;
stack->bts_blkno = blkno;
@ -547,7 +573,8 @@ _bt_setpagelock(Relation rel, BlockNumber blkno, int access)
{
ItemPointerData iptr;
if (USELOCKING) {
if (USELOCKING)
{
ItemPointerSet(&iptr, blkno, P_HIKEY);
if (access == BT_WRITE)
@ -562,7 +589,8 @@ _bt_unsetpagelock(Relation rel, BlockNumber blkno, int access)
{
ItemPointerData iptr;
if (USELOCKING) {
if (USELOCKING)
{
ItemPointerSet(&iptr, blkno, P_HIKEY);
if (access == BT_WRITE)

View File

@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/access/nbtree/nbtree.c,v 1.19 1997/05/05 03:41:17 vadim Exp $
* $Header: /cvsroot/pgsql/src/backend/access/nbtree/nbtree.c,v 1.20 1997/09/07 04:38:54 momjian Exp $
*
* NOTES
* This file contains only the public interface routines.
@ -28,19 +28,21 @@
#include <miscadmin.h>
#ifndef HAVE_MEMMOVE
# include <regex/utils.h>
#include <regex/utils.h>
#else
# include <string.h>
#include <string.h>
#endif
#ifdef BTREE_BUILD_STATS
#include <tcop/tcopprot.h>
extern int ShowExecutorStats;
#endif
bool BuildingBtree = false; /* see comment in btbuild() */
bool FastBuild = true; /* use sort/build instead of insertion build */
bool FastBuild = true; /* use sort/build instead of
* insertion build */
/*
* btbuild() -- build a new btree index.
@ -54,31 +56,37 @@ void
btbuild(Relation heap,
Relation index,
int natts,
AttrNumber *attnum,
AttrNumber * attnum,
IndexStrategy istrat,
uint16 pcount,
Datum *params,
FuncIndexInfo *finfo,
PredInfo *predInfo)
Datum * params,
FuncIndexInfo * finfo,
PredInfo * predInfo)
{
HeapScanDesc hscan;
Buffer buffer;
HeapTuple htup;
IndexTuple itup;
TupleDesc htupdesc, itupdesc;
TupleDesc htupdesc,
itupdesc;
Datum *attdata;
bool *nulls;
InsertIndexResult res = 0;
int nhtups, nitups;
int nhtups,
nitups;
int i;
BTItem btitem;
#ifndef OMIT_PARTIAL_INDEX
ExprContext *econtext = (ExprContext *) NULL;
TupleTable tupleTable = (TupleTable) NULL;
TupleTableSlot *slot = (TupleTableSlot *) NULL;
#endif
Oid hrelid, irelid;
Node *pred, *oldPred;
Oid hrelid,
irelid;
Node *pred,
*oldPred;
void *spool = (void *) NULL;
bool isunique;
bool usefast;
@ -91,15 +99,15 @@ btbuild(Relation heap,
/*
* bootstrap processing does something strange, so don't use
* sort/build for initial catalog indices. at some point i need
* to look harder at this. (there is some kind of incremental
* processing going on there.) -- pma 08/29/95
* sort/build for initial catalog indices. at some point i need to
* look harder at this. (there is some kind of incremental processing
* going on there.) -- pma 08/29/95
*/
usefast = (FastBuild && IsNormalProcessingMode());
#ifdef BTREE_BUILD_STATS
if ( ShowExecutorStats )
ResetUsage ();
if (ShowExecutorStats)
ResetUsage();
#endif
/* see if index is unique */
@ -118,25 +126,27 @@ btbuild(Relation heap,
nulls = (bool *) palloc(natts * sizeof(bool));
/*
* If this is a predicate (partial) index, we will need to evaluate the
* predicate using ExecQual, which requires the current tuple to be in a
* slot of a TupleTable. In addition, ExecQual must have an ExprContext
* referring to that slot. Here, we initialize dummy TupleTable and
* ExprContext objects for this purpose. --Nels, Feb '92
* If this is a predicate (partial) index, we will need to evaluate
* the predicate using ExecQual, which requires the current tuple to
* be in a slot of a TupleTable. In addition, ExecQual must have an
* ExprContext referring to that slot. Here, we initialize dummy
* TupleTable and ExprContext objects for this purpose. --Nels, Feb
* '92
*/
#ifndef OMIT_PARTIAL_INDEX
if (pred != NULL || oldPred != NULL) {
if (pred != NULL || oldPred != NULL)
{
tupleTable = ExecCreateTupleTable(1);
slot = ExecAllocTableSlot(tupleTable);
econtext = makeNode(ExprContext);
FillDummyExprContext(econtext, slot, htupdesc, InvalidBuffer);
/*
* we never want to use sort/build if we are extending an
* existing partial index -- it works by inserting the
* newly-qualifying tuples into the existing index.
* (sort/build would overwrite the existing index with one
* consisting of the newly-qualifying tuples.)
* we never want to use sort/build if we are extending an existing
* partial index -- it works by inserting the newly-qualifying
* tuples into the existing index. (sort/build would overwrite the
* existing index with one consisting of the newly-qualifying
* tuples.)
*/
usefast = false;
}
@ -149,12 +159,14 @@ btbuild(Relation heap,
/* build the index */
nhtups = nitups = 0;
if (usefast) {
if (usefast)
{
spool = _bt_spoolinit(index, 7, isunique);
res = (InsertIndexResult) NULL;
}
for (; HeapTupleIsValid(htup); htup = heap_getnext(hscan, 0, &buffer)) {
for (; HeapTupleIsValid(htup); htup = heap_getnext(hscan, 0, &buffer))
{
nhtups++;
@ -162,24 +174,30 @@ btbuild(Relation heap,
* If oldPred != NULL, this is an EXTEND INDEX command, so skip
* this tuple if it was already in the existing partial index
*/
if (oldPred != NULL) {
if (oldPred != NULL)
{
#ifndef OMIT_PARTIAL_INDEX
/*SetSlotContents(slot, htup);*/
/* SetSlotContents(slot, htup); */
slot->val = htup;
if (ExecQual((List*)oldPred, econtext) == true) {
if (ExecQual((List *) oldPred, econtext) == true)
{
nitups++;
continue;
}
#endif /* OMIT_PARTIAL_INDEX */
}
/* Skip this tuple if it doesn't satisfy the partial-index predicate */
if (pred != NULL) {
/*
* Skip this tuple if it doesn't satisfy the partial-index
* predicate
*/
if (pred != NULL)
{
#ifndef OMIT_PARTIAL_INDEX
/* SetSlotContents(slot, htup); */
slot->val = htup;
if (ExecQual((List*)pred, econtext) == false)
if (ExecQual((List *) pred, econtext) == false)
continue;
#endif /* OMIT_PARTIAL_INDEX */
}
@ -187,18 +205,19 @@ btbuild(Relation heap,
nitups++;
/*
* For the current heap tuple, extract all the attributes
* we use in this index, and note which are null.
* For the current heap tuple, extract all the attributes we use
* in this index, and note which are null.
*/
for (i = 1; i <= natts; i++) {
for (i = 1; i <= natts; i++)
{
int attoff;
bool attnull;
/*
* Offsets are from the start of the tuple, and are
* zero-based; indices are one-based. The next call
* returns i - 1. That's data hiding for you.
* zero-based; indices are one-based. The next call returns i
* - 1. That's data hiding for you.
*/
attoff = AttrNumberGetAttrOffset(i);
@ -216,49 +235,50 @@ btbuild(Relation heap,
itup = index_formtuple(itupdesc, attdata, nulls);
/*
* If the single index key is null, we don't insert it into
* the index. Btrees support scans on <, <=, =, >=, and >.
* Relational algebra says that A op B (where op is one of the
* operators above) returns null if either A or B is null. This
* means that no qualification used in an index scan could ever
* return true on a null attribute. It also means that indices
* can't be used by ISNULL or NOTNULL scans, but that's an
* artifact of the strategy map architecture chosen in 1986, not
* of the way nulls are handled here.
* If the single index key is null, we don't insert it into the
* index. Btrees support scans on <, <=, =, >=, and >. Relational
* algebra says that A op B (where op is one of the operators
* above) returns null if either A or B is null. This means that
* no qualification used in an index scan could ever return true
* on a null attribute. It also means that indices can't be used
* by ISNULL or NOTNULL scans, but that's an artifact of the
* strategy map architecture chosen in 1986, not of the way nulls
* are handled here.
*/
/*
* New comments: NULLs handling.
* While we can't do NULL comparison, we can follow simple
* rule for ordering items on btree pages - NULLs greater
* NOT_NULLs and NULL = NULL is TRUE. Sure, it's just rule
* for placing/finding items and no more - keytest'll return
* FALSE for a = 5 for items having 'a' isNULL.
* Look at _bt_skeycmp, _bt_compare and _bt_itemcmp for
* how it works. - vadim 03/23/97
if (itup->t_info & INDEX_NULL_MASK) {
pfree(itup);
continue;
}
/*
* New comments: NULLs handling. While we can't do NULL
* comparison, we can follow simple rule for ordering items on
* btree pages - NULLs greater NOT_NULLs and NULL = NULL is TRUE.
* Sure, it's just rule for placing/finding items and no more -
* keytest'll return FALSE for a = 5 for items having 'a' isNULL.
* Look at _bt_skeycmp, _bt_compare and _bt_itemcmp for how it
* works. - vadim 03/23/97
*
* if (itup->t_info & INDEX_NULL_MASK) { pfree(itup); continue; }
*/
itup->t_tid = htup->t_ctid;
btitem = _bt_formitem(itup);
/*
* if we are doing bottom-up btree build, we insert the index
* into a spool page for subsequent processing. otherwise, we
* insert into the btree.
* if we are doing bottom-up btree build, we insert the index into
* a spool page for subsequent processing. otherwise, we insert
* into the btree.
*/
if (usefast) {
if (usefast)
{
_bt_spool(index, btitem, spool);
} else {
}
else
{
res = _bt_doinsert(index, btitem, isunique, heap);
}
pfree(btitem);
pfree(itup);
if (res) {
if (res)
{
pfree(res);
}
}
@ -266,7 +286,8 @@ btbuild(Relation heap,
/* okay, all heap tuples are indexed */
heap_endscan(hscan);
if (pred != NULL || oldPred != NULL) {
if (pred != NULL || oldPred != NULL)
{
#ifndef OMIT_PARTIAL_INDEX
ExecDestroyTupleTable(tupleTable, true);
pfree(econtext);
@ -275,30 +296,31 @@ btbuild(Relation heap,
/*
* if we are doing bottom-up btree build, we now have a bunch of
* sorted runs in the spool pages. finish the build by (1)
* merging the runs, (2) inserting the sorted tuples into btree
* pages and (3) building the upper levels.
* sorted runs in the spool pages. finish the build by (1) merging
* the runs, (2) inserting the sorted tuples into btree pages and (3)
* building the upper levels.
*/
if (usefast) {
if (usefast)
{
_bt_spool(index, (BTItem) NULL, spool); /* flush the spool */
_bt_leafbuild(index, spool);
_bt_spooldestroy(spool);
}
#ifdef BTREE_BUILD_STATS
if ( ShowExecutorStats )
if (ShowExecutorStats)
{
fprintf(stderr, "! BtreeBuild Stats:\n");
ShowUsage ();
ResetUsage ();
ShowUsage();
ResetUsage();
}
#endif
/*
* Since we just counted the tuples in the heap, we update its
* stats in pg_class to guarantee that the planner takes advantage
* of the index we just created. Finally, only update statistics
* during normal index definitions, not for indices on system catalogs
* Since we just counted the tuples in the heap, we update its stats
* in pg_class to guarantee that the planner takes advantage of the
* index we just created. Finally, only update statistics during
* normal index definitions, not for indices on system catalogs
* created during bootstrap processing. We must close the relations
* before updatings statistics to guarantee that the relcache entries
* are flushed when we increment the command counter in UpdateStats().
@ -311,8 +333,10 @@ btbuild(Relation heap,
index_close(index);
UpdateStats(hrelid, nhtups, true);
UpdateStats(irelid, nitups, false);
if (oldPred != NULL) {
if (nitups == nhtups) pred = NULL;
if (oldPred != NULL)
{
if (nitups == nhtups)
pred = NULL;
UpdateIndexPredicate(irelid, oldPred, pred);
}
}
@ -332,7 +356,7 @@ btbuild(Relation heap,
* return an InsertIndexResult to the caller.
*/
InsertIndexResult
btinsert(Relation rel, Datum *datum, char *nulls, ItemPointer ht_ctid, Relation heapRel)
btinsert(Relation rel, Datum * datum, char *nulls, ItemPointer ht_ctid, Relation heapRel)
{
BTItem btitem;
IndexTuple itup;
@ -344,9 +368,8 @@ btinsert(Relation rel, Datum *datum, char *nulls, ItemPointer ht_ctid, Relation
/*
* See comments in btbuild.
if (itup->t_info & INDEX_NULL_MASK)
return ((InsertIndexResult) NULL);
*
* if (itup->t_info & INDEX_NULL_MASK) return ((InsertIndexResult) NULL);
*/
btitem = _bt_formitem(itup);
@ -372,9 +395,9 @@ btgettuple(IndexScanDesc scan, ScanDirection dir)
RetrieveIndexResult res;
/*
* If we've already initialized this scan, we can just advance it
* in the appropriate direction. If we haven't done so yet, we
* call a routine to get the first item in the scan.
* If we've already initialized this scan, we can just advance it in
* the appropriate direction. If we haven't done so yet, we call a
* routine to get the first item in the scan.
*/
if (ItemPointerIsValid(&(scan->currentItemData)))
@ -414,36 +437,39 @@ btrescan(IndexScanDesc scan, bool fromEnd, ScanKey scankey)
so = (BTScanOpaque) scan->opaque;
/* we hold a read lock on the current page in the scan */
if (ItemPointerIsValid(iptr = &(scan->currentItemData))) {
if (ItemPointerIsValid(iptr = &(scan->currentItemData)))
{
_bt_relbuf(scan->relation, so->btso_curbuf, BT_READ);
so->btso_curbuf = InvalidBuffer;
ItemPointerSetInvalid(iptr);
}
/* and we hold a read lock on the last marked item in the scan */
if (ItemPointerIsValid(iptr = &(scan->currentMarkData))) {
if (ItemPointerIsValid(iptr = &(scan->currentMarkData)))
{
_bt_relbuf(scan->relation, so->btso_mrkbuf, BT_READ);
so->btso_mrkbuf = InvalidBuffer;
ItemPointerSetInvalid(iptr);
}
if ( so == NULL ) /* if called from btbeginscan */
if (so == NULL) /* if called from btbeginscan */
{
so = (BTScanOpaque) palloc(sizeof(BTScanOpaqueData));
so->btso_curbuf = so->btso_mrkbuf = InvalidBuffer;
so->keyData = (ScanKey) NULL;
if ( scan->numberOfKeys > 0)
so->keyData = (ScanKey) palloc (scan->numberOfKeys * sizeof(ScanKeyData));
if (scan->numberOfKeys > 0)
so->keyData = (ScanKey) palloc(scan->numberOfKeys * sizeof(ScanKeyData));
scan->opaque = so;
scan->flags = 0x0;
}
/*
* Reset the scan keys. Note that keys ordering stuff
* moved to _bt_first. - vadim 05/05/97
* Reset the scan keys. Note that keys ordering stuff moved to
* _bt_first. - vadim 05/05/97
*/
so->numberOfKeys = scan->numberOfKeys;
if (scan->numberOfKeys > 0) {
if (scan->numberOfKeys > 0)
{
memmove(scan->keyData,
scankey,
scan->numberOfKeys * sizeof(ScanKeyData));
@ -463,7 +489,8 @@ btmovescan(IndexScanDesc scan, Datum v)
so = (BTScanOpaque) scan->opaque;
/* release any locks we still hold */
if (ItemPointerIsValid(iptr = &(scan->currentItemData))) {
if (ItemPointerIsValid(iptr = &(scan->currentItemData)))
{
_bt_relbuf(scan->relation, so->btso_curbuf, BT_READ);
so->btso_curbuf = InvalidBuffer;
ItemPointerSetInvalid(iptr);
@ -485,23 +512,25 @@ btendscan(IndexScanDesc scan)
so = (BTScanOpaque) scan->opaque;
/* release any locks we still hold */
if (ItemPointerIsValid(iptr = &(scan->currentItemData))) {
if (ItemPointerIsValid(iptr = &(scan->currentItemData)))
{
if (BufferIsValid(so->btso_curbuf))
_bt_relbuf(scan->relation, so->btso_curbuf, BT_READ);
so->btso_curbuf = InvalidBuffer;
ItemPointerSetInvalid(iptr);
}
if (ItemPointerIsValid(iptr = &(scan->currentMarkData))) {
if (ItemPointerIsValid(iptr = &(scan->currentMarkData)))
{
if (BufferIsValid(so->btso_mrkbuf))
_bt_relbuf(scan->relation, so->btso_mrkbuf, BT_READ);
so->btso_mrkbuf = InvalidBuffer;
ItemPointerSetInvalid(iptr);
}
if ( so->keyData != (ScanKey) NULL )
pfree (so->keyData);
pfree (so);
if (so->keyData != (ScanKey) NULL)
pfree(so->keyData);
pfree(so);
_bt_dropscan(scan);
}
@ -518,14 +547,16 @@ btmarkpos(IndexScanDesc scan)
so = (BTScanOpaque) scan->opaque;
/* release lock on old marked data, if any */
if (ItemPointerIsValid(iptr = &(scan->currentMarkData))) {
if (ItemPointerIsValid(iptr = &(scan->currentMarkData)))
{
_bt_relbuf(scan->relation, so->btso_mrkbuf, BT_READ);
so->btso_mrkbuf = InvalidBuffer;
ItemPointerSetInvalid(iptr);
}
/* bump lock on currentItemData and copy to currentMarkData */
if (ItemPointerIsValid(&(scan->currentItemData))) {
if (ItemPointerIsValid(&(scan->currentItemData)))
{
so->btso_mrkbuf = _bt_getbuf(scan->relation,
BufferGetBlockNumber(so->btso_curbuf),
BT_READ);
@ -545,14 +576,16 @@ btrestrpos(IndexScanDesc scan)
so = (BTScanOpaque) scan->opaque;
/* release lock on current data, if any */
if (ItemPointerIsValid(iptr = &(scan->currentItemData))) {
if (ItemPointerIsValid(iptr = &(scan->currentItemData)))
{
_bt_relbuf(scan->relation, so->btso_curbuf, BT_READ);
so->btso_curbuf = InvalidBuffer;
ItemPointerSetInvalid(iptr);
}
/* bump lock on currentMarkData and copy to currentItemData */
if (ItemPointerIsValid(&(scan->currentMarkData))) {
if (ItemPointerIsValid(&(scan->currentMarkData)))
{
so->btso_curbuf = _bt_getbuf(scan->relation,
BufferGetBlockNumber(so->btso_mrkbuf),
BT_READ);

View File

@ -7,7 +7,7 @@
*
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/access/nbtree/Attic/nbtscan.c,v 1.7 1997/02/18 17:13:45 momjian Exp $
* $Header: /cvsroot/pgsql/src/backend/access/nbtree/Attic/nbtscan.c,v 1.8 1997/09/07 04:38:57 momjian Exp $
*
*
* NOTES
@ -32,7 +32,8 @@
#include <storage/bufpage.h>
#include <access/nbtree.h>
typedef struct BTScanListData {
typedef struct BTScanListData
{
IndexScanDesc btsl_scan;
struct BTScanListData *btsl_next;
} BTScanListData;
@ -64,12 +65,14 @@ _bt_regscan(IndexScanDesc scan)
void
_bt_dropscan(IndexScanDesc scan)
{
BTScanList chk, last;
BTScanList chk,
last;
last = (BTScanList) NULL;
for (chk = BTScans;
chk != (BTScanList) NULL && chk->btsl_scan != scan;
chk = chk->btsl_next) {
chk = chk->btsl_next)
{
last = chk;
}
@ -81,7 +84,7 @@ _bt_dropscan(IndexScanDesc scan)
else
last->btsl_next = chk->btsl_next;
pfree (chk);
pfree(chk);
}
/*
@ -95,7 +98,8 @@ _bt_adjscans(Relation rel, ItemPointer tid, int op)
Oid relid;
relid = rel->rd_id;
for (l = BTScans; l != (BTScanList) NULL; l = l->btsl_next) {
for (l = BTScans; l != (BTScanList) NULL; l = l->btsl_next)
{
if (relid == l->btsl_scan->relation->rd_id)
_bt_scandel(l->btsl_scan, op,
ItemPointerGetBlockNumber(tid),
@ -139,8 +143,10 @@ _bt_scandel(IndexScanDesc scan, int op, BlockNumber blkno, OffsetNumber offno)
current = &(scan->currentItemData);
if (ItemPointerIsValid(current)
&& ItemPointerGetBlockNumber(current) == blkno
&& ItemPointerGetOffsetNumber(current) >= offno) {
switch (op) {
&& ItemPointerGetOffsetNumber(current) >= offno)
{
switch (op)
{
case BT_INSERT:
_bt_step(scan, &buf, ForwardScanDirection);
break;
@ -149,7 +155,7 @@ _bt_scandel(IndexScanDesc scan, int op, BlockNumber blkno, OffsetNumber offno)
break;
default:
elog(WARN, "_bt_scandel: bad operation '%d'", op);
/*NOTREACHED*/
/* NOTREACHED */
}
so->btso_curbuf = buf;
}
@ -157,12 +163,15 @@ _bt_scandel(IndexScanDesc scan, int op, BlockNumber blkno, OffsetNumber offno)
current = &(scan->currentMarkData);
if (ItemPointerIsValid(current)
&& ItemPointerGetBlockNumber(current) == blkno
&& ItemPointerGetOffsetNumber(current) >= offno) {
&& ItemPointerGetOffsetNumber(current) >= offno)
{
ItemPointerData tmp;
tmp = *current;
*current = scan->currentItemData;
scan->currentItemData = tmp;
switch (op) {
switch (op)
{
case BT_INSERT:
_bt_step(scan, &buf, ForwardScanDirection);
break;
@ -171,7 +180,7 @@ _bt_scandel(IndexScanDesc scan, int op, BlockNumber blkno, OffsetNumber offno)
break;
default:
elog(WARN, "_bt_scandel: bad operation '%d'", op);
/*NOTREACHED*/
/* NOTREACHED */
}
so->btso_mrkbuf = buf;
tmp = *current;

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -7,7 +7,7 @@
*
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/access/nbtree/Attic/nbtstrat.c,v 1.4 1996/11/05 10:35:37 scrappy Exp $
* $Header: /cvsroot/pgsql/src/backend/access/nbtree/Attic/nbtstrat.c,v 1.5 1997/09/07 04:39:04 momjian Exp $
*
*-------------------------------------------------------------------------
*/
@ -69,7 +69,7 @@ static uint16 BTGreaterEqualTermData[] = { /* XXX type clash */
0x0,
BTGreaterEqualStrategyNumber,
SK_COMMUTE
};
};
static uint16 BTGreaterTermData[] = { /* XXX type clash */
2,
@ -80,10 +80,10 @@ static uint16 BTGreaterTermData[] = { /* XXX type clash */
};
static StrategyTerm BTEqualExpressionData[] = {
(StrategyTerm)BTLessTermData, /* XXX */
(StrategyTerm)BTLessEqualTermData, /* XXX */
(StrategyTerm)BTGreaterEqualTermData, /* XXX */
(StrategyTerm)BTGreaterTermData, /* XXX */
(StrategyTerm) BTLessTermData, /* XXX */
(StrategyTerm) BTLessEqualTermData, /* XXX */
(StrategyTerm) BTGreaterEqualTermData, /* XXX */
(StrategyTerm) BTGreaterTermData, /* XXX */
NULL
};
@ -91,12 +91,12 @@ static StrategyEvaluationData BTEvaluationData = {
/* XXX static for simplicity */
BTMaxStrategyNumber,
(StrategyTransformMap)BTNegate, /* XXX */
(StrategyTransformMap)BTCommute, /* XXX */
(StrategyTransformMap)BTNegateCommute, /* XXX */
(StrategyTransformMap) BTNegate, /* XXX */
(StrategyTransformMap) BTCommute, /* XXX */
(StrategyTransformMap) BTNegateCommute, /* XXX */
{ NULL, NULL, (StrategyExpression)BTEqualExpressionData, NULL, NULL,
NULL,NULL,NULL,NULL,NULL,NULL,NULL}
{NULL, NULL, (StrategyExpression) BTEqualExpressionData, NULL, NULL,
NULL, NULL, NULL, NULL, NULL, NULL, NULL}
};
/* ----------------------------------------------------------------

View File

@ -7,7 +7,7 @@
*
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/access/nbtree/nbtutils.c,v 1.11 1997/08/19 21:29:47 momjian Exp $
* $Header: /cvsroot/pgsql/src/backend/access/nbtree/nbtutils.c,v 1.12 1997/09/07 04:39:05 momjian Exp $
*
*-------------------------------------------------------------------------
*/
@ -27,9 +27,9 @@ extern int NIndexTupleProcessed;
#ifndef HAVE_MEMMOVE
# include <regex/utils.h>
#include <regex/utils.h>
#else
# include <string.h>
#include <string.h>
#endif
ScanKey
@ -49,9 +49,10 @@ _bt_mkscankey(Relation rel, IndexTuple itup)
skey = (ScanKey) palloc(natts * sizeof(ScanKeyData));
for (i = 0; i < natts; i++) {
for (i = 0; i < natts; i++)
{
arg = index_getattr(itup, i + 1, itupdesc, &null);
if ( null )
if (null)
{
proc = NullValueRegProcedure;
flag = SK_ISNULL;
@ -79,7 +80,8 @@ _bt_freestack(BTStack stack)
{
BTStack ostack;
while (stack != (BTStack) NULL) {
while (stack != (BTStack) NULL)
{
ostack = stack;
stack = stack->bts_parent;
pfree(ostack->bts_btitem);
@ -102,30 +104,32 @@ _bt_orderkeys(Relation relation, BTScanOpaque so)
StrategyMap map;
int nbytes;
long test;
int i, j;
int init[BTMaxStrategyNumber+1];
int i,
j;
int init[BTMaxStrategyNumber + 1];
ScanKey key;
uint16 numberOfKeys = so->numberOfKeys;
uint16 new_numberOfKeys = 0;
AttrNumber attno = 1;
if ( numberOfKeys < 1 )
if (numberOfKeys < 1)
return;
key = so->keyData;
cur = &key[0];
if ( cur->sk_attno != 1 )
elog (WARN, "_bt_orderkeys: key(s) for attribute 1 missed");
if (cur->sk_attno != 1)
elog(WARN, "_bt_orderkeys: key(s) for attribute 1 missed");
if ( numberOfKeys == 1 )
if (numberOfKeys == 1)
{
/*
* We don't use indices for 'A is null' and 'A is not null'
* currently and 'A < = > <> NULL' is non-sense' - so
* qual is not Ok. - vadim 03/21/97
* currently and 'A < = > <> NULL' is non-sense' - so qual is not
* Ok. - vadim 03/21/97
*/
if ( cur->sk_flags & SK_ISNULL )
if (cur->sk_flags & SK_ISNULL)
so->qual_ok = 0;
so->numberOfFirstKeys = 1;
return;
@ -143,33 +147,35 @@ _bt_orderkeys(Relation relation, BTScanOpaque so)
init[j] = 0;
/* check each key passed in */
for (i = 0; ; )
for (i = 0;;)
{
if ( i < numberOfKeys )
if (i < numberOfKeys)
cur = &key[i];
if ( cur->sk_flags & SK_ISNULL ) /* see comments above */
if (cur->sk_flags & SK_ISNULL) /* see comments above */
so->qual_ok = 0;
if ( i == numberOfKeys || cur->sk_attno != attno )
if (i == numberOfKeys || cur->sk_attno != attno)
{
if ( cur->sk_attno != attno + 1 && i < numberOfKeys )
if (cur->sk_attno != attno + 1 && i < numberOfKeys)
{
elog (WARN, "_bt_orderkeys: key(s) for attribute %d missed", attno + 1);
elog(WARN, "_bt_orderkeys: key(s) for attribute %d missed", attno + 1);
}
/*
* If = has been specified, no other key will be used.
* In case of key < 2 && key == 1 and so on
* we have to set qual_ok to 0
* If = has been specified, no other key will be used. In case
* of key < 2 && key == 1 and so on we have to set qual_ok to
* 0
*/
if (init[BTEqualStrategyNumber - 1])
{
ScanKeyData *eq, *chk;
ScanKeyData *eq,
*chk;
eq = &xform[BTEqualStrategyNumber - 1];
for (j = BTMaxStrategyNumber; --j >= 0; )
for (j = BTMaxStrategyNumber; --j >= 0;)
{
if ( j == (BTEqualStrategyNumber - 1) || init[j] == 0 )
if (j == (BTEqualStrategyNumber - 1) || init[j] == 0)
continue;
chk = &xform[j];
test = (long) fmgr(chk->sk_procedure, eq->sk_argument, chk->sk_argument);
@ -186,16 +192,18 @@ _bt_orderkeys(Relation relation, BTScanOpaque so)
if (init[BTLessStrategyNumber - 1]
&& init[BTLessEqualStrategyNumber - 1])
{
ScanKeyData *lt, *le;
ScanKeyData *lt,
*le;
lt = &xform[BTLessStrategyNumber - 1];
le = &xform[BTLessEqualStrategyNumber - 1];
/*
* DO NOT use the cached function stuff here -- this is key
* ordering, happens only when the user expresses a hokey
* qualification, and gets executed only once, anyway. The
* transform maps are hard-coded, and can't be initialized
* in the correct way.
* DO NOT use the cached function stuff here -- this is
* key ordering, happens only when the user expresses a
* hokey qualification, and gets executed only once,
* anyway. The transform maps are hard-coded, and can't
* be initialized in the correct way.
*/
test = (long) fmgr(le->sk_procedure, lt->sk_argument, le->sk_argument);
if (test)
@ -208,7 +216,8 @@ _bt_orderkeys(Relation relation, BTScanOpaque so)
if (init[BTGreaterStrategyNumber - 1]
&& init[BTGreaterEqualStrategyNumber - 1])
{
ScanKeyData *gt, *ge;
ScanKeyData *gt,
*ge;
gt = &xform[BTGreaterStrategyNumber - 1];
ge = &xform[BTGreaterEqualStrategyNumber - 1];
@ -222,14 +231,14 @@ _bt_orderkeys(Relation relation, BTScanOpaque so)
}
/* okay, reorder and count */
for (j = BTMaxStrategyNumber; --j >= 0; )
for (j = BTMaxStrategyNumber; --j >= 0;)
if (init[j])
key[new_numberOfKeys++] = xform[j];
if ( attno == 1 )
if (attno == 1)
so->numberOfFirstKeys = new_numberOfKeys;
if ( i == numberOfKeys )
if (i == numberOfKeys)
break;
/* initialization for new attno */
@ -243,7 +252,7 @@ _bt_orderkeys(Relation relation, BTScanOpaque so)
init[j] = 0;
}
for (j = BTMaxStrategyNumber; --j >= 0; )
for (j = BTMaxStrategyNumber; --j >= 0;)
{
if (cur->sk_procedure == map->entry[j].sk_procedure)
break;
@ -258,9 +267,10 @@ _bt_orderkeys(Relation relation, BTScanOpaque so)
cur->sk_argument, xform[j].sk_argument);
if (test)
xform[j].sk_argument = cur->sk_argument;
else if ( j == (BTEqualStrategyNumber - 1) )
so->qual_ok = 0; /* key == a && key == b, but a != b */
} else
else if (j == (BTEqualStrategyNumber - 1))
so->qual_ok = 0;/* key == a && key == b, but a != b */
}
else
{
/* nope, use this value */
memmove(&xform[j], cur, sizeof(*cur));
@ -283,10 +293,11 @@ _bt_formitem(IndexTuple itup)
Size tuplen;
extern Oid newoid();
/* see comments in btbuild
if (itup->t_info & INDEX_NULL_MASK)
elog(WARN, "btree indices cannot include null keys");
/*
* see comments in btbuild
*
* if (itup->t_info & INDEX_NULL_MASK) elog(WARN, "btree indices cannot
* include null keys");
*/
/* make a copy of the index tuple with room for the sequence number */
@ -316,6 +327,7 @@ _bt_checkqual(IndexScanDesc scan, IndexTuple itup)
else
return (true);
}
#endif
#ifdef NOT_USED
@ -325,16 +337,17 @@ _bt_checkforkeys(IndexScanDesc scan, IndexTuple itup, Size keysz)
BTScanOpaque so;
so = (BTScanOpaque) scan->opaque;
if ( keysz > 0 && so->numberOfKeys >= keysz )
if (keysz > 0 && so->numberOfKeys >= keysz)
return (index_keytest(itup, RelationGetTupleDescriptor(scan->relation),
keysz, so->keyData));
else
return (true);
}
#endif
bool
_bt_checkkeys (IndexScanDesc scan, IndexTuple tuple, Size *keysok)
_bt_checkkeys(IndexScanDesc scan, IndexTuple tuple, Size * keysok)
{
BTScanOpaque so = (BTScanOpaque) scan->opaque;
Size keysz = so->numberOfKeys;
@ -345,7 +358,7 @@ _bt_checkkeys (IndexScanDesc scan, IndexTuple tuple, Size *keysok)
int test;
*keysok = 0;
if ( keysz == 0 )
if (keysz == 0)
return (true);
key = so->keyData;
@ -361,22 +374,26 @@ _bt_checkkeys (IndexScanDesc scan, IndexTuple tuple, Size *keysok)
&isNull);
/* btree doesn't support 'A is null' clauses, yet */
if ( isNull || key[0].sk_flags & SK_ISNULL )
if (isNull || key[0].sk_flags & SK_ISNULL)
{
return (false);
}
if (key[0].sk_flags & SK_COMMUTE) {
if (key[0].sk_flags & SK_COMMUTE)
{
test = (int) (*(key[0].sk_func))
(DatumGetPointer(key[0].sk_argument),
datum);
} else {
}
else
{
test = (int) (*(key[0].sk_func))
(datum,
DatumGetPointer(key[0].sk_argument));
}
if (!test == !(key[0].sk_flags & SK_NEGATE)) {
if (!test == !(key[0].sk_flags & SK_NEGATE))
{
return (false);
}

View File

@ -7,7 +7,7 @@
*
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/access/rtree/Attic/rtget.c,v 1.7 1996/11/21 06:13:43 vadim Exp $
* $Header: /cvsroot/pgsql/src/backend/access/rtree/Attic/rtget.c,v 1.8 1997/09/07 04:39:11 momjian Exp $
*
*-------------------------------------------------------------------------
*/
@ -21,13 +21,14 @@
#include <access/rtree.h>
#include <storage/bufpage.h>
#ifndef HAVE_MEMMOVE
# include <regex/utils.h>
#include <regex/utils.h>
#else
# include <string.h>
#include <string.h>
#endif
static OffsetNumber findnext(IndexScanDesc s, Page p, OffsetNumber n,
static OffsetNumber
findnext(IndexScanDesc s, Page p, OffsetNumber n,
ScanDirection dir);
static RetrieveIndexResult rtscancache(IndexScanDesc s, ScanDirection dir);
static RetrieveIndexResult rtfirst(IndexScanDesc s, ScanDirection dir);
@ -45,9 +46,12 @@ rtgettuple(IndexScanDesc s, ScanDirection dir)
return (res);
/* not cached, so we'll have to do some work */
if (ItemPointerIsValid(&(s->currentItemData))) {
if (ItemPointerIsValid(&(s->currentItemData)))
{
res = rtnext(s, dir);
} else {
}
else
{
res = rtfirst(s, dir);
}
return (res);
@ -72,14 +76,16 @@ rtfirst(IndexScanDesc s, ScanDirection dir)
po = (RTreePageOpaque) PageGetSpecialPointer(p);
so = (RTreeScanOpaque) s->opaque;
for (;;) {
for (;;)
{
maxoff = PageGetMaxOffsetNumber(p);
if (ScanDirectionIsBackward(dir))
n = findnext(s, p, maxoff, dir);
else
n = findnext(s, p, FirstOffsetNumber, dir);
while (n < FirstOffsetNumber || n > maxoff) {
while (n < FirstOffsetNumber || n > maxoff)
{
ReleaseBuffer(b);
if (so->s_stack == (RTSTACK *) NULL)
@ -91,9 +97,12 @@ rtfirst(IndexScanDesc s, ScanDirection dir)
po = (RTreePageOpaque) PageGetSpecialPointer(p);
maxoff = PageGetMaxOffsetNumber(p);
if (ScanDirectionIsBackward(dir)) {
if (ScanDirectionIsBackward(dir))
{
n = OffsetNumberPrev(stk->rts_child);
} else {
}
else
{
n = OffsetNumberNext(stk->rts_child);
}
so->s_stack = stk->rts_parent;
@ -101,7 +110,8 @@ rtfirst(IndexScanDesc s, ScanDirection dir)
n = findnext(s, p, n, dir);
}
if (po->flags & F_LEAF) {
if (po->flags & F_LEAF)
{
ItemPointerSet(&(s->currentItemData), BufferGetBlockNumber(b), n);
it = (IndexTuple) PageGetItem(p, PageGetItemId(p, n));
@ -110,7 +120,9 @@ rtfirst(IndexScanDesc s, ScanDirection dir)
ReleaseBuffer(b);
return (res);
} else {
}
else
{
stk = (RTSTACK *) palloc(sizeof(RTSTACK));
stk->rts_child = n;
stk->rts_blk = BufferGetBlockNumber(b);
@ -145,9 +157,12 @@ rtnext(IndexScanDesc s, ScanDirection dir)
blk = ItemPointerGetBlockNumber(&(s->currentItemData));
n = ItemPointerGetOffsetNumber(&(s->currentItemData));
if (ScanDirectionIsForward(dir)) {
if (ScanDirectionIsForward(dir))
{
n = OffsetNumberNext(n);
} else {
}
else
{
n = OffsetNumberPrev(n);
}
@ -156,11 +171,13 @@ rtnext(IndexScanDesc s, ScanDirection dir)
po = (RTreePageOpaque) PageGetSpecialPointer(p);
so = (RTreeScanOpaque) s->opaque;
for (;;) {
for (;;)
{
maxoff = PageGetMaxOffsetNumber(p);
n = findnext(s, p, n, dir);
while (n < FirstOffsetNumber || n > maxoff) {
while (n < FirstOffsetNumber || n > maxoff)
{
ReleaseBuffer(b);
if (so->s_stack == (RTSTACK *) NULL)
@ -172,9 +189,12 @@ rtnext(IndexScanDesc s, ScanDirection dir)
maxoff = PageGetMaxOffsetNumber(p);
po = (RTreePageOpaque) PageGetSpecialPointer(p);
if (ScanDirectionIsBackward(dir)) {
if (ScanDirectionIsBackward(dir))
{
n = OffsetNumberPrev(stk->rts_child);
} else {
}
else
{
n = OffsetNumberNext(stk->rts_child);
}
so->s_stack = stk->rts_parent;
@ -182,7 +202,8 @@ rtnext(IndexScanDesc s, ScanDirection dir)
n = findnext(s, p, n, dir);
}
if (po->flags & F_LEAF) {
if (po->flags & F_LEAF)
{
ItemPointerSet(&(s->currentItemData), BufferGetBlockNumber(b), n);
it = (IndexTuple) PageGetItem(p, PageGetItemId(p, n));
@ -191,7 +212,9 @@ rtnext(IndexScanDesc s, ScanDirection dir)
ReleaseBuffer(b);
return (res);
} else {
}
else
{
stk = (RTSTACK *) palloc(sizeof(RTSTACK));
stk->rts_child = n;
stk->rts_blk = BufferGetBlockNumber(b);
@ -206,9 +229,12 @@ rtnext(IndexScanDesc s, ScanDirection dir)
p = BufferGetPage(b);
po = (RTreePageOpaque) PageGetSpecialPointer(p);
if (ScanDirectionIsBackward(dir)) {
if (ScanDirectionIsBackward(dir))
{
n = PageGetMaxOffsetNumber(p);
} else {
}
else
{
n = FirstOffsetNumber;
}
}
@ -232,28 +258,36 @@ findnext(IndexScanDesc s, Page p, OffsetNumber n, ScanDirection dir)
* a ghost tuple, before the scan. If this is the case, back up one.
*/
if (so->s_flags & RTS_CURBEFORE) {
if (so->s_flags & RTS_CURBEFORE)
{
so->s_flags &= ~RTS_CURBEFORE;
n = OffsetNumberPrev(n);
}
while (n >= FirstOffsetNumber && n <= maxoff) {
while (n >= FirstOffsetNumber && n <= maxoff)
{
it = (IndexTuple) PageGetItem(p, PageGetItemId(p, n));
if (po->flags & F_LEAF) {
if (po->flags & F_LEAF)
{
if (index_keytest(it,
RelationGetTupleDescriptor(s->relation),
s->numberOfKeys, s->keyData))
break;
} else {
}
else
{
if (index_keytest(it,
RelationGetTupleDescriptor(s->relation),
so->s_internalNKey, so->s_internalKey))
break;
}
if (ScanDirectionIsBackward(dir)) {
if (ScanDirectionIsBackward(dir))
{
n = OffsetNumberPrev(n);
} else {
}
else
{
n = OffsetNumberNext(n);
}
}
@ -268,7 +302,8 @@ rtscancache(IndexScanDesc s, ScanDirection dir)
ItemPointer ip;
if (!(ScanDirectionIsNoMovement(dir)
&& ItemPointerIsValid(&(s->currentItemData)))) {
&& ItemPointerIsValid(&(s->currentItemData))))
{
return ((RetrieveIndexResult) NULL);
}
@ -280,7 +315,7 @@ rtscancache(IndexScanDesc s, ScanDirection dir)
else
res = (RetrieveIndexResult) NULL;
pfree (ip);
pfree(ip);
return (res);
}
@ -299,7 +334,8 @@ rtheapptr(Relation r, ItemPointer itemp)
OffsetNumber n;
ip = (ItemPointer) palloc(sizeof(ItemPointerData));
if (ItemPointerIsValid(itemp)) {
if (ItemPointerIsValid(itemp))
{
b = ReadBuffer(r, ItemPointerGetBlockNumber(itemp));
p = BufferGetPage(b);
n = ItemPointerGetOffsetNumber(itemp);
@ -307,7 +343,9 @@ rtheapptr(Relation r, ItemPointer itemp)
memmove((char *) ip, (char *) &(it->t_tid),
sizeof(ItemPointerData));
ReleaseBuffer(b);
} else {
}
else
{
ItemPointerSetInvalid(ip);
}

View File

@ -7,7 +7,7 @@
*
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/access/rtree/Attic/rtproc.c,v 1.7 1997/04/22 17:31:23 scrappy Exp $
* $Header: /cvsroot/pgsql/src/backend/access/rtree/Attic/rtproc.c,v 1.8 1997/09/07 04:39:16 momjian Exp $
*
*-------------------------------------------------------------------------
*/
@ -17,17 +17,17 @@
#include <utils/builtins.h>
#include <utils/geo_decls.h>
#ifndef HAVE_MEMMOVE
# include <regex/utils.h>
#include <regex/utils.h>
#else
# include <string.h>
#include <string.h>
#endif
BOX
*rt_box_union(BOX *a, BOX *b)
* rt_box_union(BOX * a, BOX * b)
{
BOX *n;
if ((n = (BOX *) palloc(sizeof (*n))) == (BOX *) NULL)
if ((n = (BOX *) palloc(sizeof(*n))) == (BOX *) NULL)
elog(WARN, "Cannot allocate box for union");
n->high.x = Max(a->high.x, b->high.x);
@ -39,11 +39,11 @@ BOX
}
BOX *
rt_box_inter(BOX *a, BOX *b)
rt_box_inter(BOX * a, BOX * b)
{
BOX *n;
if ((n = (BOX *) palloc(sizeof (*n))) == (BOX *) NULL)
if ((n = (BOX *) palloc(sizeof(*n))) == (BOX *) NULL)
elog(WARN, "Cannot allocate box for union");
n->high.x = Min(a->high.x, b->high.x);
@ -51,7 +51,8 @@ rt_box_inter(BOX *a, BOX *b)
n->low.x = Max(a->low.x, b->low.x);
n->low.y = Max(a->low.y, b->low.y);
if (n->high.x < n->low.x || n->high.y < n->low.y) {
if (n->high.x < n->low.x || n->high.y < n->low.y)
{
pfree(n);
return ((BOX *) NULL);
}
@ -60,7 +61,7 @@ rt_box_inter(BOX *a, BOX *b)
}
void
rt_box_size(BOX *a, float *size)
rt_box_size(BOX * a, float *size)
{
if (a == (BOX *) NULL || a->high.x <= a->low.x || a->high.y <= a->low.y)
*size = 0.0;
@ -79,17 +80,17 @@ rt_box_size(BOX *a, float *size)
* have a special return type for big boxes.
*/
void
rt_bigbox_size(BOX *a, float *size)
rt_bigbox_size(BOX * a, float *size)
{
rt_box_size(a, size);
}
POLYGON *
rt_poly_union(POLYGON *a, POLYGON *b)
rt_poly_union(POLYGON * a, POLYGON * b)
{
POLYGON *p;
p = (POLYGON *)PALLOCTYPE(POLYGON);
p = (POLYGON *) PALLOCTYPE(POLYGON);
if (!PointerIsValid(p))
elog(WARN, "Cannot allocate polygon for union");
@ -105,16 +106,18 @@ rt_poly_union(POLYGON *a, POLYGON *b)
}
void
rt_poly_size(POLYGON *a, float *size)
rt_poly_size(POLYGON * a, float *size)
{
double xdim, ydim;
double xdim,
ydim;
size = (float *) palloc(sizeof(float));
if (a == (POLYGON *) NULL ||
a->boundbox.high.x <= a->boundbox.low.x ||
a->boundbox.high.y <= a->boundbox.low.y)
*size = 0.0;
else {
else
{
xdim = (a->boundbox.high.x - a->boundbox.low.x);
ydim = (a->boundbox.high.y - a->boundbox.low.y);
@ -125,7 +128,7 @@ rt_poly_size(POLYGON *a, float *size)
}
POLYGON *
rt_poly_inter(POLYGON *a, POLYGON *b)
rt_poly_inter(POLYGON * a, POLYGON * b)
{
POLYGON *p;

View File

@ -7,7 +7,7 @@
*
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/access/rtree/Attic/rtree.c,v 1.13 1997/08/12 22:51:54 momjian Exp $
* $Header: /cvsroot/pgsql/src/backend/access/rtree/Attic/rtree.c,v 1.14 1997/09/07 04:39:22 momjian Exp $
*
*-------------------------------------------------------------------------
*/
@ -27,12 +27,13 @@
#include <storage/bufpage.h>
#ifndef HAVE_MEMMOVE
# include <regex/utils.h>
#include <regex/utils.h>
#else
# include <string.h>
#include <string.h>
#endif
typedef struct SPLITVEC {
typedef struct SPLITVEC
{
OffsetNumber *spl_left;
int spl_nleft;
char *spl_ldatum;
@ -41,59 +42,73 @@ typedef struct SPLITVEC {
char *spl_rdatum;
} SPLITVEC;
typedef struct RTSTATE {
typedef struct RTSTATE
{
func_ptr unionFn; /* union function */
func_ptr sizeFn; /* size function */
func_ptr interFn; /* intersection function */
} RTSTATE;
/* non-export function prototypes */
static InsertIndexResult rtdoinsert(Relation r, IndexTuple itup,
RTSTATE *rtstate);
static void rttighten(Relation r, RTSTACK *stk, char *datum, int att_size,
RTSTATE *rtstate);
static InsertIndexResult dosplit(Relation r, Buffer buffer, RTSTACK *stack,
IndexTuple itup, RTSTATE *rtstate);
static void rtintinsert(Relation r, RTSTACK *stk, IndexTuple ltup,
IndexTuple rtup, RTSTATE *rtstate);
static InsertIndexResult
rtdoinsert(Relation r, IndexTuple itup,
RTSTATE * rtstate);
static void
rttighten(Relation r, RTSTACK * stk, char *datum, int att_size,
RTSTATE * rtstate);
static InsertIndexResult
dosplit(Relation r, Buffer buffer, RTSTACK * stack,
IndexTuple itup, RTSTATE * rtstate);
static void
rtintinsert(Relation r, RTSTACK * stk, IndexTuple ltup,
IndexTuple rtup, RTSTATE * rtstate);
static void rtnewroot(Relation r, IndexTuple lt, IndexTuple rt);
static void picksplit(Relation r, Page page, SPLITVEC *v, IndexTuple itup,
RTSTATE *rtstate);
static void
picksplit(Relation r, Page page, SPLITVEC * v, IndexTuple itup,
RTSTATE * rtstate);
static void RTInitBuffer(Buffer b, uint32 f);
static OffsetNumber choose(Relation r, Page p, IndexTuple it,
RTSTATE *rtstate);
static OffsetNumber
choose(Relation r, Page p, IndexTuple it,
RTSTATE * rtstate);
static int nospace(Page p, IndexTuple it);
static void initRtstate(RTSTATE *rtstate, Relation index);
static void initRtstate(RTSTATE * rtstate, Relation index);
void
rtbuild(Relation heap,
Relation index,
int natts,
AttrNumber *attnum,
AttrNumber * attnum,
IndexStrategy istrat,
uint16 pcount,
Datum *params,
FuncIndexInfo *finfo,
PredInfo *predInfo)
Datum * params,
FuncIndexInfo * finfo,
PredInfo * predInfo)
{
HeapScanDesc scan;
Buffer buffer;
AttrNumber i;
HeapTuple htup;
IndexTuple itup;
TupleDesc hd, id;
TupleDesc hd,
id;
InsertIndexResult res;
Datum *d;
bool *nulls;
int nb, nh, ni;
int nb,
nh,
ni;
#ifndef OMIT_PARTIAL_INDEX
ExprContext *econtext;
TupleTable tupleTable;
TupleTableSlot *slot;
#endif
Oid hrelid, irelid;
Node *pred, *oldPred;
Oid hrelid,
irelid;
Node *pred,
*oldPred;
RTSTATE rtState;
initRtstate(&rtState, index);
@ -105,15 +120,16 @@ rtbuild(Relation heap,
oldPred = predInfo->oldPred;
/*
* We expect to be called exactly once for any index relation.
* If that's not the case, big trouble's what we have.
* We expect to be called exactly once for any index relation. If
* that's not the case, big trouble's what we have.
*/
if (oldPred == NULL && (nb = RelationGetNumberOfBlocks(index)) != 0)
elog(WARN, "%s already contains data", index->rd_rel->relname.data);
/* initialize the root page (if this is a new index) */
if (oldPred == NULL) {
if (oldPred == NULL)
{
buffer = ReadBuffer(index, P_NEW);
RTInitBuffer(buffer, F_LEAF);
WriteBuffer(buffer);
@ -122,18 +138,20 @@ rtbuild(Relation heap,
/* init the tuple descriptors and get set for a heap scan */
hd = RelationGetTupleDescriptor(heap);
id = RelationGetTupleDescriptor(index);
d = (Datum *)palloc(natts * sizeof (*d));
nulls = (bool *)palloc(natts * sizeof (*nulls));
d = (Datum *) palloc(natts * sizeof(*d));
nulls = (bool *) palloc(natts * sizeof(*nulls));
/*
* If this is a predicate (partial) index, we will need to evaluate the
* predicate using ExecQual, which requires the current tuple to be in a
* slot of a TupleTable. In addition, ExecQual must have an ExprContext
* referring to that slot. Here, we initialize dummy TupleTable and
* ExprContext objects for this purpose. --Nels, Feb '92
* If this is a predicate (partial) index, we will need to evaluate
* the predicate using ExecQual, which requires the current tuple to
* be in a slot of a TupleTable. In addition, ExecQual must have an
* ExprContext referring to that slot. Here, we initialize dummy
* TupleTable and ExprContext objects for this purpose. --Nels, Feb
* '92
*/
#ifndef OMIT_PARTIAL_INDEX
if (pred != NULL || oldPred != NULL) {
if (pred != NULL || oldPred != NULL)
{
tupleTable = ExecCreateTupleTable(1);
slot = ExecAllocTableSlot(tupleTable);
econtext = makeNode(ExprContext);
@ -152,7 +170,8 @@ rtbuild(Relation heap,
/* count the tuples as we insert them */
nh = ni = 0;
for (; HeapTupleIsValid(htup); htup = heap_getnext(scan, 0, &buffer)) {
for (; HeapTupleIsValid(htup); htup = heap_getnext(scan, 0, &buffer))
{
nh++;
@ -160,23 +179,29 @@ rtbuild(Relation heap,
* If oldPred != NULL, this is an EXTEND INDEX command, so skip
* this tuple if it was already in the existing partial index
*/
if (oldPred != NULL) {
if (oldPred != NULL)
{
#ifndef OMIT_PARTIAL_INDEX
/*SetSlotContents(slot, htup); */
/* SetSlotContents(slot, htup); */
slot->val = htup;
if (ExecQual((List*)oldPred, econtext) == true) {
if (ExecQual((List *) oldPred, econtext) == true)
{
ni++;
continue;
}
#endif /* OMIT_PARTIAL_INDEX */
}
/* Skip this tuple if it doesn't satisfy the partial-index predicate */
if (pred != NULL) {
/*
* Skip this tuple if it doesn't satisfy the partial-index
* predicate
*/
if (pred != NULL)
{
#ifndef OMIT_PARTIAL_INDEX
/*SetSlotContents(slot, htup); */
/* SetSlotContents(slot, htup); */
slot->val = htup;
if (ExecQual((List*)pred, econtext) == false)
if (ExecQual((List *) pred, econtext) == false)
continue;
#endif /* OMIT_PARTIAL_INDEX */
}
@ -184,23 +209,25 @@ rtbuild(Relation heap,
ni++;
/*
* For the current heap tuple, extract all the attributes
* we use in this index, and note which are null.
* For the current heap tuple, extract all the attributes we use
* in this index, and note which are null.
*/
for (i = 1; i <= natts; i++) {
for (i = 1; i <= natts; i++)
{
int attoff;
bool attnull;
/*
* Offsets are from the start of the tuple, and are
* zero-based; indices are one-based. The next call
* returns i - 1. That's data hiding for you.
* zero-based; indices are one-based. The next call returns i
* - 1. That's data hiding for you.
*/
attoff = AttrNumberGetAttrOffset(i);
/*
d[attoff] = HeapTupleGetAttributeValue(htup, buffer,
* d[attoff] = HeapTupleGetAttributeValue(htup, buffer,
*/
d[attoff] = GetIndexValue(htup,
hd,
@ -217,12 +244,11 @@ rtbuild(Relation heap,
itup->t_tid = htup->t_ctid;
/*
* Since we already have the index relation locked, we
* call rtdoinsert directly. Normal access method calls
* dispatch through rtinsert, which locks the relation
* for write. This is the right thing to do if you're
* inserting single tups, but not when you're initializing
* the whole index at once.
* Since we already have the index relation locked, we call
* rtdoinsert directly. Normal access method calls dispatch
* through rtinsert, which locks the relation for write. This is
* the right thing to do if you're inserting single tups, but not
* when you're initializing the whole index at once.
*/
res = rtdoinsert(index, itup, &rtState);
@ -234,7 +260,8 @@ rtbuild(Relation heap,
heap_endscan(scan);
RelationUnsetLockForWrite(index);
if (pred != NULL || oldPred != NULL) {
if (pred != NULL || oldPred != NULL)
{
#ifndef OMIT_PARTIAL_INDEX
ExecDestroyTupleTable(tupleTable, true);
pfree(econtext);
@ -242,14 +269,13 @@ rtbuild(Relation heap,
}
/*
* Since we just counted the tuples in the heap, we update its
* stats in pg_relation to guarantee that the planner takes
* advantage of the index we just created. UpdateStats() does a
* CommandCounterIncrement(), which flushes changed entries from
* the system relcache. The act of constructing an index changes
* these heap and index tuples in the system catalogs, so they
* need to be flushed. We close them to guarantee that they
* will be.
* Since we just counted the tuples in the heap, we update its stats
* in pg_relation to guarantee that the planner takes advantage of the
* index we just created. UpdateStats() does a
* CommandCounterIncrement(), which flushes changed entries from the
* system relcache. The act of constructing an index changes these
* heap and index tuples in the system catalogs, so they need to be
* flushed. We close them to guarantee that they will be.
*/
hrelid = heap->rd_id;
@ -260,8 +286,10 @@ rtbuild(Relation heap,
UpdateStats(hrelid, nh, true);
UpdateStats(irelid, ni, false);
if (oldPred != NULL) {
if (ni == nh) pred = NULL;
if (oldPred != NULL)
{
if (ni == nh)
pred = NULL;
UpdateIndexPredicate(irelid, oldPred, pred);
}
@ -277,7 +305,7 @@ rtbuild(Relation heap,
* It doesn't do any work; just locks the relation and passes the buck.
*/
InsertIndexResult
rtinsert(Relation r, Datum *datum, char *nulls, ItemPointer ht_ctid, Relation heapRel)
rtinsert(Relation r, Datum * datum, char *nulls, ItemPointer ht_ctid, Relation heapRel)
{
InsertIndexResult res;
IndexTuple itup;
@ -296,7 +324,7 @@ rtinsert(Relation r, Datum *datum, char *nulls, ItemPointer ht_ctid, Relation he
}
static InsertIndexResult
rtdoinsert(Relation r, IndexTuple itup, RTSTATE *rtstate)
rtdoinsert(Relation r, IndexTuple itup, RTSTATE * rtstate)
{
Page page;
Buffer buffer;
@ -312,7 +340,8 @@ rtdoinsert(Relation r, IndexTuple itup, RTSTATE *rtstate)
buffer = InvalidBuffer;
stack = (RTSTACK *) NULL;
do {
do
{
/* let go of current buffer before getting next */
if (buffer != InvalidBuffer)
ReleaseBuffer(buffer);
@ -322,7 +351,8 @@ rtdoinsert(Relation r, IndexTuple itup, RTSTATE *rtstate)
page = (Page) BufferGetPage(buffer);
opaque = (RTreePageOpaque) PageGetSpecialPointer(page);
if (!(opaque->flags & F_LEAF)) {
if (!(opaque->flags & F_LEAF))
{
RTSTACK *n;
ItemId iid;
@ -338,7 +368,8 @@ rtdoinsert(Relation r, IndexTuple itup, RTSTATE *rtstate)
}
} while (!(opaque->flags & F_LEAF));
if (nospace(page, itup)) {
if (nospace(page, itup))
{
/* need to do a split */
res = dosplit(r, buffer, stack, itup, rtstate);
freestack(stack);
@ -347,11 +378,14 @@ rtdoinsert(Relation r, IndexTuple itup, RTSTATE *rtstate)
}
/* add the item and write the buffer */
if (PageIsEmpty(page)) {
if (PageIsEmpty(page))
{
l = PageAddItem(page, (Item) itup, IndexTupleSize(itup),
FirstOffsetNumber,
LP_USED);
} else {
}
else
{
l = PageAddItem(page, (Item) itup, IndexTupleSize(itup),
OffsetNumberNext(PageGetMaxOffsetNumber(page)),
LP_USED);
@ -375,15 +409,16 @@ rtdoinsert(Relation r, IndexTuple itup, RTSTATE *rtstate)
static void
rttighten(Relation r,
RTSTACK *stk,
RTSTACK * stk,
char *datum,
int att_size,
RTSTATE *rtstate)
RTSTATE * rtstate)
{
char *oldud;
char *tdatum;
Page p;
float old_size, newd_size;
float old_size,
newd_size;
Buffer b;
if (stk == (RTSTACK *) NULL)
@ -395,22 +430,27 @@ rttighten(Relation r,
oldud = (char *) PageGetItem(p, PageGetItemId(p, stk->rts_child));
oldud += sizeof(IndexTupleData);
(*rtstate->sizeFn)(oldud, &old_size);
datum = (char *) (*rtstate->unionFn)(oldud, datum);
(*rtstate->sizeFn) (oldud, &old_size);
datum = (char *) (*rtstate->unionFn) (oldud, datum);
(*rtstate->sizeFn)(datum, &newd_size);
(*rtstate->sizeFn) (datum, &newd_size);
if (newd_size != old_size) {
if (newd_size != old_size)
{
TupleDesc td = RelationGetTupleDescriptor(r);
if (td->attrs[0]->attlen < 0) {
if (td->attrs[0]->attlen < 0)
{
/*
* This is an internal page, so 'oldud' had better be a
* union (constant-length) key, too. (See comment below.)
* This is an internal page, so 'oldud' had better be a union
* (constant-length) key, too. (See comment below.)
*/
Assert(VARSIZE(datum) == VARSIZE(oldud));
memmove(oldud, datum, VARSIZE(datum));
} else {
}
else
{
memmove(oldud, datum, att_size);
}
WriteBuffer(b);
@ -418,14 +458,16 @@ rttighten(Relation r,
/*
* The user may be defining an index on variable-sized data (like
* polygons). If so, we need to get a constant-sized datum for
* insertion on the internal page. We do this by calling the union
* proc, which is guaranteed to return a rectangle.
* insertion on the internal page. We do this by calling the
* union proc, which is guaranteed to return a rectangle.
*/
tdatum = (char *) (*rtstate->unionFn)(datum, datum);
tdatum = (char *) (*rtstate->unionFn) (datum, datum);
rttighten(r, stk->rts_parent, tdatum, att_size, rtstate);
pfree(tdatum);
} else {
}
else
{
ReleaseBuffer(b);
}
pfree(datum);
@ -441,20 +483,25 @@ rttighten(Relation r,
static InsertIndexResult
dosplit(Relation r,
Buffer buffer,
RTSTACK *stack,
RTSTACK * stack,
IndexTuple itup,
RTSTATE *rtstate)
RTSTATE * rtstate)
{
Page p;
Buffer leftbuf, rightbuf;
Page left, right;
Buffer leftbuf,
rightbuf;
Page left,
right;
ItemId itemid;
IndexTuple item;
IndexTuple ltup, rtup;
IndexTuple ltup,
rtup;
OffsetNumber maxoff;
OffsetNumber i;
OffsetNumber leftoff, rightoff;
BlockNumber lbknum, rbknum;
OffsetNumber leftoff,
rightoff;
BlockNumber lbknum,
rbknum;
BlockNumber bufblock;
RTreePageOpaque opaque;
int blank;
@ -470,17 +517,20 @@ dosplit(Relation r,
opaque = (RTreePageOpaque) PageGetSpecialPointer(p);
/*
* The root of the tree is the first block in the relation. If
* we're about to split the root, we need to do some hocus-pocus
* to enforce this guarantee.
* The root of the tree is the first block in the relation. If we're
* about to split the root, we need to do some hocus-pocus to enforce
* this guarantee.
*/
if (BufferGetBlockNumber(buffer) == P_ROOT) {
if (BufferGetBlockNumber(buffer) == P_ROOT)
{
leftbuf = ReadBuffer(r, P_NEW);
RTInitBuffer(leftbuf, opaque->flags);
lbknum = BufferGetBlockNumber(leftbuf);
left = (Page) BufferGetPage(leftbuf);
} else {
}
else
{
leftbuf = buffer;
IncrBufferRefCount(buffer);
lbknum = BufferGetBlockNumber(buffer);
@ -496,16 +546,20 @@ dosplit(Relation r,
leftoff = rightoff = FirstOffsetNumber;
maxoff = PageGetMaxOffsetNumber(p);
for (i = FirstOffsetNumber; i <= maxoff; i = OffsetNumberNext(i)) {
for (i = FirstOffsetNumber; i <= maxoff; i = OffsetNumberNext(i))
{
itemid = PageGetItemId(p, i);
item = (IndexTuple) PageGetItem(p, itemid);
if (i == *(v.spl_left)) {
if (i == *(v.spl_left))
{
PageAddItem(left, (Item) item, IndexTupleSize(item),
leftoff, LP_USED);
leftoff = OffsetNumberNext(leftoff);
v.spl_left++; /* advance in left split vector */
} else {
}
else
{
PageAddItem(right, (Item) item, IndexTupleSize(item),
rightoff, LP_USED);
rightoff = OffsetNumberNext(rightoff);
@ -517,19 +571,23 @@ dosplit(Relation r,
res = (InsertIndexResult) palloc(sizeof(InsertIndexResultData));
/* now insert the new index tuple */
if (*(v.spl_left) != FirstOffsetNumber) {
if (*(v.spl_left) != FirstOffsetNumber)
{
PageAddItem(left, (Item) itup, IndexTupleSize(itup),
leftoff, LP_USED);
leftoff = OffsetNumberNext(leftoff);
ItemPointerSet(&(res->pointerData), lbknum, leftoff);
} else {
}
else
{
PageAddItem(right, (Item) itup, IndexTupleSize(itup),
rightoff, LP_USED);
rightoff = OffsetNumberNext(rightoff);
ItemPointerSet(&(res->pointerData), rbknum, rightoff);
}
if ((bufblock = BufferGetBlockNumber(buffer)) != P_ROOT) {
if ((bufblock = BufferGetBlockNumber(buffer)) != P_ROOT)
{
PageRestoreTempPage(left, p);
}
WriteBuffer(leftbuf);
@ -538,18 +596,17 @@ dosplit(Relation r,
/*
* Okay, the page is split. We have three things left to do:
*
* 1) Adjust any active scans on this index to cope with changes
* we introduced in its structure by splitting this page.
* 1) Adjust any active scans on this index to cope with changes we
* introduced in its structure by splitting this page.
*
* 2) "Tighten" the bounding box of the pointer to the left
* page in the parent node in the tree, if any. Since we
* moved a bunch of stuff off the left page, we expect it
* to get smaller. This happens in the internal insertion
* routine.
* 2) "Tighten" the bounding box of the pointer to the left page in the
* parent node in the tree, if any. Since we moved a bunch of stuff
* off the left page, we expect it to get smaller. This happens in
* the internal insertion routine.
*
* 3) Insert a pointer to the right page in the parent. This
* may cause the parent to split. If it does, we need to
* repeat steps one and two for each split node in the tree.
* 3) Insert a pointer to the right page in the parent. This may cause
* the parent to split. If it does, we need to repeat steps one and
* two for each split node in the tree.
*/
/* adjust active scans */
@ -557,9 +614,9 @@ dosplit(Relation r,
tupDesc = r->rd_att;
ltup = (IndexTuple) index_formtuple(tupDesc,
(Datum *) &(v.spl_ldatum), isnull);
(Datum *) & (v.spl_ldatum), isnull);
rtup = (IndexTuple) index_formtuple(tupDesc,
(Datum *) &(v.spl_rdatum), isnull);
(Datum *) & (v.spl_rdatum), isnull);
pfree(isnull);
/* set pointers to new child pages in the internal index tuples */
@ -576,18 +633,21 @@ dosplit(Relation r,
static void
rtintinsert(Relation r,
RTSTACK *stk,
RTSTACK * stk,
IndexTuple ltup,
IndexTuple rtup,
RTSTATE *rtstate)
RTSTATE * rtstate)
{
IndexTuple old;
Buffer b;
Page p;
char *ldatum, *rdatum, *newdatum;
char *ldatum,
*rdatum,
*newdatum;
InsertIndexResult res;
if (stk == (RTSTACK *) NULL) {
if (stk == (RTSTACK *) NULL)
{
rtnewroot(r, ltup, rtup);
return;
}
@ -597,32 +657,36 @@ rtintinsert(Relation r,
old = (IndexTuple) PageGetItem(p, PageGetItemId(p, stk->rts_child));
/*
* This is a hack. Right now, we force rtree keys to be constant size.
* To fix this, need delete the old key and add both left and right
* for the two new pages. The insertion of left may force a split if
* the new left key is bigger than the old key.
* This is a hack. Right now, we force rtree keys to be constant
* size. To fix this, need delete the old key and add both left and
* right for the two new pages. The insertion of left may force a
* split if the new left key is bigger than the old key.
*/
if (IndexTupleSize(old) != IndexTupleSize(ltup))
elog(WARN, "Variable-length rtree keys are not supported.");
/* install pointer to left child */
memmove(old, ltup,IndexTupleSize(ltup));
memmove(old, ltup, IndexTupleSize(ltup));
if (nospace(p, rtup)) {
if (nospace(p, rtup))
{
newdatum = (((char *) ltup) + sizeof(IndexTupleData));
rttighten(r, stk->rts_parent, newdatum,
(IndexTupleSize(ltup) - sizeof(IndexTupleData)), rtstate);
res = dosplit(r, b, stk->rts_parent, rtup, rtstate);
WriteBuffer(b); /* don't forget to release buffer! - 01/31/94 */
WriteBuffer(b); /* don't forget to release buffer! -
* 01/31/94 */
pfree(res);
} else {
}
else
{
PageAddItem(p, (Item) rtup, IndexTupleSize(rtup),
PageGetMaxOffsetNumber(p), LP_USED);
WriteBuffer(b);
ldatum = (((char *) ltup) + sizeof(IndexTupleData));
rdatum = (((char *) rtup) + sizeof(IndexTupleData));
newdatum = (char *) (*rtstate->unionFn)(ldatum, rdatum);
newdatum = (char *) (*rtstate->unionFn) (ldatum, rdatum);
rttighten(r, stk->rts_parent, newdatum,
(IndexTupleSize(rtup) - sizeof(IndexTupleData)), rtstate);
@ -650,24 +714,37 @@ rtnewroot(Relation r, IndexTuple lt, IndexTuple rt)
static void
picksplit(Relation r,
Page page,
SPLITVEC *v,
SPLITVEC * v,
IndexTuple itup,
RTSTATE *rtstate)
RTSTATE * rtstate)
{
OffsetNumber maxoff;
OffsetNumber i, j;
IndexTuple item_1, item_2;
char *datum_alpha, *datum_beta;
char *datum_l, *datum_r;
char *union_d, *union_dl, *union_dr;
OffsetNumber i,
j;
IndexTuple item_1,
item_2;
char *datum_alpha,
*datum_beta;
char *datum_l,
*datum_r;
char *union_d,
*union_dl,
*union_dr;
char *inter_d;
bool firsttime;
float size_alpha, size_beta, size_union, size_inter;
float size_waste, waste;
float size_l, size_r;
float size_alpha,
size_beta,
size_union,
size_inter;
float size_waste,
waste;
float size_l,
size_r;
int nbytes;
OffsetNumber seed_1 = 0, seed_2 = 0;
OffsetNumber *left, *right;
OffsetNumber seed_1 = 0,
seed_2 = 0;
OffsetNumber *left,
*right;
maxoff = PageGetMaxOffsetNumber(page);
@ -678,18 +755,20 @@ picksplit(Relation r,
firsttime = true;
waste = 0.0;
for (i = FirstOffsetNumber; i < maxoff; i = OffsetNumberNext(i)) {
for (i = FirstOffsetNumber; i < maxoff; i = OffsetNumberNext(i))
{
item_1 = (IndexTuple) PageGetItem(page, PageGetItemId(page, i));
datum_alpha = ((char *) item_1) + sizeof(IndexTupleData);
for (j = OffsetNumberNext(i); j <= maxoff; j = OffsetNumberNext(j)) {
for (j = OffsetNumberNext(i); j <= maxoff; j = OffsetNumberNext(j))
{
item_2 = (IndexTuple) PageGetItem(page, PageGetItemId(page, j));
datum_beta = ((char *) item_2) + sizeof(IndexTupleData);
/* compute the wasted space by unioning these guys */
union_d = (char *)(rtstate->unionFn)(datum_alpha, datum_beta);
(rtstate->sizeFn)(union_d, &size_union);
inter_d = (char *)(rtstate->interFn)(datum_alpha, datum_beta);
(rtstate->sizeFn)(inter_d, &size_inter);
union_d = (char *) (rtstate->unionFn) (datum_alpha, datum_beta);
(rtstate->sizeFn) (union_d, &size_union);
inter_d = (char *) (rtstate->interFn) (datum_alpha, datum_beta);
(rtstate->sizeFn) (inter_d, &size_inter);
size_waste = size_union - size_inter;
pfree(union_d);
@ -698,11 +777,12 @@ picksplit(Relation r,
pfree(inter_d);
/*
* are these a more promising split that what we've
* already seen?
* are these a more promising split that what we've already
* seen?
*/
if (size_waste > waste || firsttime) {
if (size_waste > waste || firsttime)
{
waste = size_waste;
seed_1 = i;
seed_2 = j;
@ -718,67 +798,76 @@ picksplit(Relation r,
item_1 = (IndexTuple) PageGetItem(page, PageGetItemId(page, seed_1));
datum_alpha = ((char *) item_1) + sizeof(IndexTupleData);
datum_l = (char *)(*rtstate->unionFn)(datum_alpha, datum_alpha);
(*rtstate->sizeFn)(datum_l, &size_l);
datum_l = (char *) (*rtstate->unionFn) (datum_alpha, datum_alpha);
(*rtstate->sizeFn) (datum_l, &size_l);
item_2 = (IndexTuple) PageGetItem(page, PageGetItemId(page, seed_2));
datum_beta = ((char *) item_2) + sizeof(IndexTupleData);
datum_r = (char *)(*rtstate->unionFn)(datum_beta, datum_beta);
(*rtstate->sizeFn)(datum_r, &size_r);
datum_r = (char *) (*rtstate->unionFn) (datum_beta, datum_beta);
(*rtstate->sizeFn) (datum_r, &size_r);
/*
* Now split up the regions between the two seeds. An important
* property of this split algorithm is that the split vector v
* has the indices of items to be split in order in its left and
* right vectors. We exploit this property by doing a merge in
* the code that actually splits the page.
* property of this split algorithm is that the split vector v has the
* indices of items to be split in order in its left and right
* vectors. We exploit this property by doing a merge in the code
* that actually splits the page.
*
* For efficiency, we also place the new index tuple in this loop.
* This is handled at the very end, when we have placed all the
* existing tuples and i == maxoff + 1.
* For efficiency, we also place the new index tuple in this loop. This
* is handled at the very end, when we have placed all the existing
* tuples and i == maxoff + 1.
*/
maxoff = OffsetNumberNext(maxoff);
for (i = FirstOffsetNumber; i <= maxoff; i = OffsetNumberNext(i)) {
for (i = FirstOffsetNumber; i <= maxoff; i = OffsetNumberNext(i))
{
/*
* If we've already decided where to place this item, just
* put it on the right list. Otherwise, we need to figure
* out which page needs the least enlargement in order to
* store the item.
* If we've already decided where to place this item, just put it
* on the right list. Otherwise, we need to figure out which page
* needs the least enlargement in order to store the item.
*/
if (i == seed_1) {
if (i == seed_1)
{
*left++ = i;
v->spl_nleft++;
continue;
} else if (i == seed_2) {
}
else if (i == seed_2)
{
*right++ = i;
v->spl_nright++;
continue;
}
/* okay, which page needs least enlargement? */
if (i == maxoff) {
if (i == maxoff)
{
item_1 = itup;
} else {
}
else
{
item_1 = (IndexTuple) PageGetItem(page, PageGetItemId(page, i));
}
datum_alpha = ((char *) item_1) + sizeof(IndexTupleData);
union_dl = (char *)(*rtstate->unionFn)(datum_l, datum_alpha);
union_dr = (char *)(*rtstate->unionFn)(datum_r, datum_alpha);
(*rtstate->sizeFn)(union_dl, &size_alpha);
(*rtstate->sizeFn)(union_dr, &size_beta);
union_dl = (char *) (*rtstate->unionFn) (datum_l, datum_alpha);
union_dr = (char *) (*rtstate->unionFn) (datum_r, datum_alpha);
(*rtstate->sizeFn) (union_dl, &size_alpha);
(*rtstate->sizeFn) (union_dr, &size_beta);
/* pick which page to add it to */
if (size_alpha - size_l < size_beta - size_r) {
if (size_alpha - size_l < size_beta - size_r)
{
pfree(datum_l);
pfree(union_dr);
datum_l = union_dl;
size_l = size_alpha;
*left++ = i;
v->spl_nleft++;
} else {
}
else
{
pfree(datum_r);
pfree(union_dl);
datum_r = union_dr;
@ -811,13 +900,15 @@ RTInitBuffer(Buffer b, uint32 f)
}
static OffsetNumber
choose(Relation r, Page p, IndexTuple it, RTSTATE *rtstate)
choose(Relation r, Page p, IndexTuple it, RTSTATE * rtstate)
{
OffsetNumber maxoff;
OffsetNumber i;
char *ud, *id;
char *ud,
*id;
char *datum;
float usize, dsize;
float usize,
dsize;
OffsetNumber which;
float which_grow;
@ -826,14 +917,16 @@ choose(Relation r, Page p, IndexTuple it, RTSTATE *rtstate)
which_grow = -1.0;
which = -1;
for (i = FirstOffsetNumber; i <= maxoff; i = OffsetNumberNext(i)) {
for (i = FirstOffsetNumber; i <= maxoff; i = OffsetNumberNext(i))
{
datum = (char *) PageGetItem(p, PageGetItemId(p, i));
datum += sizeof(IndexTupleData);
(*rtstate->sizeFn)(datum, &dsize);
ud = (char *) (*rtstate->unionFn)(datum, id);
(*rtstate->sizeFn)(ud, &usize);
(*rtstate->sizeFn) (datum, &dsize);
ud = (char *) (*rtstate->unionFn) (datum, id);
(*rtstate->sizeFn) (ud, &usize);
pfree(ud);
if (which_grow < 0 || usize - dsize < which_grow) {
if (which_grow < 0 || usize - dsize < which_grow)
{
which = i;
which_grow = usize - dsize;
if (which_grow == 0)
@ -851,11 +944,12 @@ nospace(Page p, IndexTuple it)
}
void
freestack(RTSTACK *s)
freestack(RTSTACK * s)
{
RTSTACK *p;
while (s != (RTSTACK *) NULL) {
while (s != (RTSTACK *) NULL)
{
p = s->rts_parent;
pfree(s);
s = p;
@ -891,9 +985,12 @@ rtdelete(Relation r, ItemPointer tid)
return ((char *) NULL);
}
static void initRtstate(RTSTATE *rtstate, Relation index)
static void
initRtstate(RTSTATE * rtstate, Relation index)
{
RegProcedure union_proc, size_proc, inter_proc;
RegProcedure union_proc,
size_proc,
inter_proc;
func_ptr user_fn;
int pronargs;
@ -916,7 +1013,8 @@ _rtdump(Relation r)
{
Buffer buf;
Page page;
OffsetNumber offnum, maxoff;
OffsetNumber offnum,
maxoff;
BlockNumber blkno;
BlockNumber nblocks;
RTreePageOpaque po;
@ -927,7 +1025,8 @@ _rtdump(Relation r)
char *itkey;
nblocks = RelationGetNumberOfBlocks(r);
for (blkno = 0; blkno < nblocks; blkno++) {
for (blkno = 0; blkno < nblocks; blkno++)
{
buf = ReadBuffer(r, blkno);
page = BufferGetPage(buf);
po = (RTreePageOpaque) PageGetSpecialPointer(page);
@ -935,14 +1034,16 @@ _rtdump(Relation r)
printf("Page %d maxoff %d <%s>\n", blkno, maxoff,
(po->flags & F_LEAF ? "LEAF" : "INTERNAL"));
if (PageIsEmpty(page)) {
if (PageIsEmpty(page))
{
ReleaseBuffer(buf);
continue;
}
for (offnum = FirstOffsetNumber;
offnum <= maxoff;
offnum = OffsetNumberNext(offnum)) {
offnum = OffsetNumberNext(offnum))
{
itup = (IndexTuple) PageGetItem(page, PageGetItemId(page, offnum));
itblkno = ItemPointerGetBlockNumber(&(itup->t_tid));
itoffno = ItemPointerGetOffsetNumber(&(itup->t_tid));
@ -957,5 +1058,5 @@ _rtdump(Relation r)
ReleaseBuffer(buf);
}
}
#endif /* defined RTDEBUG */
#endif /* defined RTDEBUG */

View File

@ -7,7 +7,7 @@
*
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/access/rtree/Attic/rtscan.c,v 1.10 1997/05/20 10:29:30 vadim Exp $
* $Header: /cvsroot/pgsql/src/backend/access/rtree/Attic/rtscan.c,v 1.11 1997/09/07 04:39:24 momjian Exp $
*
*-------------------------------------------------------------------------
*/
@ -21,20 +21,23 @@
#include <access/rtree.h>
#include <access/rtstrat.h>
#ifndef HAVE_MEMMOVE
# include <regex/utils.h>
#include <regex/utils.h>
#else
# include <string.h>
#include <string.h>
#endif
/* routines defined and used here */
static void rtregscan(IndexScanDesc s);
static void rtdropscan(IndexScanDesc s);
static void rtadjone(IndexScanDesc s, int op, BlockNumber blkno,
static void
rtadjone(IndexScanDesc s, int op, BlockNumber blkno,
OffsetNumber offnum);
static void adjuststack(RTSTACK *stk, BlockNumber blkno,
static void
adjuststack(RTSTACK * stk, BlockNumber blkno,
OffsetNumber offnum);
static void adjustiptr(IndexScanDesc s, ItemPointer iptr,
static void
adjustiptr(IndexScanDesc s, ItemPointer iptr,
int op, BlockNumber blkno, OffsetNumber offnum);
/*
@ -47,7 +50,8 @@ static void adjustiptr(IndexScanDesc s, ItemPointer iptr,
* locks on the same object, so that's why we need to handle this case.
*/
typedef struct RTScanListData {
typedef struct RTScanListData
{
IndexScanDesc rtsl_scan;
struct RTScanListData *rtsl_next;
} RTScanListData;
@ -79,7 +83,8 @@ rtrescan(IndexScanDesc s, bool fromEnd, ScanKey key)
RegProcedure internal_proc;
int i;
if (!IndexScanIsValid(s)) {
if (!IndexScanIsValid(s))
{
elog(WARN, "rtrescan: invalid scan.");
return;
}
@ -98,24 +103,31 @@ rtrescan(IndexScanDesc s, bool fromEnd, ScanKey key)
/*
* Set flags.
*/
if (RelationGetNumberOfBlocks(s->relation) == 0) {
if (RelationGetNumberOfBlocks(s->relation) == 0)
{
s->flags = ScanUnmarked;
} else if (fromEnd) {
}
else if (fromEnd)
{
s->flags = ScanUnmarked | ScanUncheckedPrevious;
} else {
}
else
{
s->flags = ScanUnmarked | ScanUncheckedNext;
}
s->scanFromEnd = fromEnd;
if (s->numberOfKeys > 0) {
if (s->numberOfKeys > 0)
{
memmove(s->keyData,
key,
s->numberOfKeys * sizeof(ScanKeyData));
}
p = (RTreeScanOpaque) s->opaque;
if (p != (RTreeScanOpaque) NULL) {
if (p != (RTreeScanOpaque) NULL)
{
freestack(p->s_stack);
freestack(p->s_markstk);
p->s_stack = p->s_markstk = (RTSTACK *) NULL;
@ -124,25 +136,29 @@ rtrescan(IndexScanDesc s, bool fromEnd, ScanKey key)
{
p->s_internalKey[i].sk_argument = s->keyData[i].sk_argument;
}
} else {
}
else
{
/* initialize opaque data */
p = (RTreeScanOpaque) palloc(sizeof(RTreeScanOpaqueData));
p->s_stack = p->s_markstk = (RTSTACK *) NULL;
p->s_internalNKey = s->numberOfKeys;
p->s_flags = 0x0;
s->opaque = p;
if (s->numberOfKeys > 0) {
if (s->numberOfKeys > 0)
{
p->s_internalKey =
(ScanKey) palloc(sizeof(ScanKeyData) * s->numberOfKeys);
/*
* Scans on internal pages use different operators than they
* do on leaf pages. For example, if the user wants all boxes
* that exactly match (x1,y1,x2,y2), then on internal pages
* we need to find all boxes that contain (x1,y1,x2,y2).
* that exactly match (x1,y1,x2,y2), then on internal pages we
* need to find all boxes that contain (x1,y1,x2,y2).
*/
for (i = 0; i < s->numberOfKeys; i++) {
for (i = 0; i < s->numberOfKeys; i++)
{
p->s_internalKey[i].sk_argument = s->keyData[i].sk_argument;
internal_proc = RTMapOperator(s->relation,
s->keyData[i].sk_attno,
@ -161,7 +177,9 @@ void
rtmarkpos(IndexScanDesc s)
{
RTreeScanOpaque p;
RTSTACK *o, *n, *tmp;
RTSTACK *o,
*n,
*tmp;
s->currentMarkData = s->currentItemData;
p = (RTreeScanOpaque) s->opaque;
@ -174,7 +192,8 @@ rtmarkpos(IndexScanDesc s)
n = p->s_stack;
/* copy the parent stack from the current item data */
while (n != (RTSTACK *) NULL) {
while (n != (RTSTACK *) NULL)
{
tmp = (RTSTACK *) palloc(sizeof(RTSTACK));
tmp->rts_child = n->rts_child;
tmp->rts_blk = n->rts_blk;
@ -191,7 +210,9 @@ void
rtrestrpos(IndexScanDesc s)
{
RTreeScanOpaque p;
RTSTACK *o, *n, *tmp;
RTSTACK *o,
*n,
*tmp;
s->currentItemData = s->currentMarkData;
p = (RTreeScanOpaque) s->opaque;
@ -204,7 +225,8 @@ rtrestrpos(IndexScanDesc s)
n = p->s_markstk;
/* copy the parent stack from the current item data */
while (n != (RTSTACK *) NULL) {
while (n != (RTSTACK *) NULL)
{
tmp = (RTSTACK *) palloc(sizeof(RTSTACK));
tmp->rts_child = n->rts_child;
tmp->rts_blk = n->rts_blk;
@ -224,10 +246,11 @@ rtendscan(IndexScanDesc s)
p = (RTreeScanOpaque) s->opaque;
if (p != (RTreeScanOpaque) NULL) {
if (p != (RTreeScanOpaque) NULL)
{
freestack(p->s_stack);
freestack(p->s_markstk);
pfree (s->opaque);
pfree(s->opaque);
}
rtdropscan(s);
@ -255,7 +278,8 @@ rtdropscan(IndexScanDesc s)
for (l = RTScans;
l != (RTScanList) NULL && l->rtsl_scan != s;
l = l->rtsl_next) {
l = l->rtsl_next)
{
prev = l;
}
@ -277,7 +301,8 @@ rtadjscans(Relation r, int op, BlockNumber blkno, OffsetNumber offnum)
Oid relid;
relid = r->rd_id;
for (l = RTScans; l != (RTScanList) NULL; l = l->rtsl_next) {
for (l = RTScans; l != (RTScanList) NULL; l = l->rtsl_next)
{
if (l->rtsl_scan->relation->rd_id == relid)
rtadjone(l->rtsl_scan, op, blkno, offnum);
}
@ -306,7 +331,8 @@ rtadjone(IndexScanDesc s,
so = (RTreeScanOpaque) s->opaque;
if (op == RTOP_SPLIT) {
if (op == RTOP_SPLIT)
{
adjuststack(so->s_stack, blkno, offnum);
adjuststack(so->s_markstk, blkno, offnum);
}
@ -329,20 +355,27 @@ adjustiptr(IndexScanDesc s,
OffsetNumber curoff;
RTreeScanOpaque so;
if (ItemPointerIsValid(iptr)) {
if (ItemPointerGetBlockNumber(iptr) == blkno) {
if (ItemPointerIsValid(iptr))
{
if (ItemPointerGetBlockNumber(iptr) == blkno)
{
curoff = ItemPointerGetOffsetNumber(iptr);
so = (RTreeScanOpaque) s->opaque;
switch (op) {
switch (op)
{
case RTOP_DEL:
/* back up one if we need to */
if (curoff >= offnum) {
if (curoff >= offnum)
{
if (curoff > FirstOffsetNumber) {
if (curoff > FirstOffsetNumber)
{
/* just adjust the item pointer */
ItemPointerSet(iptr, blkno, OffsetNumberPrev(curoff));
} else {
}
else
{
/* remember that we're before the current tuple */
ItemPointerSet(iptr, blkno, FirstOffsetNumber);
if (iptr == &(s->currentItemData))
@ -384,11 +417,12 @@ adjustiptr(IndexScanDesc s,
*/
/*ARGSUSED*/
static void
adjuststack(RTSTACK *stk,
adjuststack(RTSTACK * stk,
BlockNumber blkno,
OffsetNumber offnum)
{
while (stk != (RTSTACK *) NULL) {
while (stk != (RTSTACK *) NULL)
{
if (stk->rts_blk == blkno)
stk->rts_child = FirstOffsetNumber;

View File

@ -7,7 +7,7 @@
*
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/access/rtree/Attic/rtstrat.c,v 1.6 1997/08/19 21:29:52 momjian Exp $
* $Header: /cvsroot/pgsql/src/backend/access/rtree/Attic/rtstrat.c,v 1.7 1997/09/07 04:39:26 momjian Exp $
*
*-------------------------------------------------------------------------
*/
@ -18,7 +18,8 @@
#include <access/rtree.h>
#include <access/istrat.h>
static StrategyNumber RelationGetRTStrategy(Relation r,
static StrategyNumber
RelationGetRTStrategy(Relation r,
AttrNumber attnum, RegProcedure proc);
/*
@ -58,7 +59,7 @@ static StrategyNumber RTNegate[RTNStrategies] = {
InvalidStrategy,
InvalidStrategy,
InvalidStrategy
};
};
/* if a op_1 b, what is the operator op_2 such that b op_2 a? */
static StrategyNumber RTCommute[RTNStrategies] = {
@ -70,7 +71,7 @@ static StrategyNumber RTCommute[RTNStrategies] = {
InvalidStrategy,
InvalidStrategy,
InvalidStrategy
};
};
/* if a op_1 b, what is the operator op_2 such that (b !op_2 a)? */
static StrategyNumber RTNegateCommute[RTNStrategies] = {
@ -82,7 +83,7 @@ static StrategyNumber RTNegateCommute[RTNStrategies] = {
InvalidStrategy,
InvalidStrategy,
InvalidStrategy
};
};
/*
* Now do the TermData arrays. These exist in case the user doesn't give
@ -119,11 +120,11 @@ static StrategyNumber RTNegateCommute[RTNStrategies] = {
/* if you only have "contained-by", how do you determine equality? */
static uint16 RTContainedByTermData[] = {
2, /* make two comparisons */
RTContainedByStrategyNumber, /* use "a contained-by b" */
RTContainedByStrategyNumber,/* use "a contained-by b" */
0x0, /* without any magic */
RTContainedByStrategyNumber, /* then use contained-by, */
RTContainedByStrategyNumber,/* then use contained-by, */
SK_COMMUTE /* swapping a and b */
};
};
/* if you only have "contains", how do you determine equality? */
static uint16 RTContainsTermData[] = {
@ -132,14 +133,14 @@ static uint16 RTContainsTermData[] = {
0x0, /* without any magic */
RTContainsStrategyNumber, /* then use contains again, */
SK_COMMUTE /* swapping a and b */
};
};
/* now put all that together in one place for the planner */
static StrategyTerm RTEqualExpressionData[] = {
(StrategyTerm) RTContainedByTermData,
(StrategyTerm) RTContainsTermData,
NULL
};
};
/*
* If you were sufficiently attentive to detail, you would go through
@ -201,7 +202,7 @@ static StrategyNumber RTOperMap[RTNStrategies] = {
RTContainsStrategyNumber,
RTContainsStrategyNumber,
RTOverlapStrategyNumber
};
};
static StrategyNumber
RelationGetRTStrategy(Relation r,
@ -222,6 +223,7 @@ RelationInvokeRTStrategy(Relation r,
return (RelationInvokeStrategy(r, &RTEvaluationData, attnum, s,
left, right));
}
#endif
RegProcedure

View File

@ -7,7 +7,7 @@
*
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/access/transam/transam.c,v 1.9 1997/08/19 21:29:59 momjian Exp $
* $Header: /cvsroot/pgsql/src/backend/access/transam/transam.c,v 1.10 1997/09/07 04:39:29 momjian Exp $
*
* NOTES
* This file contains the high level access-method interface to the
@ -29,7 +29,8 @@
static int RecoveryCheckingEnabled(void);
static void TransRecover(Relation logRelation);
static bool TransactionLogTest(TransactionId transactionId, XidStatus status);
static void TransactionLogUpdate(TransactionId transactionId,
static void
TransactionLogUpdate(TransactionId transactionId,
XidStatus status);
/* ----------------
@ -113,6 +114,7 @@ SetRecoveryCheckingEnabled(bool state)
{
RecoveryCheckingEnableState = (state == true);
}
#endif
/* ----------------------------------------------------------------
@ -132,7 +134,8 @@ SetRecoveryCheckingEnabled(bool state)
* --------------------------------
*/
static bool /* true/false: does transaction id have specified status? */
static bool /* true/false: does transaction id have
* specified status? */
TransactionLogTest(TransactionId transactionId, /* transaction id to test */
XidStatus status) /* transaction status */
{
@ -145,7 +148,7 @@ TransactionLogTest(TransactionId transactionId, /* transaction id to test */
* as having been committed
* ----------------
*/
if (! RelationIsValid(LogRelation))
if (!RelationIsValid(LogRelation))
return (bool) (status == XID_COMMIT);
/* ----------------
@ -171,7 +174,8 @@ TransactionLogTest(TransactionId transactionId, /* transaction id to test */
transactionId,
&fail);
if (! fail) {
if (!fail)
{
TransactionIdStore(transactionId, &cachedTestXid);
cachedTestXidStatus = xidstatus;
return (bool)
@ -187,7 +191,7 @@ TransactionLogTest(TransactionId transactionId, /* transaction id to test */
/*
* so lint is happy...
*/
return(false);
return (false);
}
/* --------------------------------
@ -200,13 +204,13 @@ TransactionLogUpdate(TransactionId transactionId, /* trans id to update */
{
BlockNumber blockNumber;
bool fail = false; /* success/failure */
AbsoluteTime currentTime; /* time of this transaction */
AbsoluteTime currentTime;/* time of this transaction */
/* ----------------
* during initialization we don't record any updates.
* ----------------
*/
if (! RelationIsValid(LogRelation))
if (!RelationIsValid(LogRelation))
return;
/* ----------------
@ -238,7 +242,8 @@ TransactionLogUpdate(TransactionId transactionId, /* trans id to update */
* (we only record commit times)
* ----------------
*/
if (RelationIsValid(TimeRelation) && status == XID_COMMIT) {
if (RelationIsValid(TimeRelation) && status == XID_COMMIT)
{
TransComputeBlockNumber(TimeRelation, transactionId, &blockNumber);
TransBlockNumberSetCommitTime(TimeRelation,
blockNumber,
@ -268,7 +273,8 @@ TransactionLogUpdate(TransactionId transactionId, /* trans id to update */
*/
AbsoluteTime /* commit time of transaction id */
TransactionIdGetCommitTime(TransactionId transactionId) /* transaction id to test */
TransactionIdGetCommitTime(TransactionId transactionId) /* transaction id to
* test */
{
BlockNumber blockNumber;
AbsoluteTime commitTime; /* commit time */
@ -278,7 +284,7 @@ TransactionIdGetCommitTime(TransactionId transactionId) /* transaction id to tes
* return invalid if we aren't running yet...
* ----------------
*/
if (! RelationIsValid(TimeRelation))
if (!RelationIsValid(TimeRelation))
return INVALID_ABSTIME;
/* ----------------
@ -305,11 +311,13 @@ TransactionIdGetCommitTime(TransactionId transactionId) /* transaction id to tes
* update our cache and return the transaction commit time
* ----------------
*/
if (! fail) {
if (!fail)
{
TransactionIdStore(transactionId, &cachedGetCommitTimeXid);
cachedGetCommitTime = commitTime;
return commitTime;
} else
}
else
return INVALID_ABSTIME;
}
@ -516,7 +524,8 @@ InitializeTransactionLog(void)
* ----------------
*/
SpinAcquire(OidGenLockId);
if (!TransactionIdDidCommit(AmiTransactionId)) {
if (!TransactionIdDidCommit(AmiTransactionId))
{
/* ----------------
* SOMEDAY initialize the information stored in
@ -526,7 +535,9 @@ InitializeTransactionLog(void)
TransactionLogUpdate(AmiTransactionId, XID_COMMIT);
VariableRelationPutNextXid(FirstTransactionId);
} else if (RecoveryCheckingEnabled()) {
}
else if (RecoveryCheckingEnabled())
{
/* ----------------
* if we have a pre-initialized database and if the
* perform recovery checking flag was passed then we
@ -641,10 +652,10 @@ TransactionIdCommit(TransactionId transactionId)
return;
/*
* Within TransactionLogUpdate we call UpdateLastCommited()
* which assumes we have exclusive access to pg_variable.
* Therefore we need to get exclusive access before calling
* TransactionLogUpdate. -mer 18 Aug 1992
* Within TransactionLogUpdate we call UpdateLastCommited() which
* assumes we have exclusive access to pg_variable. Therefore we need
* to get exclusive access before calling TransactionLogUpdate. -mer
* 18 Aug 1992
*/
SpinAcquire(OidGenLockId);
TransactionLogUpdate(transactionId, XID_COMMIT);
@ -681,4 +692,5 @@ TransactionIdSetInProgress(TransactionId transactionId)
TransactionLogUpdate(transactionId, XID_INPROGRESS);
}
#endif

View File

@ -7,7 +7,7 @@
*
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/access/transam/Attic/transsup.c,v 1.9 1997/08/19 21:30:12 momjian Exp $
* $Header: /cvsroot/pgsql/src/backend/access/transam/Attic/transsup.c,v 1.10 1997/09/07 04:39:32 momjian Exp $
*
* NOTES
* This file contains support functions for the high
@ -23,13 +23,17 @@
#include <access/xact.h>
#include <storage/lmgr.h>
static AbsoluteTime TransBlockGetCommitTime(Block tblock,
static AbsoluteTime
TransBlockGetCommitTime(Block tblock,
TransactionId transactionId);
static XidStatus TransBlockGetXidStatus(Block tblock,
static XidStatus
TransBlockGetXidStatus(Block tblock,
TransactionId transactionId);
static void TransBlockSetCommitTime(Block tblock,
static void
TransBlockSetCommitTime(Block tblock,
TransactionId transactionId, AbsoluteTime commitTime);
static void TransBlockSetXidStatus(Block tblock,
static void
TransBlockSetXidStatus(Block tblock,
TransactionId transactionId, XidStatus xstatus);
/* ----------------------------------------------------------------
@ -55,8 +59,9 @@ AmiTransactionOverride(bool flag)
*/
void
TransComputeBlockNumber(Relation relation, /* relation to test */
TransactionId transactionId, /* transaction id to test */
BlockNumber *blockNumberOutP)
TransactionId transactionId, /* transaction id to
* test */
BlockNumber * blockNumberOutP)
{
long itemsPerBlock = 0;
@ -106,7 +111,7 @@ TransComputeBlockNumber(Relation relation, /* relation to test */
static XidStatus
TransBlockGetLastTransactionIdStatus(Block tblock,
TransactionId baseXid,
TransactionId *returnXidP)
TransactionId * returnXidP)
{
Index index;
Index maxIndex;
@ -129,12 +134,13 @@ TransBlockGetLastTransactionIdStatus(Block tblock,
* ----------------
*/
maxIndex = TP_NumXidStatusPerBlock;
for (index = maxIndex; index > 0; index--) {
offset = BitIndexOf(index-1);
for (index = maxIndex; index > 0; index--)
{
offset = BitIndexOf(index - 1);
bit1 = ((bits8) BitArrayBitIsSet((BitArray) tblock, offset++)) << 1;
bit2 = (bits8) BitArrayBitIsSet((BitArray) tblock, offset);
xstatus = (bit1 | bit2) ;
xstatus = (bit1 | bit2);
/* ----------------
* here we have the status of some transaction, so test
@ -142,8 +148,10 @@ TransBlockGetLastTransactionIdStatus(Block tblock,
* we save the transaction id in the place specified by the caller.
* ----------------
*/
if (xstatus != XID_INPROGRESS) {
if (returnXidP != NULL) {
if (xstatus != XID_INPROGRESS)
{
if (returnXidP != NULL)
{
TransactionIdStore(baseXid, returnXidP);
TransactionIdAdd(returnXidP, index - 1);
}
@ -158,7 +166,8 @@ TransBlockGetLastTransactionIdStatus(Block tblock,
* status is "in progress" to know this condition has arisen.
* ----------------
*/
if (index == 0) {
if (index == 0)
{
if (returnXidP != NULL)
TransactionIdStore(baseXid, returnXidP);
}
@ -169,6 +178,7 @@ TransBlockGetLastTransactionIdStatus(Block tblock,
*/
return xstatus;
}
#endif
/* --------------------------------
@ -191,7 +201,8 @@ TransBlockGetXidStatus(Block tblock,
* sanity check
* ----------------
*/
if (tblock == NULL) {
if (tblock == NULL)
{
return XID_INVALID;
}
@ -262,7 +273,8 @@ TransBlockSetXidStatus(Block tblock,
* store the transaction value at the specified offset
* ----------------
*/
switch(xstatus) {
switch (xstatus)
{
case XID_COMMIT: /* set 10 */
BitArraySetBit((BitArray) tblock, offset);
BitArrayClearBit((BitArray) tblock, offset + 1);
@ -322,7 +334,7 @@ TransBlockGetCommitTime(Block tblock,
*/
timeArray = (AbsoluteTime *) tblock;
return (AbsoluteTime)
timeArray[ index ];
timeArray[index];
}
/* --------------------------------
@ -364,7 +376,7 @@ TransBlockSetCommitTime(Block tblock,
* ----------------
*/
timeArray = (AbsoluteTime *) tblock;
timeArray[ index ] = commitTime;
timeArray[index] = commitTime;
}
/* ----------------------------------------------------------------
@ -380,7 +392,7 @@ XidStatus
TransBlockNumberGetXidStatus(Relation relation,
BlockNumber blockNumber,
TransactionId xid,
bool *failP)
bool * failP)
{
Buffer buffer; /* buffer associated with block */
Block block; /* block containing xstatus */
@ -437,7 +449,7 @@ TransBlockNumberSetXidStatus(Relation relation,
BlockNumber blockNumber,
TransactionId xid,
XidStatus xstatus,
bool *failP)
bool * failP)
{
Buffer buffer; /* buffer associated with block */
Block block; /* block containing xstatus */
@ -490,7 +502,7 @@ AbsoluteTime
TransBlockNumberGetCommitTime(Relation relation,
BlockNumber blockNumber,
TransactionId xid,
bool *failP)
bool * failP)
{
Buffer buffer; /* buffer associated with block */
Block block; /* block containing commit time */
@ -551,7 +563,7 @@ TransBlockNumberSetCommitTime(Relation relation,
BlockNumber blockNumber,
TransactionId xid,
AbsoluteTime xtime,
bool *failP)
bool * failP)
{
Buffer buffer; /* buffer associated with block */
Block block; /* block containing commit time */
@ -604,10 +616,11 @@ TransBlockNumberSetCommitTime(Relation relation,
#ifdef NOT_USED
void
TransGetLastRecordedTransaction(Relation relation,
TransactionId xid, /* return: transaction id */
bool *failP)
TransactionId xid, /* return: transaction
* id */
bool * failP)
{
BlockNumber blockNumber; /* block number */
BlockNumber blockNumber;/* block number */
Buffer buffer; /* buffer associated with block */
Block block; /* block containing xid status */
BlockNumber n; /* number of blocks in the relation */
@ -633,7 +646,8 @@ TransGetLastRecordedTransaction(Relation relation,
* ----------------
*/
n = RelationGetNumberOfBlocks(relation);
if (n == 0) {
if (n == 0)
{
(*failP) = true;
return;
}
@ -642,7 +656,7 @@ TransGetLastRecordedTransaction(Relation relation,
* get the block containing the transaction information
* ----------------
*/
blockNumber = n-1;
blockNumber = n - 1;
buffer = ReadBuffer(relation, blockNumber);
block = BufferGetBlock(buffer);
@ -663,4 +677,5 @@ TransGetLastRecordedTransaction(Relation relation,
*/
RelationUnsetLockForRead(relation);
}
#endif

View File

@ -7,7 +7,7 @@
*
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/access/transam/varsup.c,v 1.9 1997/08/19 21:30:16 momjian Exp $
* $Header: /cvsroot/pgsql/src/backend/access/transam/varsup.c,v 1.10 1997/09/07 04:39:35 momjian Exp $
*
*-------------------------------------------------------------------------
*/
@ -20,12 +20,12 @@
#include <access/heapam.h>
#include <catalog/catname.h>
static void GetNewObjectIdBlock(Oid *oid_return, int oid_block_size);
static void VariableRelationGetNextOid(Oid *oid_return);
static void VariableRelationGetNextXid(TransactionId *xidP);
static void GetNewObjectIdBlock(Oid * oid_return, int oid_block_size);
static void VariableRelationGetNextOid(Oid * oid_return);
static void VariableRelationGetNextXid(TransactionId * xidP);
static void VariableRelationPutLastXid(TransactionId xid);
static void VariableRelationPutNextOid(Oid *oidP);
static void VariableRelationGetLastXid(TransactionId *xidP);
static void VariableRelationPutNextOid(Oid * oidP);
static void VariableRelationGetLastXid(TransactionId * xidP);
/* ---------------------
* spin lock for oid generation
@ -43,7 +43,7 @@ int OidGenLockId;
* --------------------------------
*/
static void
VariableRelationGetNextXid(TransactionId *xidP)
VariableRelationGetNextXid(TransactionId * xidP)
{
Buffer buf;
VariableRelationContents var;
@ -58,7 +58,7 @@ VariableRelationGetNextXid(TransactionId *xidP)
* do nothing before things are initialized
* ----------------
*/
if (! RelationIsValid(VariableRelation))
if (!RelationIsValid(VariableRelation))
return;
/* ----------------
@ -68,7 +68,7 @@ VariableRelationGetNextXid(TransactionId *xidP)
*/
buf = ReadBuffer(VariableRelation, 0);
if (! BufferIsValid(buf))
if (!BufferIsValid(buf))
{
SpinRelease(OidGenLockId);
elog(WARN, "VariableRelationGetNextXid: ReadBuffer failed");
@ -85,7 +85,7 @@ VariableRelationGetNextXid(TransactionId *xidP)
* --------------------------------
*/
static void
VariableRelationGetLastXid(TransactionId *xidP)
VariableRelationGetLastXid(TransactionId * xidP)
{
Buffer buf;
VariableRelationContents var;
@ -100,7 +100,7 @@ VariableRelationGetLastXid(TransactionId *xidP)
* do nothing before things are initialized
* ----------------
*/
if (! RelationIsValid(VariableRelation))
if (!RelationIsValid(VariableRelation))
return;
/* ----------------
@ -110,7 +110,7 @@ VariableRelationGetLastXid(TransactionId *xidP)
*/
buf = ReadBuffer(VariableRelation, 0);
if (! BufferIsValid(buf))
if (!BufferIsValid(buf))
{
SpinRelease(OidGenLockId);
elog(WARN, "VariableRelationGetNextXid: ReadBuffer failed");
@ -144,7 +144,7 @@ VariableRelationPutNextXid(TransactionId xid)
* do nothing before things are initialized
* ----------------
*/
if (! RelationIsValid(VariableRelation))
if (!RelationIsValid(VariableRelation))
return;
/* ----------------
@ -154,7 +154,7 @@ VariableRelationPutNextXid(TransactionId xid)
*/
buf = ReadBuffer(VariableRelation, 0);
if (! BufferIsValid(buf))
if (!BufferIsValid(buf))
{
SpinRelease(OidGenLockId);
elog(WARN, "VariableRelationPutNextXid: ReadBuffer failed");
@ -164,9 +164,9 @@ VariableRelationPutNextXid(TransactionId xid)
TransactionIdStore(xid, &(var->nextXidData));
flushmode = SetBufferWriteMode (BUFFER_FLUSH_WRITE);
flushmode = SetBufferWriteMode(BUFFER_FLUSH_WRITE);
WriteBuffer(buf);
SetBufferWriteMode (flushmode);
SetBufferWriteMode(flushmode);
}
/* --------------------------------
@ -189,7 +189,7 @@ VariableRelationPutLastXid(TransactionId xid)
* do nothing before things are initialized
* ----------------
*/
if (! RelationIsValid(VariableRelation))
if (!RelationIsValid(VariableRelation))
return;
/* ----------------
@ -199,7 +199,7 @@ VariableRelationPutLastXid(TransactionId xid)
*/
buf = ReadBuffer(VariableRelation, 0);
if (! BufferIsValid(buf))
if (!BufferIsValid(buf))
{
SpinRelease(OidGenLockId);
elog(WARN, "VariableRelationPutLastXid: ReadBuffer failed");
@ -217,7 +217,7 @@ VariableRelationPutLastXid(TransactionId xid)
* --------------------------------
*/
static void
VariableRelationGetNextOid(Oid *oid_return)
VariableRelationGetNextOid(Oid * oid_return)
{
Buffer buf;
VariableRelationContents var;
@ -235,7 +235,8 @@ VariableRelationGetNextOid(Oid *oid_return)
* should be called instead..
* ----------------
*/
if (! RelationIsValid(VariableRelation)) {
if (!RelationIsValid(VariableRelation))
{
if (PointerIsValid(oid_return))
(*oid_return) = InvalidOid;
return;
@ -248,7 +249,7 @@ VariableRelationGetNextOid(Oid *oid_return)
*/
buf = ReadBuffer(VariableRelation, 0);
if (! BufferIsValid(buf))
if (!BufferIsValid(buf))
{
SpinRelease(OidGenLockId);
elog(WARN, "VariableRelationGetNextXid: ReadBuffer failed");
@ -256,7 +257,8 @@ VariableRelationGetNextOid(Oid *oid_return)
var = (VariableRelationContents) BufferGetBlock(buf);
if (PointerIsValid(oid_return)) {
if (PointerIsValid(oid_return))
{
/* ----------------
* nothing up my sleeve... what's going on here is that this code
@ -285,7 +287,7 @@ VariableRelationGetNextOid(Oid *oid_return)
* --------------------------------
*/
static void
VariableRelationPutNextOid(Oid *oidP)
VariableRelationPutNextOid(Oid * oidP)
{
Buffer buf;
VariableRelationContents var;
@ -300,14 +302,14 @@ VariableRelationPutNextOid(Oid *oidP)
* do nothing before things are initialized
* ----------------
*/
if (! RelationIsValid(VariableRelation))
if (!RelationIsValid(VariableRelation))
return;
/* ----------------
* sanity check
* ----------------
*/
if (! PointerIsValid(oidP))
if (!PointerIsValid(oidP))
{
SpinRelease(OidGenLockId);
elog(WARN, "VariableRelationPutNextOid: invalid oid pointer");
@ -320,7 +322,7 @@ VariableRelationPutNextOid(Oid *oidP)
*/
buf = ReadBuffer(VariableRelation, 0);
if (! BufferIsValid(buf))
if (!BufferIsValid(buf))
{
SpinRelease(OidGenLockId);
elog(WARN, "VariableRelationPutNextOid: ReadBuffer failed");
@ -385,7 +387,7 @@ static int prefetched_xid_count = 0;
static TransactionId next_prefetched_xid;
void
GetNewTransactionId(TransactionId *xid)
GetNewTransactionId(TransactionId * xid)
{
TransactionId nextid;
@ -394,7 +396,8 @@ GetNewTransactionId(TransactionId *xid)
* bootstrap transaction id.
* ----------------
*/
if (AMI_OVERRIDE) {
if (AMI_OVERRIDE)
{
TransactionIdStore(AmiTransactionId, xid);
return;
}
@ -405,7 +408,8 @@ GetNewTransactionId(TransactionId *xid)
* ----------------
*/
if (prefetched_xid_count == 0) {
if (prefetched_xid_count == 0)
{
/* ----------------
* obtain exclusive access to the variable relation page
*
@ -456,8 +460,9 @@ UpdateLastCommittedXid(TransactionId xid)
TransactionId lastid;
/* we assume that spinlock OidGenLockId has been acquired
* prior to entering this function
/*
* we assume that spinlock OidGenLockId has been acquired prior to
* entering this function
*/
/* ----------------
@ -492,7 +497,8 @@ UpdateLastCommittedXid(TransactionId xid)
* ----------------
*/
static void
GetNewObjectIdBlock(Oid *oid_return, /* place to return the new object id */
GetNewObjectIdBlock(Oid * oid_return, /* place to return the new object
* id */
int oid_block_size) /* number of oids desired */
{
Oid nextoid;
@ -552,7 +558,7 @@ static int prefetched_oid_count = 0;
static Oid next_prefetched_oid;
void
GetNewObjectId(Oid *oid_return) /* place to return the new object id */
GetNewObjectId(Oid * oid_return)/* place to return the new object id */
{
/* ----------------
* if we run out of prefetched oids, then we get some
@ -560,7 +566,8 @@ GetNewObjectId(Oid *oid_return) /* place to return the new object id */
* ----------------
*/
if (prefetched_oid_count == 0) {
if (prefetched_oid_count == 0)
{
int oid_block_size = VAR_OID_PREFETCH;
/* ----------------
@ -571,7 +578,7 @@ GetNewObjectId(Oid *oid_return) /* place to return the new object id */
* initialized. This would be bad.
* ----------------
*/
if (! RelationIsValid(VariableRelation))
if (!RelationIsValid(VariableRelation))
VariableRelation = heap_openr(VariableRelationName);
/* ----------------
@ -602,10 +609,11 @@ GetNewObjectId(Oid *oid_return) /* place to return the new object id */
void
CheckMaxObjectId(Oid assigned_oid)
{
Oid pass_oid;
Oid pass_oid;
if (prefetched_oid_count == 0) /* make sure next/max is set, or reload */
if (prefetched_oid_count == 0) /* make sure next/max is set, or
* reload */
GetNewObjectId(&pass_oid);
/* ----------------
@ -656,4 +664,3 @@ Oid pass_oid;
GetNewObjectId(&pass_oid); /* throw away returned oid */
}

View File

@ -7,7 +7,7 @@
*
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/access/transam/xact.c,v 1.13 1997/08/29 09:02:11 vadim Exp $
* $Header: /cvsroot/pgsql/src/backend/access/transam/xact.c,v 1.14 1997/09/07 04:39:38 momjian Exp $
*
* NOTES
* Transaction aborts can now occur two ways:
@ -181,10 +181,10 @@ TransactionStateData CurrentTransactionStateData = {
0x0, /* start time */
TRANS_DEFAULT, /* transaction state */
TBLOCK_DEFAULT /* transaction block state */
};
};
TransactionState CurrentTransactionState =
&CurrentTransactionStateData;
&CurrentTransactionStateData;
/* ----------------
* info returned when the system is disabled
@ -202,9 +202,9 @@ TransactionState CurrentTransactionState =
* V1 transaction system. -cim 3/18/90
* ----------------
*/
TransactionId DisabledTransactionId = (TransactionId)-1;
TransactionId DisabledTransactionId = (TransactionId) - 1;
CommandId DisabledCommandId = (CommandId) -1;
CommandId DisabledCommandId = (CommandId) - 1;
AbsoluteTime DisabledStartTime = (AbsoluteTime) BIG_ABSTIME; /* 1073741823; */
@ -253,6 +253,7 @@ SetTransactionFlushEnabled(bool state)
{
TransactionFlushState = (state == true);
}
#endif
/* --------------------------------
@ -267,18 +268,26 @@ IsTransactionState(void)
{
TransactionState s = CurrentTransactionState;
switch (s->state) {
case TRANS_DEFAULT: return false;
case TRANS_START: return true;
case TRANS_INPROGRESS: return true;
case TRANS_COMMIT: return true;
case TRANS_ABORT: return true;
case TRANS_DISABLED: return false;
switch (s->state)
{
case TRANS_DEFAULT:
return false;
case TRANS_START:
return true;
case TRANS_INPROGRESS:
return true;
case TRANS_COMMIT:
return true;
case TRANS_ABORT:
return true;
case TRANS_DISABLED:
return false;
}
/*
* Shouldn't get here, but lint is not happy with this...
*/
return(false);
return (false);
}
/* --------------------------------
@ -315,13 +324,16 @@ OverrideTransactionSystem(bool flag)
{
TransactionState s = CurrentTransactionState;
if (flag == true) {
if (flag == true)
{
if (s->state == TRANS_DISABLED)
return;
SavedTransactionState = s->state;
s->state = TRANS_DISABLED;
} else {
}
else
{
if (s->state != TRANS_DISABLED)
return;
@ -471,6 +483,7 @@ ClearCommandIdCounterOverflowFlag()
{
CommandIdCounterOverflowFlag = false;
}
#endif
/* --------------------------------
@ -481,7 +494,8 @@ void
CommandCounterIncrement()
{
CurrentTransactionStateData.commandId += 1;
if (CurrentTransactionStateData.commandId == FirstCommandId) {
if (CurrentTransactionStateData.commandId == FirstCommandId)
{
CommandIdCounterOverflowFlag = true;
elog(WARN, "You may only have 65535 commands per transaction");
}
@ -495,7 +509,7 @@ CommandCounterIncrement()
}
void
SetScanCommandId (CommandId savedId)
SetScanCommandId(CommandId savedId)
{
CurrentTransactionStateData.scanCommandId = savedId;
@ -534,11 +548,12 @@ AtStart_Cache()
static void
AtStart_Locks()
{
/*
* at present, it is unknown to me what belongs here -cim 3/18/90
*
* There isn't anything to do at the start of a xact for locks.
* -mer 5/24/92
* There isn't anything to do at the start of a xact for locks. -mer
* 5/24/92
*/
}
@ -603,7 +618,8 @@ RecordTransactionCommit()
*/
leak = BufferPoolCheckLeak();
FlushBufferPool(!TransactionFlushEnabled());
if (leak) ResetBufferPool();
if (leak)
ResetBufferPool();
/* ----------------
* have the transaction access methods record the status
@ -618,7 +634,8 @@ RecordTransactionCommit()
*/
leak = BufferPoolCheckLeak();
FlushBufferPool(!TransactionFlushEnabled());
if (leak) ResetBufferPool();
if (leak)
ResetBufferPool();
}
@ -823,10 +840,10 @@ StartTransaction()
s->state = TRANS_INPROGRESS;
/*
* Let others to know about current transaction is in progress
* - vadim 11/26/96
* Let others to know about current transaction is in progress - vadim
* 11/26/96
*/
if ( MyProc != (PROC*) NULL )
if (MyProc != (PROC *) NULL)
MyProc->xid = s->transactionIdData;
}
@ -872,7 +889,7 @@ CommitTransaction()
* do commit processing
* ----------------
*/
CloseSequences ();
CloseSequences();
DestroyTempRels();
AtEOXact_portals();
RecordTransactionCommit();
@ -893,10 +910,10 @@ CommitTransaction()
}
/*
* Let others to know about no transaction in progress
* - vadim 11/26/96
* Let others to know about no transaction in progress - vadim
* 11/26/96
*/
if ( MyProc != (PROC*) NULL )
if (MyProc != (PROC *) NULL)
MyProc->xid = InvalidTransactionId;
}
@ -911,10 +928,10 @@ AbortTransaction()
TransactionState s = CurrentTransactionState;
/*
* Let others to know about no transaction in progress
* - vadim 11/26/96
* Let others to know about no transaction in progress - vadim
* 11/26/96
*/
if ( MyProc != (PROC*) NULL )
if (MyProc != (PROC *) NULL)
MyProc->xid = InvalidTransactionId;
/* ----------------
@ -938,7 +955,7 @@ AbortTransaction()
* do abort processing
* ----------------
*/
CloseSequences ();
CloseSequences();
AtEOXact_portals();
RecordTransactionAbort();
RelationPurgeLocalRelation(false);
@ -954,10 +971,12 @@ AbortTransaction()
*/
s->state = TRANS_DEFAULT;
{
/* We need to do this in case another process notified us while
we are in the middle of an aborted transaction. We need to
notify our frontend after we finish the current transaction.
-- jw, 1/3/94
/*
* We need to do this in case another process notified us while we
* are in the middle of an aborted transaction. We need to notify
* our frontend after we finish the current transaction. -- jw,
* 1/3/94
*/
if (IsNormalProcessingMode())
Async_NotifyAtAbort();
@ -973,7 +992,8 @@ StartTransactionCommand()
{
TransactionState s = CurrentTransactionState;
switch(s->blockState) {
switch (s->blockState)
{
/* ----------------
* if we aren't in a transaction block, we
* just do our usual start transaction.
@ -1043,6 +1063,7 @@ StartTransactionCommand()
break;
}
}
/* --------------------------------
* CommitTransactionCommand
* --------------------------------
@ -1052,7 +1073,8 @@ CommitTransactionCommand()
{
TransactionState s = CurrentTransactionState;
switch(s->blockState) {
switch (s->blockState)
{
/* ----------------
* if we aren't in a transaction block, we
* just do our usual transaction commit
@ -1087,8 +1109,8 @@ CommitTransactionCommand()
case TBLOCK_INPROGRESS:
CommandCounterIncrement();
#ifdef TBL_FREE_CMD_MEMORY
EndPortalAllocMode ();
StartPortalAllocMode (DefaultAllocMode, 0);
EndPortalAllocMode();
StartPortalAllocMode(DefaultAllocMode, 0);
#endif
break;
@ -1134,7 +1156,8 @@ AbortCurrentTransaction()
{
TransactionState s = CurrentTransactionState;
switch(s->blockState) {
switch (s->blockState)
{
/* ----------------
* if we aren't in a transaction block, we
* just do our usual abort transaction.
@ -1261,7 +1284,8 @@ EndTransactionBlock(void)
if (s->state == TRANS_DISABLED)
return;
if (s->blockState == TBLOCK_INPROGRESS) {
if (s->blockState == TBLOCK_INPROGRESS)
{
/* ----------------
* here we are in a transaction block which should commit
* when we get to the upcoming CommitTransactionCommand()
@ -1274,7 +1298,8 @@ EndTransactionBlock(void)
return;
}
if (s->blockState == TBLOCK_ABORT) {
if (s->blockState == TBLOCK_ABORT)
{
/* ----------------
* here, we are in a transaction block which aborted
* and since the AbortTransaction() was already done,
@ -1316,7 +1341,8 @@ AbortTransactionBlock(void)
if (s->state == TRANS_DISABLED)
return;
if (s->blockState == TBLOCK_INPROGRESS) {
if (s->blockState == TBLOCK_INPROGRESS)
{
/* ----------------
* here we were inside a transaction block something
* screwed up inside the system so we enter the abort state,
@ -1347,6 +1373,7 @@ AbortTransactionBlock(void)
AbortTransaction();
s->blockState = TBLOCK_ENDABORT;
}
#endif
/* --------------------------------
@ -1366,16 +1393,18 @@ UserAbortTransactionBlock()
return;
/*
* if the transaction has already been automatically aborted with an error,
* and the user subsequently types 'abort', allow it. (the behavior is
* the same as if they had typed 'end'.)
* if the transaction has already been automatically aborted with an
* error, and the user subsequently types 'abort', allow it. (the
* behavior is the same as if they had typed 'end'.)
*/
if (s->blockState == TBLOCK_ABORT) {
if (s->blockState == TBLOCK_ABORT)
{
s->blockState = TBLOCK_ENDABORT;
return;
}
if (s->blockState == TBLOCK_INPROGRESS) {
if (s->blockState == TBLOCK_INPROGRESS)
{
/* ----------------
* here we were inside a transaction block and we
* got an abort command from the user, so we move to
@ -1420,7 +1449,8 @@ IsTransactionBlock()
TransactionState s = CurrentTransactionState;
if (s->blockState == TBLOCK_INPROGRESS
|| s->blockState == TBLOCK_ENDABORT) {
|| s->blockState == TBLOCK_ENDABORT)
{
return (true);
}

View File

@ -7,7 +7,7 @@
*
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/access/transam/Attic/xid.c,v 1.7 1997/08/19 21:30:20 momjian Exp $
* $Header: /cvsroot/pgsql/src/backend/access/transam/Attic/xid.c,v 1.8 1997/09/07 04:39:40 momjian Exp $
*
* OLD COMMENTS
* XXX WARNING
@ -39,7 +39,7 @@ extern TransactionId FirstTransactionId;
bool
TransactionIdIsValid(TransactionId transactionId)
{
return ((bool) (transactionId != NullTransactionId) );
return ((bool) (transactionId != NullTransactionId));
}
/* XXX char16 name for catalogs */
@ -50,7 +50,7 @@ xidin(char *representation)
}
/* XXX char16 name for catalogs */
char*
char *
xidout(TransactionId transactionId)
{
/* return(TransactionIdFormString(transactionId)); */
@ -73,7 +73,7 @@ xidout(TransactionId transactionId)
* ----------------------------------------------------------------
*/
void
StoreInvalidTransactionId(TransactionId *destination)
StoreInvalidTransactionId(TransactionId * destination)
{
*destination = NullTransactionId;
}
@ -86,7 +86,7 @@ StoreInvalidTransactionId(TransactionId *destination)
*/
void
TransactionIdStore(TransactionId transactionId,
TransactionId *destination)
TransactionId * destination)
{
*destination = transactionId;
}
@ -108,7 +108,7 @@ TransactionIdEquals(TransactionId id1, TransactionId id2)
bool
TransactionIdIsLessThan(TransactionId id1, TransactionId id2)
{
return ((bool)(id1 < id2));
return ((bool) (id1 < id2));
}
/* ----------------------------------------------------------------
@ -123,7 +123,7 @@ TransactionIdIsLessThan(TransactionId id1, TransactionId id2)
bool
xideq(TransactionId xid1, TransactionId xid2)
{
return( (bool) (xid1 == xid2) );
return ((bool) (xid1 == xid2));
}
@ -134,7 +134,7 @@ xideq(TransactionId xid1, TransactionId xid2)
*/
#ifdef NOT_USED
void
TransactionIdIncrement(TransactionId *transactionId)
TransactionIdIncrement(TransactionId * transactionId)
{
(*transactionId)++;
@ -142,6 +142,7 @@ TransactionIdIncrement(TransactionId *transactionId)
elog(FATAL, "TransactionIdIncrement: exhausted XID's");
return;
}
#endif
/* ----------------------------------------------------------------
@ -149,9 +150,8 @@ TransactionIdIncrement(TransactionId *transactionId)
* ----------------------------------------------------------------
*/
void
TransactionIdAdd(TransactionId *xid, int value)
TransactionIdAdd(TransactionId * xid, int value)
{
*xid += value;
return;
}

View File

@ -7,7 +7,7 @@
* Copyright (c) 1994, Regents of the University of California
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/bootstrap/bootstrap.c,v 1.21 1997/08/19 21:30:24 momjian Exp $
* $Header: /cvsroot/pgsql/src/backend/bootstrap/bootstrap.c,v 1.22 1997/09/07 04:39:49 momjian Exp $
*
*-------------------------------------------------------------------------
*/
@ -69,7 +69,7 @@
#include "access/xact.h"
#ifndef HAVE_MEMMOVE
# include "regex/utils.h"
#include "regex/utils.h"
#endif
#include <string.h>
@ -103,12 +103,12 @@
#define ALLOC(t, c) (t *)calloc((unsigned)(c), sizeof(t))
#define FIRST_TYPE_OID 16 /* OID of the first type */
extern int Int_yyparse (void);
extern int Int_yyparse(void);
static hashnode *AddStr(char *str, int strlength, int mderef);
static AttributeTupleForm AllocateAttribute(void);
static bool BootstrapAlreadySeen(Oid id);
static int CompHash (char *str, int len);
static hashnode *FindStr (char *str, int length, hashnode *mderef);
static int CompHash(char *str, int len);
static hashnode *FindStr(char *str, int length, hashnode * mderef);
static int gettype(char *type);
static void cleanup(void);
@ -134,10 +134,11 @@ static void cleanup(void);
#define NUMSQR 529
#define NUMCUBE 12167
char *strtable [STRTABLESIZE];
hashnode *hashtable [HASHTABLESIZE];
char *strtable[STRTABLESIZE];
hashnode *hashtable[HASHTABLESIZE];
static int strtable_end = -1; /* Tells us last occupied string space */
static int strtable_end = -1; /* Tells us last occupied string
* space */
/*-
* Basic information associated with each type. This is used before
@ -147,7 +148,8 @@ static int strtable_end = -1; /* Tells us last occupied string space */
* (e.g., F_REGPROCIN scans pg_proc). this obviously creates some
* order dependencies in the catalog creation process.
*/
struct typinfo {
struct typinfo
{
char name[NAMEDATALEN];
Oid oid;
Oid elem;
@ -157,36 +159,37 @@ struct typinfo {
};
static struct typinfo Procid[] = {
{ "bool", 16, 0, 1, F_BOOLIN, F_BOOLOUT },
{ "bytea", 17, 0, -1, F_BYTEAIN, F_BYTEAOUT },
{ "char", 18, 0, 1, F_CHARIN, F_CHAROUT },
{ "name", 19, 0, NAMEDATALEN, F_NAMEIN, F_NAMEOUT },
{ "char16", 20, 0, 16, F_CHAR16IN, F_CHAR16OUT},
{"bool", 16, 0, 1, F_BOOLIN, F_BOOLOUT},
{"bytea", 17, 0, -1, F_BYTEAIN, F_BYTEAOUT},
{"char", 18, 0, 1, F_CHARIN, F_CHAROUT},
{"name", 19, 0, NAMEDATALEN, F_NAMEIN, F_NAMEOUT},
{"char16", 20, 0, 16, F_CHAR16IN, F_CHAR16OUT},
/* { "dt", 20, 0, 4, F_DTIN, F_DTOUT}, */
{ "int2", 21, 0, 2, F_INT2IN, F_INT2OUT },
{ "int28", 22, 0, 16, F_INT28IN, F_INT28OUT },
{ "int4", 23, 0, 4, F_INT4IN, F_INT4OUT },
{ "regproc", 24, 0, 4, F_REGPROCIN, F_REGPROCOUT },
{ "text", 25, 0, -1, F_TEXTIN, F_TEXTOUT },
{ "oid", 26, 0, 4, F_INT4IN, F_INT4OUT },
{ "tid", 27, 0, 6, F_TIDIN, F_TIDOUT },
{ "xid", 28, 0, 5, F_XIDIN, F_XIDOUT },
{ "iid", 29, 0, 1, F_CIDIN, F_CIDOUT },
{ "oid8", 30, 0, 32, F_OID8IN, F_OID8OUT },
{ "smgr", 210, 0, 2, F_SMGRIN, F_SMGROUT },
{ "_int4", 1007, 23, -1, F_ARRAY_IN, F_ARRAY_OUT },
{ "_aclitem", 1034, 1033, -1, F_ARRAY_IN, F_ARRAY_OUT }
{"int2", 21, 0, 2, F_INT2IN, F_INT2OUT},
{"int28", 22, 0, 16, F_INT28IN, F_INT28OUT},
{"int4", 23, 0, 4, F_INT4IN, F_INT4OUT},
{"regproc", 24, 0, 4, F_REGPROCIN, F_REGPROCOUT},
{"text", 25, 0, -1, F_TEXTIN, F_TEXTOUT},
{"oid", 26, 0, 4, F_INT4IN, F_INT4OUT},
{"tid", 27, 0, 6, F_TIDIN, F_TIDOUT},
{"xid", 28, 0, 5, F_XIDIN, F_XIDOUT},
{"iid", 29, 0, 1, F_CIDIN, F_CIDOUT},
{"oid8", 30, 0, 32, F_OID8IN, F_OID8OUT},
{"smgr", 210, 0, 2, F_SMGRIN, F_SMGROUT},
{"_int4", 1007, 23, -1, F_ARRAY_IN, F_ARRAY_OUT},
{"_aclitem", 1034, 1033, -1, F_ARRAY_IN, F_ARRAY_OUT}
};
static int n_types = sizeof(Procid) / sizeof(struct typinfo);
struct typmap { /* a hack */
struct typmap
{ /* a hack */
Oid am_oid;
TypeTupleFormData am_typ;
};
static struct typmap **Typ = (struct typmap **)NULL;
static struct typmap *Ap = (struct typmap *)NULL;
static struct typmap **Typ = (struct typmap **) NULL;
static struct typmap *Ap = (struct typmap *) NULL;
static int Warnings = 0;
static char Blanks[MAXATTR];
@ -194,20 +197,23 @@ static char Blanks[MAXATTR];
static char *relname; /* current relation name */
AttributeTupleForm attrtypes[MAXATTR]; /* points to attribute info */
static char *values[MAXATTR]; /* cooresponding attribute values */
static char *values[MAXATTR];/* cooresponding attribute values */
int numattr; /* number of attributes for cur. rel */
extern int fsyncOff; /* do not fsync the database */
#ifndef HAVE_SIGSETJMP
static jmp_buf Warn_restart;
#define sigsetjmp(x,y) setjmp(x)
#define siglongjmp longjmp
#else
static sigjmp_buf Warn_restart;
#endif
int DebugMode;
static GlobalMemory nogc = (GlobalMemory) NULL; /* special no-gc mem context */
static GlobalMemory nogc = (GlobalMemory) NULL; /* special no-gc mem
* context */
extern int optind;
extern char *optarg;
@ -218,13 +224,14 @@ extern char *optarg;
* to allow us to build the indices after they've been declared.
*/
typedef struct _IndexList {
char* il_heap;
char* il_ind;
typedef struct _IndexList
{
char *il_heap;
char *il_ind;
int il_natts;
AttrNumber *il_attnos;
uint16 il_nparams;
Datum * il_params;
Datum *il_params;
FuncIndexInfo *il_finfo;
PredInfo *il_predInfo;
struct _IndexList *il_next;
@ -232,10 +239,11 @@ typedef struct _IndexList {
static IndexList *ILHead = (IndexList *) NULL;
typedef void (*sig_func)();
typedef void (*sig_func) ();
/* ----------------------------------------------------------------
* misc functions
* ----------------------------------------------------------------
@ -258,13 +266,13 @@ err_out(void)
static void
usage(void)
{
fprintf(stderr,"Usage: postgres -boot [-d] [-C] [-F] [-O] [-Q] ");
fprintf(stderr,"[-P portno] [dbName]\n");
fprintf(stderr," d: debug mode\n");
fprintf(stderr," C: disable version checking\n");
fprintf(stderr," F: turn off fsync\n");
fprintf(stderr," O: set BootstrapProcessing mode\n");
fprintf(stderr," P portno: specify port number\n");
fprintf(stderr, "Usage: postgres -boot [-d] [-C] [-F] [-O] [-Q] ");
fprintf(stderr, "[-P portno] [dbName]\n");
fprintf(stderr, " d: debug mode\n");
fprintf(stderr, " C: disable version checking\n");
fprintf(stderr, " F: turn off fsync\n");
fprintf(stderr, " O: set BootstrapProcessing mode\n");
fprintf(stderr, " P portno: specify port number\n");
exitpg(1);
}
@ -289,7 +297,8 @@ BootstrapMain(int argc, char *argv[])
int portFd = -1;
char *dbName;
int flag;
int override = 1; /* use BootstrapProcessing or InitProcessing mode */
int override = 1; /* use BootstrapProcessing or
* InitProcessing mode */
extern int optind;
extern char *optarg;
@ -322,8 +331,10 @@ BootstrapMain(int argc, char *argv[])
dbName = NULL;
DataDir = getenv("PGDATA"); /* Null if no PGDATA variable */
while ((flag = getopt(argc, argv, "D:dCOQP:F")) != EOF) {
switch (flag) {
while ((flag = getopt(argc, argv, "D:dCOQP:F")) != EOF)
{
switch (flag)
{
case 'D':
DataDir = optarg;
break;
@ -342,7 +353,7 @@ BootstrapMain(int argc, char *argv[])
case 'Q':
Quiet = 1;
break;
case 'P':/* specify port */
case 'P': /* specify port */
portFd = atoi(optarg);
break;
default:
@ -351,14 +362,17 @@ BootstrapMain(int argc, char *argv[])
}
} /* while */
if (argc - optind > 1) {
if (argc - optind > 1)
{
usage();
} else
if (argc - optind == 1) {
}
else if (argc - optind == 1)
{
dbName = argv[optind];
}
if (!DataDir) {
if (!DataDir)
{
fprintf(stderr, "%s does not know where to find the database system "
"data. You must specify the directory that contains the "
"database system either by specifying the -D invocation "
@ -367,9 +381,11 @@ BootstrapMain(int argc, char *argv[])
exitpg(1);
}
if (dbName == NULL) {
if (dbName == NULL)
{
dbName = getenv("USER");
if (dbName == NULL) {
if (dbName == NULL)
{
fputs("bootstrap backend: failed, no db name specified\n", stderr);
fputs(" and no USER enviroment variable\n", stderr);
exitpg(1);
@ -380,7 +396,8 @@ BootstrapMain(int argc, char *argv[])
* initialize input fd
* ----------------
*/
if (IsUnderPostmaster == true && portFd < 0) {
if (IsUnderPostmaster == true && portFd < 0)
{
fputs("backend: failed, no -P option with -postmaster opt.\n", stderr);
exitpg(1);
}
@ -399,13 +416,14 @@ BootstrapMain(int argc, char *argv[])
InitPostgres(dbName);
LockDisable(true);
for (i = 0 ; i < MAXATTR; i++) {
attrtypes[i]=(AttributeTupleForm )NULL;
for (i = 0; i < MAXATTR; i++)
{
attrtypes[i] = (AttributeTupleForm) NULL;
Blanks[i] = ' ';
}
for(i = 0; i < STRTABLESIZE; ++i)
for (i = 0; i < STRTABLESIZE; ++i)
strtable[i] = NULL;
for(i = 0; i < HASHTABLESIZE; ++i)
for (i = 0; i < HASHTABLESIZE; ++i)
hashtable[i] = NULL;
/* ----------------
@ -415,9 +433,11 @@ BootstrapMain(int argc, char *argv[])
#ifndef win32
pqsignal(SIGHUP, handle_warn);
if (sigsetjmp(Warn_restart, 1) != 0) {
if (sigsetjmp(Warn_restart, 1) != 0)
{
#else
if (setjmp(Warn_restart) != 0) {
if (setjmp(Warn_restart) != 0)
{
#endif /* win32 */
Warnings++;
AbortCurrentTransaction();
@ -428,9 +448,10 @@ BootstrapMain(int argc, char *argv[])
* ----------------
*/
/* the sed script boot.sed renamed yyparse to Int_yyparse
for the bootstrap parser to avoid conflicts with the normal SQL
parser */
/*
* the sed script boot.sed renamed yyparse to Int_yyparse for the
* bootstrap parser to avoid conflicts with the normal SQL parser
*/
Int_yyparse();
/* clean up processing */
@ -461,53 +482,60 @@ boot_openrel(char *relname)
HeapTuple tup;
if (strlen(relname) > 15)
relname[15] ='\000';
relname[15] = '\000';
if (Typ == (struct typmap **)NULL) {
if (Typ == (struct typmap **) NULL)
{
StartPortalAllocMode(DefaultAllocMode, 0);
rdesc = heap_openr(TypeRelationName);
sdesc = heap_beginscan(rdesc, 0, NowTimeQual, 0, (ScanKey)NULL);
for (i=0; PointerIsValid(tup=heap_getnext(sdesc,0,(Buffer *)NULL)); ++i);
sdesc = heap_beginscan(rdesc, 0, NowTimeQual, 0, (ScanKey) NULL);
for (i = 0; PointerIsValid(tup = heap_getnext(sdesc, 0, (Buffer *) NULL)); ++i);
heap_endscan(sdesc);
app = Typ = ALLOC(struct typmap *, i + 1);
while (i-- > 0)
*app++ = ALLOC(struct typmap, 1);
*app = (struct typmap *)NULL;
sdesc = heap_beginscan(rdesc, 0, NowTimeQual, 0, (ScanKey)NULL);
*app = (struct typmap *) NULL;
sdesc = heap_beginscan(rdesc, 0, NowTimeQual, 0, (ScanKey) NULL);
app = Typ;
while (PointerIsValid(tup = heap_getnext(sdesc, 0, (Buffer *)NULL))) {
while (PointerIsValid(tup = heap_getnext(sdesc, 0, (Buffer *) NULL)))
{
(*app)->am_oid = tup->t_oid;
memmove((char *)&(*app++)->am_typ,
(char *)GETSTRUCT(tup),
sizeof ((*app)->am_typ));
memmove((char *) &(*app++)->am_typ,
(char *) GETSTRUCT(tup),
sizeof((*app)->am_typ));
}
heap_endscan(sdesc);
heap_close(rdesc);
EndPortalAllocMode();
}
if (reldesc != NULL) {
if (reldesc != NULL)
{
closerel(NULL);
}
if (!Quiet)
printf("Amopen: relation %s. attrsize %d\n", relname ? relname : "(null)",
(int)ATTRIBUTE_TUPLE_SIZE);
(int) ATTRIBUTE_TUPLE_SIZE);
reldesc = heap_openr(relname);
Assert(reldesc);
numattr = reldesc->rd_rel->relnatts;
for (i = 0; i < numattr; i++) {
if (attrtypes[i] == NULL) {
for (i = 0; i < numattr; i++)
{
if (attrtypes[i] == NULL)
{
attrtypes[i] = AllocateAttribute();
}
memmove((char *)attrtypes[i],
(char *)reldesc->rd_att->attrs[i],
memmove((char *) attrtypes[i],
(char *) reldesc->rd_att->attrs[i],
ATTRIBUTE_TUPLE_SIZE);
/* Some old pg_attribute tuples might not have attisset. */
/* If the attname is attisset, don't look for it - it may
not be defined yet.
/*
* If the attname is attisset, don't look for it - it may not be
* defined yet.
*/
if (namestrcmp(&attrtypes[i]->attname, "attisset") == 0)
attrtypes[i]->attisset = get_attisset(reldesc->rd_id,
@ -515,8 +543,10 @@ boot_openrel(char *relname)
else
attrtypes[i]->attisset = false;
if (DebugMode) {
if (DebugMode)
{
AttributeTupleForm at = attrtypes[i];
printf("create attribute %d name %s len %d num %d type %d\n",
i, at->attname.data, at->attlen, at->attnum,
at->atttypid
@ -533,27 +563,35 @@ boot_openrel(char *relname)
void
closerel(char *name)
{
if (name) {
if (reldesc) {
if (name)
{
if (reldesc)
{
if (namestrcmp(RelationGetRelationName(reldesc), name) != 0)
elog(WARN,"closerel: close of '%s' when '%s' was expected",
elog(WARN, "closerel: close of '%s' when '%s' was expected",
name, relname ? relname : "(null)");
} else
elog(WARN,"closerel: close of '%s' before any relation was opened",
}
else
elog(WARN, "closerel: close of '%s' before any relation was opened",
name);
}
if (reldesc == NULL) {
elog(WARN,"Warning: no opened relation to close.\n");
} else {
if (!Quiet) printf("Amclose: relation %s.\n", relname ? relname : "(null)");
if (reldesc == NULL)
{
elog(WARN, "Warning: no opened relation to close.\n");
}
else
{
if (!Quiet)
printf("Amclose: relation %s.\n", relname ? relname : "(null)");
heap_close(reldesc);
reldesc = (Relation)NULL;
reldesc = (Relation) NULL;
}
}
/* ----------------
* DEFINEATTR()
*
@ -568,28 +606,34 @@ DefineAttr(char *name, char *type, int attnum)
int attlen;
int t;
if (reldesc != NULL) {
fputs("Warning: no open relations allowed with 't' command.\n",stderr);
if (reldesc != NULL)
{
fputs("Warning: no open relations allowed with 't' command.\n", stderr);
closerel(relname);
}
t = gettype(type);
if (attrtypes[attnum] == (AttributeTupleForm )NULL)
if (attrtypes[attnum] == (AttributeTupleForm) NULL)
attrtypes[attnum] = AllocateAttribute();
if (Typ != (struct typmap **)NULL) {
if (Typ != (struct typmap **) NULL)
{
attrtypes[attnum]->atttypid = Ap->am_oid;
namestrcpy(&attrtypes[attnum]->attname, name);
if (!Quiet) printf("<%s %s> ", attrtypes[attnum]->attname.data, type);
if (!Quiet)
printf("<%s %s> ", attrtypes[attnum]->attname.data, type);
attrtypes[attnum]->attnum = 1 + attnum; /* fillatt */
attlen = attrtypes[attnum]->attlen = Ap->am_typ.typlen;
attrtypes[attnum]->attbyval = Ap->am_typ.typbyval;
} else {
}
else
{
attrtypes[attnum]->atttypid = Procid[t].oid;
namestrcpy(&attrtypes[attnum]->attname,name);
if (!Quiet) printf("<%s %s> ", attrtypes[attnum]->attname.data, type);
namestrcpy(&attrtypes[attnum]->attname, name);
if (!Quiet)
printf("<%s %s> ", attrtypes[attnum]->attname.data, type);
attrtypes[attnum]->attnum = 1 + attnum; /* fillatt */
attlen = attrtypes[attnum]->attlen = Procid[t].len;
attrtypes[attnum]->attbyval = (attlen==1) || (attlen==2)||(attlen==4);
attrtypes[attnum]->attbyval = (attlen == 1) || (attlen == 2) || (attlen == 4);
}
}
@ -607,28 +651,32 @@ InsertOneTuple(Oid objectid)
int i;
if (DebugMode) {
if (DebugMode)
{
printf("InsertOneTuple oid %d, %d attrs\n", objectid, numattr);
fflush(stdout);
}
tupDesc = CreateTupleDesc(numattr,attrtypes);
tuple = heap_formtuple(tupDesc,(Datum*)values,Blanks);
tupDesc = CreateTupleDesc(numattr, attrtypes);
tuple = heap_formtuple(tupDesc, (Datum *) values, Blanks);
pfree(tupDesc); /* just free's tupDesc, not the attrtypes */
if(objectid !=(Oid)0) {
tuple->t_oid=objectid;
if (objectid != (Oid) 0)
{
tuple->t_oid = objectid;
}
heap_insert(reldesc, tuple);
pfree(tuple);
if (DebugMode) {
if (DebugMode)
{
printf("End InsertOneTuple, objectid=%d\n", objectid);
fflush(stdout);
}
/*
* Reset blanks for next tuple
*/
for (i = 0; i<numattr; i++)
for (i = 0; i < numattr; i++)
Blanks[i] = ' ';
}
@ -645,20 +693,24 @@ InsertOneValue(Oid objectid, char *value, int i)
if (DebugMode)
printf("Inserting value: '%s'\n", value);
if (i < 0 || i >= MAXATTR) {
if (i < 0 || i >= MAXATTR)
{
printf("i out of range: %d\n", i);
Assert(0);
}
if (Typ != (struct typmap **)NULL) {
if (Typ != (struct typmap **) NULL)
{
struct typmap *ap;
if (DebugMode)
puts("Typ != NULL");
app = Typ;
while (*app && (*app)->am_oid != reldesc->rd_att->attrs[i]->atttypid)
++app;
ap = *app;
if (ap == NULL) {
if (ap == NULL)
{
printf("Unable to find atttypid in Typ list! %d\n",
reldesc->rd_att->attrs[i]->atttypid
);
@ -667,13 +719,17 @@ InsertOneValue(Oid objectid, char *value, int i)
values[i] = fmgr(ap->am_typ.typinput,
value,
ap->am_typ.typelem,
-1); /* shouldn't have char() or varchar() types
during boostrapping but just to be safe */
-1); /* shouldn't have char() or varchar()
* types during boostrapping but just to
* be safe */
prt = fmgr(ap->am_typ.typoutput, values[i],
ap->am_typ.typelem);
if (!Quiet) printf("%s ", prt);
if (!Quiet)
printf("%s ", prt);
pfree(prt);
} else {
}
else
{
typeindex = attrtypes[i]->atttypid - FIRST_TYPE_OID;
if (DebugMode)
printf("Typ == NULL, typeindex = %d idx = %d\n", typeindex, i);
@ -681,10 +737,12 @@ InsertOneValue(Oid objectid, char *value, int i)
Procid[typeindex].elem, -1);
prt = fmgr(Procid[typeindex].outproc, values[i],
Procid[typeindex].elem);
if (!Quiet) printf("%s ", prt);
if (!Quiet)
printf("%s ", prt);
pfree(prt);
}
if (DebugMode) {
if (DebugMode)
{
puts("End InsertValue");
fflush(stdout);
}
@ -699,10 +757,11 @@ InsertOneNull(int i)
{
if (DebugMode)
printf("Inserting null\n");
if (i < 0 || i >= MAXATTR) {
if (i < 0 || i >= MAXATTR)
{
elog(FATAL, "i out of range (too many attrs): %d\n", i);
}
values[i] = (char *)NULL;
values[i] = (char *) NULL;
Blanks[i] = 'n';
}
@ -718,13 +777,16 @@ BootstrapAlreadySeen(Oid id)
seenthis = false;
for (i=0; i < nseen; i++) {
if (seenArray[i] == id) {
for (i = 0; i < nseen; i++)
{
if (seenArray[i] == id)
{
seenthis = true;
break;
}
}
if (!seenthis) {
if (!seenthis)
{
seenArray[nseen] = id;
nseen++;
}
@ -742,11 +804,13 @@ cleanup()
if (!beenhere)
beenhere = 1;
else {
elog(FATAL,"Memory manager fault: cleanup called twice.\n", stderr);
else
{
elog(FATAL, "Memory manager fault: cleanup called twice.\n", stderr);
exitpg(1);
}
if (reldesc != (Relation)NULL) {
if (reldesc != (Relation) NULL)
{
heap_close(reldesc);
}
CommitTransactionCommand();
@ -766,42 +830,50 @@ gettype(char *type)
HeapTuple tup;
struct typmap **app;
if (Typ != (struct typmap **)NULL) {
for (app = Typ; *app != (struct typmap *)NULL; app++) {
if (strncmp((*app)->am_typ.typname.data, type, NAMEDATALEN) == 0) {
if (Typ != (struct typmap **) NULL)
{
for (app = Typ; *app != (struct typmap *) NULL; app++)
{
if (strncmp((*app)->am_typ.typname.data, type, NAMEDATALEN) == 0)
{
Ap = *app;
return((*app)->am_oid);
return ((*app)->am_oid);
}
}
} else {
for (i = 0; i <= n_types; i++) {
if (strncmp(type, Procid[i].name, NAMEDATALEN) == 0) {
return(i);
}
else
{
for (i = 0; i <= n_types; i++)
{
if (strncmp(type, Procid[i].name, NAMEDATALEN) == 0)
{
return (i);
}
}
if (DebugMode)
printf("bootstrap.c: External Type: %s\n", type);
rdesc = heap_openr(TypeRelationName);
sdesc = heap_beginscan(rdesc, 0, NowTimeQual, 0, (ScanKey)NULL);
sdesc = heap_beginscan(rdesc, 0, NowTimeQual, 0, (ScanKey) NULL);
i = 0;
while (PointerIsValid(tup = heap_getnext(sdesc, 0, (Buffer *)NULL)))
while (PointerIsValid(tup = heap_getnext(sdesc, 0, (Buffer *) NULL)))
++i;
heap_endscan(sdesc);
app = Typ = ALLOC(struct typmap *, i + 1);
while (i-- > 0)
*app++ = ALLOC(struct typmap, 1);
*app = (struct typmap *)NULL;
sdesc = heap_beginscan(rdesc, 0, NowTimeQual, 0, (ScanKey)NULL);
*app = (struct typmap *) NULL;
sdesc = heap_beginscan(rdesc, 0, NowTimeQual, 0, (ScanKey) NULL);
app = Typ;
while (PointerIsValid(tup = heap_getnext(sdesc, 0, (Buffer *)NULL))) {
while (PointerIsValid(tup = heap_getnext(sdesc, 0, (Buffer *) NULL)))
{
(*app)->am_oid = tup->t_oid;
memmove((char *)&(*app++)->am_typ,
(char *)GETSTRUCT(tup),
sizeof ((*app)->am_typ));
memmove((char *) &(*app++)->am_typ,
(char *) GETSTRUCT(tup),
sizeof((*app)->am_typ));
}
heap_endscan(sdesc);
heap_close(rdesc);
return(gettype(type));
return (gettype(type));
}
elog(WARN, "Error: unknown type '%s'.\n", type);
err_out();
@ -817,9 +889,10 @@ static AttributeTupleForm /* XXX */
AllocateAttribute()
{
AttributeTupleForm attribute =
(AttributeTupleForm)malloc(ATTRIBUTE_TUPLE_SIZE);
(AttributeTupleForm) malloc(ATTRIBUTE_TUPLE_SIZE);
if (!PointerIsValid(attribute)) {
if (!PointerIsValid(attribute))
{
elog(FATAL, "AllocateAttribute: malloc failed");
}
memset(attribute, 0, ATTRIBUTE_TUPLE_SIZE);
@ -841,18 +914,20 @@ AllocateAttribute()
* be freed by the CALLER.
* ----------------
*/
char*
char *
MapArrayTypeName(char *s)
{
int i, j;
static char newStr[NAMEDATALEN]; /* array type names < NAMEDATALEN long */
int i,
j;
static char newStr[NAMEDATALEN]; /* array type names <
* NAMEDATALEN long */
if (s == NULL || s[0] == '\0')
return s;
j = 1;
newStr[0] = '_';
for (i=0; i<NAMEDATALEN-1 && s[i] != '['; i++, j++)
for (i = 0; i < NAMEDATALEN - 1 && s[i] != '['; i++, j++)
newStr[j] = s[i];
newStr[j] = '\0';
@ -867,17 +942,20 @@ MapArrayTypeName(char *s)
* ----------------
*/
int
EnterString (char *str)
EnterString(char *str)
{
hashnode *node;
int len;
len= strlen(str);
len = strlen(str);
node = FindStr(str, len, 0);
if (node) {
if (node)
{
return (node->strnum);
} else {
}
else
{
node = AddStr(str, len, 0);
return (node->strnum);
}
@ -892,7 +970,7 @@ EnterString (char *str)
char *
LexIDStr(int ident_num)
{
return(strtable[ident_num]);
return (strtable[ident_num]);
}
@ -910,7 +988,7 @@ CompHash(char *str, int len)
{
register int result;
result =(NUM * str[0] + NUMSQR * str[len-1] + NUMCUBE * str[(len-1)/2]);
result = (NUM * str[0] + NUMSQR * str[len - 1] + NUMCUBE * str[(len - 1) / 2]);
return (result % HASHTABLESIZE);
@ -925,19 +1003,24 @@ CompHash(char *str, int len)
* ----------------
*/
static hashnode *
FindStr(char *str, int length, hashnode *mderef)
FindStr(char *str, int length, hashnode * mderef)
{
hashnode *node;
node = hashtable [CompHash (str, length)];
while (node != NULL) {
node = hashtable[CompHash(str, length)];
while (node != NULL)
{
/*
* We must differentiate between string constants that
* might have the same value as a identifier
* and the identifier itself.
* We must differentiate between string constants that might have
* the same value as a identifier and the identifier itself.
*/
if (!strcmp(str, strtable[node->strnum])) {
return(node); /* no need to check */
} else {
if (!strcmp(str, strtable[node->strnum]))
{
return (node); /* no need to check */
}
else
{
node = node->next;
}
}
@ -957,11 +1040,14 @@ FindStr(char *str, int length, hashnode *mderef)
static hashnode *
AddStr(char *str, int strlength, int mderef)
{
hashnode *temp, *trail, *newnode;
hashnode *temp,
*trail,
*newnode;
int hashresult;
int len;
if (++strtable_end == STRTABLESIZE) {
if (++strtable_end == STRTABLESIZE)
{
/* Error, string table overflow, so we Punt */
elog(FATAL,
"There are too many string constants and identifiers for the compiler to handle.");
@ -970,34 +1056,38 @@ AddStr(char *str, int strlength, int mderef)
}
/*
* Some of the utilites (eg, define type, create relation) assume
* that the string they're passed is a NAMEDATALEN. We get array bound
* read violations from purify if we don't allocate at least NAMEDATALEN
* bytes for strings of this sort. Because we're lazy, we allocate
* at least NAMEDATALEN bytes all the time.
* Some of the utilites (eg, define type, create relation) assume that
* the string they're passed is a NAMEDATALEN. We get array bound
* read violations from purify if we don't allocate at least
* NAMEDATALEN bytes for strings of this sort. Because we're lazy, we
* allocate at least NAMEDATALEN bytes all the time.
*/
if ((len = strlength + 1) < NAMEDATALEN)
len = NAMEDATALEN;
strtable [strtable_end] = malloc((unsigned) len);
strcpy (strtable[strtable_end], str);
strtable[strtable_end] = malloc((unsigned) len);
strcpy(strtable[strtable_end], str);
/* Now put a node in the hash table */
newnode = (hashnode*)malloc(sizeof(hashnode)*1);
newnode = (hashnode *) malloc(sizeof(hashnode) * 1);
newnode->strnum = strtable_end;
newnode->next = NULL;
/* Find out where it goes */
hashresult = CompHash (str, strlength);
if (hashtable [hashresult] == NULL) {
hashtable [hashresult] = newnode;
} else { /* There is something in the list */
trail = hashtable [hashresult];
hashresult = CompHash(str, strlength);
if (hashtable[hashresult] == NULL)
{
hashtable[hashresult] = newnode;
}
else
{ /* There is something in the list */
trail = hashtable[hashresult];
temp = trail->next;
while (temp != NULL) {
while (temp != NULL)
{
trail = temp;
temp = temp->next;
}
@ -1022,11 +1112,11 @@ void
index_register(char *heap,
char *ind,
int natts,
AttrNumber *attnos,
AttrNumber * attnos,
uint16 nparams,
Datum *params,
FuncIndexInfo *finfo,
PredInfo *predInfo)
Datum * params,
FuncIndexInfo * finfo,
PredInfo * predInfo)
{
Datum *v;
IndexList *newind;
@ -1034,9 +1124,9 @@ index_register(char *heap,
MemoryContext oldcxt;
/*
* XXX mao 10/31/92 -- don't gc index reldescs, associated info
* at bootstrap time. we'll declare the indices now, but want to
* create them later.
* XXX mao 10/31/92 -- don't gc index reldescs, associated info at
* bootstrap time. we'll declare the indices now, but want to create
* them later.
*/
if (nogc == (GlobalMemory) NULL)
@ -1057,29 +1147,39 @@ index_register(char *heap,
newind->il_attnos = (AttrNumber *) palloc(len);
memmove(newind->il_attnos, attnos, len);
if ((newind->il_nparams = nparams) > 0) {
if ((newind->il_nparams = nparams) > 0)
{
v = newind->il_params = (Datum *) palloc(2 * nparams * sizeof(Datum));
nparams *= 2;
while (nparams-- > 0) {
*v = (Datum) palloc(strlen((char *)(*params)) + 1);
while (nparams-- > 0)
{
*v = (Datum) palloc(strlen((char *) (*params)) + 1);
strcpy((char *) *v++, (char *) *params++);
}
} else {
}
else
{
newind->il_params = (Datum *) NULL;
}
if (finfo != (FuncIndexInfo *) NULL) {
if (finfo != (FuncIndexInfo *) NULL)
{
newind->il_finfo = (FuncIndexInfo *) palloc(sizeof(FuncIndexInfo));
memmove(newind->il_finfo, finfo, sizeof(FuncIndexInfo));
} else {
}
else
{
newind->il_finfo = (FuncIndexInfo *) NULL;
}
if (predInfo != NULL) {
newind->il_predInfo = (PredInfo*)palloc(sizeof(PredInfo));
if (predInfo != NULL)
{
newind->il_predInfo = (PredInfo *) palloc(sizeof(PredInfo));
newind->il_predInfo->pred = predInfo->pred;
newind->il_predInfo->oldPred = predInfo->oldPred;
} else {
}
else
{
newind->il_predInfo = NULL;
}
@ -1096,7 +1196,8 @@ build_indices()
Relation heap;
Relation ind;
for ( ; ILHead != (IndexList *) NULL; ILHead = ILHead->il_next) {
for (; ILHead != (IndexList *) NULL; ILHead = ILHead->il_next)
{
heap = heap_openr(ILHead->il_heap);
ind = index_openr(ILHead->il_ind);
index_build(heap, ind, ILHead->il_natts, ILHead->il_attnos,
@ -1104,17 +1205,18 @@ build_indices()
ILHead->il_predInfo);
/*
* All of the rest of this routine is needed only because in bootstrap
* processing we don't increment xact id's. The normal DefineIndex
* code replaces a pg_class tuple with updated info including the
* relhasindex flag (which we need to have updated). Unfortunately,
* there are always two indices defined on each catalog causing us to
* update the same pg_class tuple twice for each catalog getting an
* index during bootstrap resulting in the ghost tuple problem (see
* heap_replace). To get around this we change the relhasindex
* field ourselves in this routine keeping track of what catalogs we
* already changed so that we don't modify those tuples twice. The
* normal mechanism for updating pg_class is disabled during bootstrap.
* All of the rest of this routine is needed only because in
* bootstrap processing we don't increment xact id's. The normal
* DefineIndex code replaces a pg_class tuple with updated info
* including the relhasindex flag (which we need to have updated).
* Unfortunately, there are always two indices defined on each
* catalog causing us to update the same pg_class tuple twice for
* each catalog getting an index during bootstrap resulting in the
* ghost tuple problem (see heap_replace). To get around this we
* change the relhasindex field ourselves in this routine keeping
* track of what catalogs we already changed so that we don't
* modify those tuples twice. The normal mechanism for updating
* pg_class is disabled during bootstrap.
*
* -mer
*/
@ -1124,4 +1226,3 @@ build_indices()
UpdateStats(heap->rd_id, 0, true);
}
}

View File

@ -7,7 +7,7 @@
*
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/catalog/catalog.c,v 1.7 1997/08/18 20:51:59 momjian Exp $
* $Header: /cvsroot/pgsql/src/backend/catalog/catalog.c,v 1.8 1997/09/07 04:40:00 momjian Exp $
*
*-------------------------------------------------------------------------
*/
@ -31,12 +31,13 @@ relpath(char relname[])
{
char *path;
if (IsSharedSystemRelationName(relname)) {
if (IsSharedSystemRelationName(relname))
{
path = (char *) palloc(strlen(DataDir) + sizeof(NameData) + 2);
sprintf(path, "%s/%s", DataDir, relname);
return (path);
}
return(relname);
return (relname);
}
#ifdef NOT_USED
@ -59,6 +60,7 @@ issystem(char relname[])
else
return FALSE;
}
#endif
/*
@ -99,8 +101,9 @@ IsSharedSystemRelationName(char *relname)
return FALSE;
i = 0;
while ( SharedSystemRelationNames[i] != NULL) {
if (strcmp(SharedSystemRelationNames[i],relname) == 0)
while (SharedSystemRelationNames[i] != NULL)
{
if (strcmp(SharedSystemRelationNames[i], relname) == 0)
return TRUE;
i++;
}
@ -122,12 +125,13 @@ IsSharedSystemRelationName(char *relname)
* for a block of OID's to be declared as invalid ones to allow
* user programs to use them for temporary object identifiers.
*/
Oid newoid()
Oid
newoid()
{
Oid lastoid;
GetNewObjectId(&lastoid);
if (! OidIsValid(lastoid))
if (!OidIsValid(lastoid))
elog(WARN, "newoid: GetNewObjectId returns invalid oid");
return lastoid;
}
@ -159,33 +163,42 @@ fillatt(TupleDesc tupleDesc)
if (natts < 0 || natts > MaxHeapAttributeNumber)
elog(WARN, "fillatt: %d attributes is too large", natts);
if (natts == 0) {
if (natts == 0)
{
elog(DEBUG, "fillatt: called with natts == 0");
return;
}
attributeP = &att[0];
for (i = 0; i < natts;) {
for (i = 0; i < natts;)
{
tuple = SearchSysCacheTuple(TYPOID,
Int32GetDatum((*attributeP)->atttypid),
0,0,0);
if (!HeapTupleIsValid(tuple)) {
0, 0, 0);
if (!HeapTupleIsValid(tuple))
{
elog(WARN, "fillatt: unknown atttypid %ld",
(*attributeP)->atttypid);
} else {
(*attributeP)->attnum = (int16) ++i;
/* Check if the attr is a set before messing with the length
and byval, since those were already set in
TupleDescInitEntry. In fact, this seems redundant
here, but who knows what I'll break if I take it out...
}
else
{
(*attributeP)->attnum = (int16)++ i;
same for char() and varchar() stuff. I share the same
sentiments. This function is poorly written anyway. -ay 6/95
/*
* Check if the attr is a set before messing with the length
* and byval, since those were already set in
* TupleDescInitEntry. In fact, this seems redundant here,
* but who knows what I'll break if I take it out...
*
* same for char() and varchar() stuff. I share the same
* sentiments. This function is poorly written anyway. -ay
* 6/95
*/
if (!(*attributeP)->attisset &&
(*attributeP)->atttypid!=BPCHAROID &&
(*attributeP)->atttypid!=VARCHAROID) {
(*attributeP)->atttypid != BPCHAROID &&
(*attributeP)->atttypid != VARCHAROID)
{
typp = (TypeTupleForm) GETSTRUCT(tuple); /* XXX */
(*attributeP)->attlen = typp->typlen;

View File

@ -7,7 +7,7 @@
*
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/catalog/heap.c,v 1.24 1997/09/05 18:13:45 momjian Exp $
* $Header: /cvsroot/pgsql/src/backend/catalog/heap.c,v 1.25 1997/09/07 04:40:10 momjian Exp $
*
* INTERFACE ROUTINES
* heap_creatr() - Create an uncataloged heap relation
@ -53,12 +53,13 @@
#include <utils/relcache.h>
#include <nodes/plannodes.h>
#ifndef HAVE_MEMMOVE
# include <regex/utils.h>
#include <regex/utils.h>
#else
# include <string.h>
#include <string.h>
#endif
static void AddPgRelationTuple(Relation pg_class_desc,
static void
AddPgRelationTuple(Relation pg_class_desc,
Relation new_rel_desc, Oid new_rel_oid, int arch, unsigned natts);
static void AddToTempRelList(Relation r);
static void DeletePgAttributeTuples(Relation rdesc);
@ -69,8 +70,8 @@ static void RelationRemoveIndexes(Relation relation);
static void RelationRemoveInheritance(Relation relation);
static void RemoveFromTempRelList(Relation r);
static void addNewRelationType(char *typeName, Oid new_rel_oid);
static void StoreConstraints (Relation rel);
static void RemoveConstraints (Relation rel);
static void StoreConstraints(Relation rel);
static void RemoveConstraints(Relation rel);
/* ----------------------------------------------------------------
@ -91,7 +92,7 @@ static void RemoveConstraints (Relation rel);
*/
static FormData_pg_attribute a1 = {
0xffffffff, {"ctid"}, 27l, 0l, sizeof (ItemPointerData),
0xffffffff, {"ctid"}, 27l, 0l, sizeof(ItemPointerData),
SelfItemPointerAttributeNumber, 0, -1, '\0', '\0', 'i', '\0', '\0'
};
@ -101,52 +102,52 @@ static FormData_pg_attribute a2 = {
};
static FormData_pg_attribute a3 = {
0xffffffff, {"xmin"}, 28l, 0l, sizeof (TransactionId),
0xffffffff, {"xmin"}, 28l, 0l, sizeof(TransactionId),
MinTransactionIdAttributeNumber, 0, -1, '\0', '\0', 'i', '\0', '\0'
};
static FormData_pg_attribute a4 = {
0xffffffff, {"cmin"}, 29l, 0l, sizeof (CommandId),
0xffffffff, {"cmin"}, 29l, 0l, sizeof(CommandId),
MinCommandIdAttributeNumber, 0, -1, '\001', '\0', 's', '\0', '\0'
};
static FormData_pg_attribute a5 = {
0xffffffff, {"xmax"}, 28l, 0l, sizeof (TransactionId),
0xffffffff, {"xmax"}, 28l, 0l, sizeof(TransactionId),
MaxTransactionIdAttributeNumber, 0, -1, '\0', '\0', 'i', '\0', '\0'
};
static FormData_pg_attribute a6 = {
0xffffffff, {"cmax"}, 29l, 0l, sizeof (CommandId),
0xffffffff, {"cmax"}, 29l, 0l, sizeof(CommandId),
MaxCommandIdAttributeNumber, 0, -1, '\001', '\0', 's', '\0', '\0'
};
static FormData_pg_attribute a7 = {
0xffffffff, {"chain"}, 27l, 0l, sizeof (ItemPointerData),
0xffffffff, {"chain"}, 27l, 0l, sizeof(ItemPointerData),
ChainItemPointerAttributeNumber, 0, -1, '\0', '\0', 'i', '\0', '\0'
};
static FormData_pg_attribute a8 = {
0xffffffff, {"anchor"}, 27l, 0l, sizeof (ItemPointerData),
0xffffffff, {"anchor"}, 27l, 0l, sizeof(ItemPointerData),
AnchorItemPointerAttributeNumber, 0, -1, '\0', '\0', 'i', '\0', '\0'
};
static FormData_pg_attribute a9 = {
0xffffffff, {"tmin"}, 702l, 0l, sizeof (AbsoluteTime),
0xffffffff, {"tmin"}, 702l, 0l, sizeof(AbsoluteTime),
MinAbsoluteTimeAttributeNumber, 0, -1, '\001', '\0', 'i', '\0', '\0'
};
static FormData_pg_attribute a10 = {
0xffffffff, {"tmax"}, 702l, 0l, sizeof (AbsoluteTime),
0xffffffff, {"tmax"}, 702l, 0l, sizeof(AbsoluteTime),
MaxAbsoluteTimeAttributeNumber, 0, -1, '\001', '\0', 'i', '\0', '\0'
};
static FormData_pg_attribute a11 = {
0xffffffff, {"vtype"}, 18l, 0l, sizeof (char),
0xffffffff, {"vtype"}, 18l, 0l, sizeof(char),
VersionTypeAttributeNumber, 0, -1, '\001', '\0', 'c', '\0', '\0'
};
static AttributeTupleForm HeapAtt[] =
{ &a1, &a2, &a3, &a4, &a5, &a6, &a7, &a8, &a9, &a10, &a11 };
{&a1, &a2, &a3, &a4, &a5, &a6, &a7, &a8, &a9, &a10, &a11};
/* ----------------------------------------------------------------
* XXX END OF UGLY HARD CODED BADNESS XXX
@ -157,10 +158,12 @@ static AttributeTupleForm HeapAtt[] =
the list of temporary uncatalogued relations that are created.
these relations should be destroyed at the end of transactions
*/
typedef struct tempRelList {
typedef struct tempRelList
{
Relation *rels; /* array of relation descriptors */
int num; /* number of temporary relations */
int size; /* size of space allocated for the rels array */
int size; /* size of space allocated for the rels
* array */
} TempRelList;
#define TEMP_REL_LIST_SIZE 32
@ -195,10 +198,11 @@ heap_creatr(char *name,
Relation rdesc;
int len;
bool nailme = false;
char* relname = name;
char *relname = name;
char tempname[40];
int isTemp = 0;
int natts = tupDesc->natts;
/* AttributeTupleForm *att = tupDesc->attrs; */
extern GlobalMemory CacheCxt;
@ -226,29 +230,29 @@ heap_creatr(char *name,
if (!CacheCxt)
CacheCxt = CreateGlobalMemory("Cache");
oldcxt = MemoryContextSwitchTo((MemoryContext)CacheCxt);
oldcxt = MemoryContextSwitchTo((MemoryContext) CacheCxt);
/* ----------------
* real ugly stuff to assign the proper relid in the relation
* descriptor follows.
* ----------------
*/
if (! strcmp(RelationRelationName,relname))
if (!strcmp(RelationRelationName, relname))
{
relid = RelOid_pg_class;
nailme = true;
}
else if (! strcmp(AttributeRelationName,relname))
else if (!strcmp(AttributeRelationName, relname))
{
relid = RelOid_pg_attribute;
nailme = true;
}
else if (! strcmp(ProcedureRelationName, relname))
else if (!strcmp(ProcedureRelationName, relname))
{
relid = RelOid_pg_proc;
nailme = true;
}
else if (! strcmp(TypeRelationName,relname))
else if (!strcmp(TypeRelationName, relname))
{
relid = RelOid_pg_type;
nailme = true;
@ -274,7 +278,7 @@ heap_creatr(char *name,
len = sizeof(RelationData);
rdesc = (Relation) palloc(len);
memset((char *)rdesc, 0,len);
memset((char *) rdesc, 0, len);
/* ----------
create a new tuple descriptor from the one passed in
@ -297,24 +301,26 @@ heap_creatr(char *name,
RelationSetReferenceCount(rdesc, 1);
rdesc->rd_rel = (Form_pg_class)palloc(sizeof *rdesc->rd_rel);
rdesc->rd_rel = (Form_pg_class) palloc(sizeof *rdesc->rd_rel);
memset((char *)rdesc->rd_rel, 0,
memset((char *) rdesc->rd_rel, 0,
sizeof *rdesc->rd_rel);
namestrcpy(&(rdesc->rd_rel->relname), relname);
rdesc->rd_rel->relkind = RELKIND_UNCATALOGED;
rdesc->rd_rel->relnatts = natts;
rdesc->rd_rel->relsmgr = smgr;
if ( tupDesc->constr )
if (tupDesc->constr)
rdesc->rd_rel->relchecks = tupDesc->constr->num_check;
for (i = 0; i < natts; i++) {
for (i = 0; i < natts; i++)
{
rdesc->rd_att->attrs[i]->attrelid = relid;
}
rdesc->rd_id = relid;
if (nailme) {
if (nailme)
{
/* for system relations, set the reltype field here */
rdesc->rd_rel->reltype = relid;
}
@ -332,15 +338,16 @@ heap_creatr(char *name,
*/
rdesc->rd_tmpunlinked = TRUE; /* change once table is created */
rdesc->rd_fd = (File)smgrcreate(smgr, rdesc);
rdesc->rd_fd = (File) smgrcreate(smgr, rdesc);
rdesc->rd_tmpunlinked = FALSE;
RelationRegisterRelation(rdesc);
MemoryContextSwitchTo(oldcxt);
/* add all temporary relations to the tempRels list
so they can be properly disposed of at the end of transaction
/*
* add all temporary relations to the tempRels list so they can be
* properly disposed of at the end of transaction
*/
if (isTemp)
AddToTempRelList(rdesc);
@ -430,10 +437,13 @@ CheckAttributeNames(TupleDesc tupdesc)
* an unknown typid (usually as a result of a 'retrieve into'
* - jolly
*/
for (i = 0; i < natts; i += 1) {
for (j = 0; j < sizeof HeapAtt / sizeof HeapAtt[0]; j += 1) {
for (i = 0; i < natts; i += 1)
{
for (j = 0; j < sizeof HeapAtt / sizeof HeapAtt[0]; j += 1)
{
if (nameeq(&(HeapAtt[j]->attname),
&(tupdesc->attrs[i]->attname))) {
&(tupdesc->attrs[i]->attname)))
{
elog(WARN,
"create: system attribute named \"%s\"",
HeapAtt[j]->attname.data);
@ -451,10 +461,13 @@ CheckAttributeNames(TupleDesc tupdesc)
* next check for repeated attribute names
* ----------------
*/
for (i = 1; i < natts; i += 1) {
for (j = 0; j < i; j += 1) {
for (i = 1; i < natts; i += 1)
{
for (j = 0; j < i; j += 1)
{
if (nameeq(&(tupdesc->attrs[j]->attname),
&(tupdesc->attrs[i]->attname))) {
&(tupdesc->attrs[i]->attname)))
{
elog(WARN,
"create: repeated attribute \"%s\"",
tupdesc->attrs[j]->attname.data);
@ -479,16 +492,19 @@ RelationAlreadyExists(Relation pg_class_desc, char relname[])
HeapTuple tup;
/*
* If this is not bootstrap (initdb) time, use the catalog index
* on pg_class.
* If this is not bootstrap (initdb) time, use the catalog index on
* pg_class.
*/
if (!IsBootstrapProcessingMode()) {
if (!IsBootstrapProcessingMode())
{
tup = ClassNameIndexScan(pg_class_desc, relname);
if (HeapTupleIsValid(tup)) {
if (HeapTupleIsValid(tup))
{
pfree(tup);
return ((int) true);
} else
}
else
return ((int) false);
}
@ -499,8 +515,8 @@ RelationAlreadyExists(Relation pg_class_desc, char relname[])
*/
ScanKeyEntryInitialize(&key,
0,
(AttrNumber)Anum_pg_class_relname,
(RegProcedure)NameEqualRegProcedure,
(AttrNumber) Anum_pg_class_relname,
(RegProcedure) NameEqualRegProcedure,
(Datum) relname);
/* ----------------
@ -518,7 +534,7 @@ RelationAlreadyExists(Relation pg_class_desc, char relname[])
* didn't find an existing relation.
* ----------------
*/
tup = heap_getnext(pg_class_scan, 0, (Buffer *)NULL);
tup = heap_getnext(pg_class_scan, 0, (Buffer *) NULL);
/* ----------------
* end the scan and return existance of relation.
@ -580,7 +596,8 @@ AddNewAttributeTuples(Oid new_rel_oid,
* ----------------
*/
dpp = tupdesc->attrs;
for (i = 0; i < natts; i++) {
for (i = 0; i < natts; i++)
{
(*dpp)->attrelid = new_rel_oid;
(*dpp)->attdisbursion = 0;
@ -601,13 +618,14 @@ AddNewAttributeTuples(Oid new_rel_oid,
* ----------------
*/
dpp = HeapAtt;
for (i = 0; i < -1 - FirstLowInvalidHeapAttributeNumber; i++) {
for (i = 0; i < -1 - FirstLowInvalidHeapAttributeNumber; i++)
{
(*dpp)->attrelid = new_rel_oid;
/* (*dpp)->attdisbursion = 0; unneeded */
tup = heap_addheader(Natts_pg_attribute,
ATTRIBUTE_TUPLE_SIZE,
(char *)*dpp);
(char *) *dpp);
heap_insert(rdesc, tup);
@ -645,8 +663,9 @@ AddPgRelationTuple(Relation pg_class_desc,
HeapTuple tup;
Relation idescs[Num_pg_class_indices];
bool isBootstrap;
extern bool ItsSequenceCreation; /* It's hack, I know...
* - vadim 03/28/97 */
extern bool ItsSequenceCreation; /* It's hack, I know... -
* vadim 03/28/97 */
/* ----------------
* first we munge some of the information in our
* uncataloged relation's relation descriptor.
@ -655,10 +674,10 @@ AddPgRelationTuple(Relation pg_class_desc,
new_rel_reltup = new_rel_desc->rd_rel;
/* CHECK should get new_rel_oid first via an insert then use XXX */
/* new_rel_reltup->reltuples = 1; */ /* XXX */
/* new_rel_reltup->reltuples = 1; *//* XXX */
new_rel_reltup->relowner = GetUserId();
if ( ItsSequenceCreation )
if (ItsSequenceCreation)
new_rel_reltup->relkind = RELKIND_SEQUENCE;
else
new_rel_reltup->relkind = RELKIND_RELATION;
@ -689,10 +708,12 @@ AddPgRelationTuple(Relation pg_class_desc,
heap_insert(pg_class_desc, tup);
if (! isBootstrap) {
if (!isBootstrap)
{
/*
* First, open the catalog indices and insert index tuples for
* the new relation.
* First, open the catalog indices and insert index tuples for the
* new relation.
*/
CatalogOpenIndices(Num_pg_class_indices, Name_pg_class_indices, idescs);
@ -718,15 +739,14 @@ addNewRelationType(char *typeName, Oid new_rel_oid)
{
Oid new_type_oid;
/* The sizes are set to oid size because it makes implementing sets MUCH
* easier, and no one (we hope) uses these fields to figure out
* how much space to allocate for the type.
* An oid is the type used for a set definition. When a user
* requests a set, what they actually get is the oid of a tuple in
* the pg_proc catalog, so the size of the "set" is the size
* of an oid.
* Similarly, byval being true makes sets much easier, and
* it isn't used by anything else.
/*
* The sizes are set to oid size because it makes implementing sets
* MUCH easier, and no one (we hope) uses these fields to figure out
* how much space to allocate for the type. An oid is the type used
* for a set definition. When a user requests a set, what they
* actually get is the oid of a tuple in the pg_proc catalog, so the
* size of the "set" is the size of an oid. Similarly, byval being
* true makes sets much easier, and it isn't used by anything else.
* Note the assumption that OIDs are the same size as int4s.
*/
new_type_oid = TypeCreate(typeName, /* type name */
@ -761,6 +781,7 @@ heap_create(char relname[],
Relation pg_class_desc;
Relation new_rel_desc;
Oid new_rel_oid;
/* NameData typeNameData; */
int natts = tupdesc->natts;
@ -782,7 +803,8 @@ heap_create(char relname[],
*/
pg_class_desc = heap_openr(RelationRelationName);
if (RelationAlreadyExists(pg_class_desc, relname)) {
if (RelationAlreadyExists(pg_class_desc, relname))
{
heap_close(pg_class_desc);
elog(WARN, "amcreate: %s relation already exists", relname);
}
@ -825,7 +847,7 @@ heap_create(char relname[],
arch,
natts);
StoreConstraints (new_rel_desc);
StoreConstraints(new_rel_desc);
/* ----------------
* ok, the relation has been cataloged, so close our relations
@ -914,8 +936,9 @@ RelationRemoveInheritance(Relation relation)
* if any subclasses exist, then we disallow the deletion.
* ----------------
*/
tuple = heap_getnext(scan, 0, (Buffer *)NULL);
if (HeapTupleIsValid(tuple)) {
tuple = heap_getnext(scan, 0, (Buffer *) NULL);
if (HeapTupleIsValid(tuple))
{
heap_endscan(scan);
heap_close(catalogRelation);
@ -937,9 +960,11 @@ RelationRemoveInheritance(Relation relation)
1,
&entry);
for (;;) {
tuple = heap_getnext(scan, 0, (Buffer *)NULL);
if (!HeapTupleIsValid(tuple)) {
for (;;)
{
tuple = heap_getnext(scan, 0, (Buffer *) NULL);
if (!HeapTupleIsValid(tuple))
{
break;
}
heap_delete(catalogRelation, &tuple->t_ctid);
@ -963,9 +988,11 @@ RelationRemoveInheritance(Relation relation)
1,
&entry);
for (;;) {
tuple = heap_getnext(scan, 0, (Buffer *)NULL);
if (!HeapTupleIsValid(tuple)) {
for (;;)
{
tuple = heap_getnext(scan, 0, (Buffer *) NULL);
if (!HeapTupleIsValid(tuple))
{
break;
}
heap_delete(catalogRelation, &tuple->t_ctid);
@ -1000,13 +1027,15 @@ RelationRemoveIndexes(Relation relation)
1,
&entry);
for (;;) {
tuple = heap_getnext(scan, 0, (Buffer *)NULL);
if (!HeapTupleIsValid(tuple)) {
for (;;)
{
tuple = heap_getnext(scan, 0, (Buffer *) NULL);
if (!HeapTupleIsValid(tuple))
{
break;
}
index_destroy(((IndexTupleForm)GETSTRUCT(tuple))->indexrelid);
index_destroy(((IndexTupleForm) GETSTRUCT(tuple))->indexrelid);
}
heap_endscan(scan);
@ -1053,7 +1082,8 @@ DeletePgRelationTuple(Relation rdesc)
*/
tup = heap_getnext(pg_class_scan, 0, (Buffer *) NULL);
if (! PointerIsValid(tup)) {
if (!PointerIsValid(tup))
{
heap_endscan(pg_class_scan);
heap_close(pg_class_desc);
elog(WARN, "DeletePgRelationTuple: %s relation nonexistent",
@ -1114,8 +1144,9 @@ DeletePgAttributeTuples(Relation rdesc)
* have been deleted.
* ----------------
*/
while (tup = heap_getnext(pg_attribute_scan, 0, (Buffer *)NULL),
PointerIsValid(tup)) {
while (tup = heap_getnext(pg_attribute_scan, 0, (Buffer *) NULL),
PointerIsValid(tup))
{
heap_delete(pg_attribute_desc, &tup->t_ctid);
}
@ -1182,9 +1213,10 @@ DeletePgTypeTuple(Relation rdesc)
* tuple is not valid then something's wrong.
* ----------------
*/
tup = heap_getnext(pg_type_scan, 0, (Buffer *)NULL);
tup = heap_getnext(pg_type_scan, 0, (Buffer *) NULL);
if (! PointerIsValid(tup)) {
if (!PointerIsValid(tup))
{
heap_endscan(pg_type_scan);
heap_close(pg_type_desc);
elog(WARN, "DeletePgTypeTuple: %s type nonexistent",
@ -1218,9 +1250,10 @@ DeletePgTypeTuple(Relation rdesc)
* the schema.
* ----------------
*/
atttup = heap_getnext(pg_attribute_scan, 0, (Buffer *)NULL);
atttup = heap_getnext(pg_attribute_scan, 0, (Buffer *) NULL);
if (PointerIsValid(atttup)) {
if (PointerIsValid(atttup))
{
Oid relid = ((AttributeTupleForm) GETSTRUCT(atttup))->attrelid;
heap_endscan(pg_type_scan);
@ -1263,8 +1296,8 @@ heap_destroy(char *relname)
* ----------------
*/
rdesc = heap_openr(relname);
if ( rdesc == NULL )
elog (WARN, "Relation %s Does Not Exist!", relname);
if (rdesc == NULL)
elog(WARN, "Relation %s Does Not Exist!", relname);
RelationSetLockForWrite(rdesc);
rid = rdesc->rd_id;
@ -1287,7 +1320,8 @@ heap_destroy(char *relname)
* remove indexes if necessary
* ----------------
*/
if (rdesc->rd_rel->relhasindex) {
if (rdesc->rd_rel->relhasindex)
{
RelationRemoveIndexes(rdesc);
}
@ -1295,13 +1329,14 @@ heap_destroy(char *relname)
* remove rules if necessary
* ----------------
*/
if (rdesc->rd_rules != NULL) {
if (rdesc->rd_rules != NULL)
{
RelationRemoveRules(rid);
}
/* triggers */
if ( rdesc->rd_rel->reltriggers > 0 )
RelationRemoveTriggers (rdesc);
if (rdesc->rd_rel->reltriggers > 0)
RelationRemoveTriggers(rdesc);
/* ----------------
* delete attribute tuples
@ -1327,7 +1362,7 @@ heap_destroy(char *relname)
/*
* release dirty buffers of this relation
*/
ReleaseRelationBuffers (rdesc);
ReleaseRelationBuffers(rdesc);
/* ----------------
* flush the relation from the relcache
@ -1336,13 +1371,13 @@ heap_destroy(char *relname)
RelationIdInvalidateRelationCacheByRelationId(rdesc->rd_id);
*/
RemoveConstraints (rdesc);
RemoveConstraints(rdesc);
/* ----------------
* unlink the relation and finish up.
* ----------------
*/
if ( !(rdesc->rd_istemp) || !(rdesc->rd_tmpunlinked) )
if (!(rdesc->rd_istemp) || !(rdesc->rd_tmpunlinked))
{
smgrunlink(rdesc->rd_rel->relsmgr, rdesc);
}
@ -1353,7 +1388,7 @@ heap_destroy(char *relname)
heap_close(rdesc);
/* ok - flush the relation from the relcache */
RelationForgetRelation (rid);
RelationForgetRelation(rid);
}
/*
@ -1366,7 +1401,7 @@ void
heap_destroyr(Relation rdesc)
{
ReleaseRelationBuffers(rdesc);
if ( !(rdesc->rd_istemp) || !(rdesc->rd_tmpunlinked) )
if (!(rdesc->rd_istemp) || !(rdesc->rd_tmpunlinked))
{
smgrunlink(rdesc->rd_rel->relsmgr, rdesc);
}
@ -1400,14 +1435,15 @@ heap_destroyr(Relation rdesc)
void
InitTempRelList(void)
{
if (tempRels) {
if (tempRels)
{
free(tempRels->rels);
free(tempRels);
}
tempRels = (TempRelList*)malloc(sizeof(TempRelList));
tempRels = (TempRelList *) malloc(sizeof(TempRelList));
tempRels->size = TEMP_REL_LIST_SIZE;
tempRels->rels = (Relation*)malloc(sizeof(Relation) * tempRels->size);
tempRels->rels = (Relation *) malloc(sizeof(Relation) * tempRels->size);
memset(tempRels->rels, 0, sizeof(Relation) * tempRels->size);
tempRels->num = 0;
}
@ -1427,8 +1463,10 @@ RemoveFromTempRelList(Relation r)
if (!tempRels)
return;
for (i=0; i<tempRels->num; i++) {
if (tempRels->rels[i] == r) {
for (i = 0; i < tempRels->num; i++)
{
if (tempRels->rels[i] == r)
{
tempRels->rels[i] = NULL;
break;
}
@ -1446,7 +1484,8 @@ AddToTempRelList(Relation r)
if (!tempRels)
return;
if (tempRels->num == tempRels->size) {
if (tempRels->num == tempRels->size)
{
tempRels->size += TEMP_REL_LIST_SIZE;
tempRels->rels = realloc(tempRels->rels,
sizeof(Relation) * tempRels->size);
@ -1467,7 +1506,8 @@ DestroyTempRels(void)
if (!tempRels)
return;
for (i=0;i<tempRels->num;i++) {
for (i = 0; i < tempRels->num; i++)
{
rdesc = tempRels->rels[i];
/* rdesc may be NULL if it has been removed from the list already */
if (rdesc)
@ -1478,15 +1518,16 @@ DestroyTempRels(void)
tempRels = NULL;
}
extern List *flatten_tlist(List *tlist);
extern List *pg_plan(char *query_string, Oid *typev, int nargs,
QueryTreeList **queryListP, CommandDest dest);
extern List *flatten_tlist(List * tlist);
extern List *
pg_plan(char *query_string, Oid * typev, int nargs,
QueryTreeList ** queryListP, CommandDest dest);
static void
StoreAttrDefault (Relation rel, AttrDefault *attrdef)
StoreAttrDefault(Relation rel, AttrDefault * attrdef)
{
char str[MAX_PARSE_BUFFER];
char cast[2*NAMEDATALEN] = {0};
char cast[2 * NAMEDATALEN] = {0};
AttributeTupleForm atp = rel->rd_att->attrs[attrdef->adnum - 1];
QueryTreeList *queryTree_list;
Query *query;
@ -1504,60 +1545,60 @@ StoreAttrDefault (Relation rel, AttrDefault *attrdef)
extern GlobalMemory CacheCxt;
start:;
sprintf (str, "select %s%s from %.*s", attrdef->adsrc, cast,
sprintf(str, "select %s%s from %.*s", attrdef->adsrc, cast,
NAMEDATALEN, rel->rd_rel->relname.data);
setheapoverride(true);
planTree_list = (List*) pg_plan (str, NULL, 0, &queryTree_list, None);
planTree_list = (List *) pg_plan(str, NULL, 0, &queryTree_list, None);
setheapoverride(false);
query = (Query*) (queryTree_list->qtrees[0]);
query = (Query *) (queryTree_list->qtrees[0]);
if ( length (query->rtable) > 1 ||
flatten_tlist (query->targetList) != NIL )
elog (WARN, "DEFAULT: cannot use attribute(s)");
te = (TargetEntry *) lfirst (query->targetList);
if (length(query->rtable) > 1 ||
flatten_tlist(query->targetList) != NIL)
elog(WARN, "DEFAULT: cannot use attribute(s)");
te = (TargetEntry *) lfirst(query->targetList);
resdom = te->resdom;
expr = te->expr;
if ( IsA (expr, Const) )
if (IsA(expr, Const))
{
if ( ((Const*)expr)->consttype != atp->atttypid )
if (((Const *) expr)->consttype != atp->atttypid)
{
if ( *cast != 0 )
elog (WARN, "DEFAULT: const type mismatched");
sprintf (cast, ":: %s", get_id_typname (atp->atttypid));
if (*cast != 0)
elog(WARN, "DEFAULT: const type mismatched");
sprintf(cast, ":: %s", get_id_typname(atp->atttypid));
goto start;
}
}
else if ( exprType (expr) != atp->atttypid )
elog (WARN, "DEFAULT: type mismatched");
else if (exprType(expr) != atp->atttypid)
elog(WARN, "DEFAULT: type mismatched");
adbin = nodeToString (expr);
oldcxt = MemoryContextSwitchTo ((MemoryContext) CacheCxt);
attrdef->adbin = (char*) palloc (strlen (adbin) + 1);
strcpy (attrdef->adbin, adbin);
(void) MemoryContextSwitchTo (oldcxt);
pfree (adbin);
adbin = nodeToString(expr);
oldcxt = MemoryContextSwitchTo((MemoryContext) CacheCxt);
attrdef->adbin = (char *) palloc(strlen(adbin) + 1);
strcpy(attrdef->adbin, adbin);
(void) MemoryContextSwitchTo(oldcxt);
pfree(adbin);
values[Anum_pg_attrdef_adrelid - 1] = rel->rd_id;
values[Anum_pg_attrdef_adnum - 1] = attrdef->adnum;
values[Anum_pg_attrdef_adbin - 1] = PointerGetDatum (textin (attrdef->adbin));
values[Anum_pg_attrdef_adsrc - 1] = PointerGetDatum (textin (attrdef->adsrc));
adrel = heap_openr (AttrDefaultRelationName);
tuple = heap_formtuple (adrel->rd_att, values, nulls);
CatalogOpenIndices (Num_pg_attrdef_indices, Name_pg_attrdef_indices, idescs);
heap_insert (adrel, tuple);
CatalogIndexInsert (idescs, Num_pg_attrdef_indices, adrel, tuple);
CatalogCloseIndices (Num_pg_attrdef_indices, idescs);
heap_close (adrel);
values[Anum_pg_attrdef_adbin - 1] = PointerGetDatum(textin(attrdef->adbin));
values[Anum_pg_attrdef_adsrc - 1] = PointerGetDatum(textin(attrdef->adsrc));
adrel = heap_openr(AttrDefaultRelationName);
tuple = heap_formtuple(adrel->rd_att, values, nulls);
CatalogOpenIndices(Num_pg_attrdef_indices, Name_pg_attrdef_indices, idescs);
heap_insert(adrel, tuple);
CatalogIndexInsert(idescs, Num_pg_attrdef_indices, adrel, tuple);
CatalogCloseIndices(Num_pg_attrdef_indices, idescs);
heap_close(adrel);
pfree (DatumGetPointer(values[Anum_pg_attrdef_adbin - 1]));
pfree (DatumGetPointer(values[Anum_pg_attrdef_adsrc - 1]));
pfree (tuple);
pfree(DatumGetPointer(values[Anum_pg_attrdef_adbin - 1]));
pfree(DatumGetPointer(values[Anum_pg_attrdef_adsrc - 1]));
pfree(tuple);
}
static void
StoreRelCheck (Relation rel, ConstrCheck *check)
StoreRelCheck(Relation rel, ConstrCheck * check)
{
char str[MAX_PARSE_BUFFER];
QueryTreeList *queryTree_list;
@ -1574,138 +1615,138 @@ StoreRelCheck (Relation rel, ConstrCheck *check)
char nulls[4] = {' ', ' ', ' ', ' '};
extern GlobalMemory CacheCxt;
sprintf (str, "select 1 from %.*s where %s",
sprintf(str, "select 1 from %.*s where %s",
NAMEDATALEN, rel->rd_rel->relname.data, check->ccsrc);
setheapoverride(true);
planTree_list = (List*) pg_plan (str, NULL, 0, &queryTree_list, None);
planTree_list = (List *) pg_plan(str, NULL, 0, &queryTree_list, None);
setheapoverride(false);
query = (Query*) (queryTree_list->qtrees[0]);
query = (Query *) (queryTree_list->qtrees[0]);
if ( length (query->rtable) > 1 )
elog (WARN, "CHECK: only relation %.*s can be referenced",
if (length(query->rtable) > 1)
elog(WARN, "CHECK: only relation %.*s can be referenced",
NAMEDATALEN, rel->rd_rel->relname.data);
plan = (Plan*) lfirst(planTree_list);
plan = (Plan *) lfirst(planTree_list);
qual = plan->qual;
ccbin = nodeToString (qual);
oldcxt = MemoryContextSwitchTo ((MemoryContext) CacheCxt);
check->ccbin = (char*) palloc (strlen (ccbin) + 1);
strcpy (check->ccbin, ccbin);
(void) MemoryContextSwitchTo (oldcxt);
pfree (ccbin);
ccbin = nodeToString(qual);
oldcxt = MemoryContextSwitchTo((MemoryContext) CacheCxt);
check->ccbin = (char *) palloc(strlen(ccbin) + 1);
strcpy(check->ccbin, ccbin);
(void) MemoryContextSwitchTo(oldcxt);
pfree(ccbin);
values[Anum_pg_relcheck_rcrelid - 1] = rel->rd_id;
values[Anum_pg_relcheck_rcname - 1] = PointerGetDatum (namein (check->ccname));
values[Anum_pg_relcheck_rcbin - 1] = PointerGetDatum (textin (check->ccbin));
values[Anum_pg_relcheck_rcsrc - 1] = PointerGetDatum (textin (check->ccsrc));
rcrel = heap_openr (RelCheckRelationName);
tuple = heap_formtuple (rcrel->rd_att, values, nulls);
CatalogOpenIndices (Num_pg_relcheck_indices, Name_pg_relcheck_indices, idescs);
heap_insert (rcrel, tuple);
CatalogIndexInsert (idescs, Num_pg_relcheck_indices, rcrel, tuple);
CatalogCloseIndices (Num_pg_relcheck_indices, idescs);
heap_close (rcrel);
values[Anum_pg_relcheck_rcname - 1] = PointerGetDatum(namein(check->ccname));
values[Anum_pg_relcheck_rcbin - 1] = PointerGetDatum(textin(check->ccbin));
values[Anum_pg_relcheck_rcsrc - 1] = PointerGetDatum(textin(check->ccsrc));
rcrel = heap_openr(RelCheckRelationName);
tuple = heap_formtuple(rcrel->rd_att, values, nulls);
CatalogOpenIndices(Num_pg_relcheck_indices, Name_pg_relcheck_indices, idescs);
heap_insert(rcrel, tuple);
CatalogIndexInsert(idescs, Num_pg_relcheck_indices, rcrel, tuple);
CatalogCloseIndices(Num_pg_relcheck_indices, idescs);
heap_close(rcrel);
pfree (DatumGetPointer(values[Anum_pg_relcheck_rcname - 1]));
pfree (DatumGetPointer(values[Anum_pg_relcheck_rcbin - 1]));
pfree (DatumGetPointer(values[Anum_pg_relcheck_rcsrc - 1]));
pfree (tuple);
pfree(DatumGetPointer(values[Anum_pg_relcheck_rcname - 1]));
pfree(DatumGetPointer(values[Anum_pg_relcheck_rcbin - 1]));
pfree(DatumGetPointer(values[Anum_pg_relcheck_rcsrc - 1]));
pfree(tuple);
return;
}
static void
StoreConstraints (Relation rel)
StoreConstraints(Relation rel)
{
TupleConstr *constr = rel->rd_att->constr;
int i;
if ( !constr )
if (!constr)
return;
if ( constr->num_defval > 0 )
if (constr->num_defval > 0)
{
for (i = 0; i < constr->num_defval; i++)
StoreAttrDefault (rel, &(constr->defval[i]));
StoreAttrDefault(rel, &(constr->defval[i]));
}
if ( constr->num_check > 0 )
if (constr->num_check > 0)
{
for (i = 0; i < constr->num_check; i++)
StoreRelCheck (rel, &(constr->check[i]));
StoreRelCheck(rel, &(constr->check[i]));
}
return;
}
static void
RemoveAttrDefault (Relation rel)
RemoveAttrDefault(Relation rel)
{
Relation adrel;
HeapScanDesc adscan;
ScanKeyData key;
HeapTuple tup;
adrel = heap_openr (AttrDefaultRelationName);
adrel = heap_openr(AttrDefaultRelationName);
ScanKeyEntryInitialize(&key, 0, Anum_pg_attrdef_adrelid,
ObjectIdEqualRegProcedure, rel->rd_id);
RelationSetLockForWrite (adrel);
RelationSetLockForWrite(adrel);
adscan = heap_beginscan(adrel, 0, NowTimeQual, 1, &key);
while (tup = heap_getnext (adscan, 0, (Buffer *)NULL), PointerIsValid(tup))
heap_delete (adrel, &tup->t_ctid);
while (tup = heap_getnext(adscan, 0, (Buffer *) NULL), PointerIsValid(tup))
heap_delete(adrel, &tup->t_ctid);
heap_endscan (adscan);
heap_endscan(adscan);
RelationUnsetLockForWrite (adrel);
heap_close (adrel);
RelationUnsetLockForWrite(adrel);
heap_close(adrel);
}
static void
RemoveRelCheck (Relation rel)
RemoveRelCheck(Relation rel)
{
Relation rcrel;
HeapScanDesc rcscan;
ScanKeyData key;
HeapTuple tup;
rcrel = heap_openr (RelCheckRelationName);
rcrel = heap_openr(RelCheckRelationName);
ScanKeyEntryInitialize(&key, 0, Anum_pg_relcheck_rcrelid,
ObjectIdEqualRegProcedure, rel->rd_id);
RelationSetLockForWrite (rcrel);
RelationSetLockForWrite(rcrel);
rcscan = heap_beginscan(rcrel, 0, NowTimeQual, 1, &key);
while (tup = heap_getnext (rcscan, 0, (Buffer *)NULL), PointerIsValid(tup))
heap_delete (rcrel, &tup->t_ctid);
while (tup = heap_getnext(rcscan, 0, (Buffer *) NULL), PointerIsValid(tup))
heap_delete(rcrel, &tup->t_ctid);
heap_endscan (rcscan);
heap_endscan(rcscan);
RelationUnsetLockForWrite (rcrel);
heap_close (rcrel);
RelationUnsetLockForWrite(rcrel);
heap_close(rcrel);
}
static void
RemoveConstraints (Relation rel)
RemoveConstraints(Relation rel)
{
TupleConstr *constr = rel->rd_att->constr;
if ( !constr )
if (!constr)
return;
if ( constr->num_defval > 0 )
RemoveAttrDefault (rel);
if (constr->num_defval > 0)
RemoveAttrDefault(rel);
if ( constr->num_check > 0 )
RemoveRelCheck (rel);
if (constr->num_check > 0)
RemoveRelCheck(rel);
return;
}

View File

@ -7,7 +7,7 @@
*
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/catalog/index.c,v 1.19 1997/08/22 14:10:26 vadim Exp $
* $Header: /cvsroot/pgsql/src/backend/catalog/index.c,v 1.20 1997/09/07 04:40:19 momjian Exp $
*
*
* INTERFACE ROUTINES
@ -51,9 +51,9 @@
#include <access/istrat.h>
#ifndef HAVE_MEMMOVE
# include <regex/utils.h>
#include <regex/utils.h>
#else
# include <string.h>
#include <string.h>
#endif
/*
@ -63,29 +63,34 @@
#define NTUPLES_PER_PAGE(natts) (BLCKSZ/((natts)*AVG_TUPLE_SIZE))
/* non-export function prototypes */
static Oid RelationNameGetObjectId(char *relationName, Relation pg_class,
static Oid
RelationNameGetObjectId(char *relationName, Relation pg_class,
bool setHasIndexAttribute);
static Oid GetHeapRelationOid(char *heapRelationName, char *indexRelationName);
static TupleDesc BuildFuncTupleDesc(FuncIndexInfo *funcInfo);
static TupleDesc ConstructTupleDescriptor(Oid heapoid, Relation heapRelation,
List *attributeList,
static TupleDesc BuildFuncTupleDesc(FuncIndexInfo * funcInfo);
static TupleDesc
ConstructTupleDescriptor(Oid heapoid, Relation heapRelation,
List * attributeList,
int numatts, AttrNumber attNums[]);
static void ConstructIndexReldesc(Relation indexRelation, Oid amoid);
static Oid UpdateRelationRelation(Relation indexRelation);
static void InitializeAttributeOids(Relation indexRelation,
static void
InitializeAttributeOids(Relation indexRelation,
int numatts,
Oid indexoid);
static void
AppendAttributeTuples(Relation indexRelation, int numatts);
static void UpdateIndexRelation(Oid indexoid, Oid heapoid,
FuncIndexInfo *funcInfo, int natts,
AttrNumber attNums[], Oid classOids[], Node *predicate,
List *attributeList, bool islossy, bool unique);
static void DefaultBuild(Relation heapRelation, Relation indexRelation,
AppendAttributeTuples(Relation indexRelation, int numatts);
static void
UpdateIndexRelation(Oid indexoid, Oid heapoid,
FuncIndexInfo * funcInfo, int natts,
AttrNumber attNums[], Oid classOids[], Node * predicate,
List * attributeList, bool islossy, bool unique);
static void
DefaultBuild(Relation heapRelation, Relation indexRelation,
int numberOfAttributes, AttrNumber attributeNumber[],
IndexStrategy indexStrategy, uint16 parameterCount,
Datum parameter[], FuncIndexInfoPtr funcInfo, PredInfo *predInfo);
Datum parameter[], FuncIndexInfoPtr funcInfo, PredInfo * predInfo);
/* ----------------------------------------------------------------
* sysatts is a structure containing attribute tuple forms
@ -111,17 +116,17 @@ static void DefaultBuild(Relation heapRelation, Relation indexRelation,
* ----------------------------------------------------------------
*/
static FormData_pg_attribute sysatts[] = {
{ 0l, {"ctid"}, 27l, 0l, 6, -1, 0, -1, '\0', '\0', 'i', '\0', '\0' },
{ 0l, {"oid"}, 26l, 0l, 4, -2, 0, -1, '\001', '\0', 'i', '\0', '\0' },
{ 0l, {"xmin"}, 28l, 0l, 4, -3, 0, -1, '\0', '\0', 'i', '\0', '\0' },
{ 0l, {"cmin"}, 29l, 0l, 2, -4, 0, -1, '\001', '\0', 's', '\0', '\0' },
{ 0l, {"xmax"}, 28l, 0l, 4, -5, 0, -1, '\0', '\0', 'i', '\0', '\0' },
{ 0l, {"cmax"}, 29l, 0l, 2, -6, 0, -1, '\001', '\0', 's', '\0', '\0' },
{ 0l, {"chain"}, 27l, 0l, 6, -7, 0, -1, '\0', '\0', 'i', '\0', '\0' },
{ 0l, {"anchor"}, 27l, 0l, 6, -8, 0, -1, '\0', '\0', 'i', '\0', '\0' },
{ 0l, {"tmin"}, 702l, 0l, 4, -9, 0, -1, '\001', '\0', 'i', '\0', '\0' },
{ 0l, {"tmax"}, 702l, 0l, 4, -10, 0, -1, '\001', '\0', 'i', '\0', '\0' },
{ 0l, {"vtype"}, 18l, 0l, 1, -11, 0, -1, '\001', '\0', 'c', '\0', '\0' },
{0l, {"ctid"}, 27l, 0l, 6, -1, 0, -1, '\0', '\0', 'i', '\0', '\0'},
{0l, {"oid"}, 26l, 0l, 4, -2, 0, -1, '\001', '\0', 'i', '\0', '\0'},
{0l, {"xmin"}, 28l, 0l, 4, -3, 0, -1, '\0', '\0', 'i', '\0', '\0'},
{0l, {"cmin"}, 29l, 0l, 2, -4, 0, -1, '\001', '\0', 's', '\0', '\0'},
{0l, {"xmax"}, 28l, 0l, 4, -5, 0, -1, '\0', '\0', 'i', '\0', '\0'},
{0l, {"cmax"}, 29l, 0l, 2, -6, 0, -1, '\001', '\0', 's', '\0', '\0'},
{0l, {"chain"}, 27l, 0l, 6, -7, 0, -1, '\0', '\0', 'i', '\0', '\0'},
{0l, {"anchor"}, 27l, 0l, 6, -8, 0, -1, '\0', '\0', 'i', '\0', '\0'},
{0l, {"tmin"}, 702l, 0l, 4, -9, 0, -1, '\001', '\0', 'i', '\0', '\0'},
{0l, {"tmax"}, 702l, 0l, 4, -10, 0, -1, '\001', '\0', 'i', '\0', '\0'},
{0l, {"vtype"}, 18l, 0l, 1, -11, 0, -1, '\001', '\0', 'c', '\0', '\0'},
};
/* ----------------------------------------------------------------
@ -155,12 +160,15 @@ RelationNameGetObjectId(char *relationName,
* speed this up.
*/
if (!IsBootstrapProcessingMode()) {
if (!IsBootstrapProcessingMode())
{
pg_class_tuple = ClassNameIndexScan(pg_class, relationName);
if (HeapTupleIsValid(pg_class_tuple)) {
if (HeapTupleIsValid(pg_class_tuple))
{
relationObjectId = pg_class_tuple->t_oid;
pfree(pg_class_tuple);
} else
}
else
relationObjectId = InvalidOid;
return (relationObjectId);
@ -184,9 +192,12 @@ RelationNameGetObjectId(char *relationName,
*/
pg_class_tuple = heap_getnext(pg_class_scan, 0, &buffer);
if (! HeapTupleIsValid(pg_class_tuple)) {
if (!HeapTupleIsValid(pg_class_tuple))
{
relationObjectId = InvalidOid;
} else {
}
else
{
relationObjectId = pg_class_tuple->t_oid;
ReleaseBuffer(buffer);
}
@ -244,7 +255,7 @@ GetHeapRelationOid(char *heapRelationName, char *indexRelationName)
* check that the heap relation exists..
* ----------------
*/
if (! OidIsValid(heapoid))
if (!OidIsValid(heapoid))
elog(WARN, "Cannot create index on '%s': relation does not exist",
heapRelationName);
@ -258,7 +269,7 @@ GetHeapRelationOid(char *heapRelationName, char *indexRelationName)
}
static TupleDesc
BuildFuncTupleDesc(FuncIndexInfo *funcInfo)
BuildFuncTupleDesc(FuncIndexInfo * funcInfo)
{
HeapTuple tuple;
TupleDesc funcTupDesc;
@ -289,24 +300,24 @@ BuildFuncTupleDesc(FuncIndexInfo *funcInfo)
if (!HeapTupleIsValid(tuple))
func_error("BuildFuncTupleDesc", funcname, nargs, argtypes);
retType = ((Form_pg_proc)GETSTRUCT(tuple))->prorettype;
retType = ((Form_pg_proc) GETSTRUCT(tuple))->prorettype;
/*
* Look up the return type in pg_type for the type length.
*/
tuple = SearchSysCacheTuple(TYPOID,
ObjectIdGetDatum(retType),
0,0,0);
0, 0, 0);
if (!HeapTupleIsValid(tuple))
elog(WARN,"Function %s return type does not exist",FIgetname(funcInfo));
elog(WARN, "Function %s return type does not exist", FIgetname(funcInfo));
/*
* Assign some of the attributes values. Leave the rest as 0.
*/
funcTupDesc->attrs[0]->attlen = ((TypeTupleForm)GETSTRUCT(tuple))->typlen;
funcTupDesc->attrs[0]->attlen = ((TypeTupleForm) GETSTRUCT(tuple))->typlen;
funcTupDesc->attrs[0]->atttypid = retType;
funcTupDesc->attrs[0]->attnum = 1;
funcTupDesc->attrs[0]->attbyval = ((TypeTupleForm)GETSTRUCT(tuple))->typbyval;
funcTupDesc->attrs[0]->attbyval = ((TypeTupleForm) GETSTRUCT(tuple))->typbyval;
/*
* make the attributes name the same as the functions
@ -323,7 +334,7 @@ BuildFuncTupleDesc(FuncIndexInfo *funcInfo)
static TupleDesc
ConstructTupleDescriptor(Oid heapoid,
Relation heapRelation,
List *attributeList,
List * attributeList,
int numatts,
AttrNumber attNums[])
{
@ -357,7 +368,8 @@ ConstructTupleDescriptor(Oid heapoid,
* tuple forms or the relation tuple descriptor
* ----------------
*/
for (i = 0; i < numatts; i += 1) {
for (i = 0; i < numatts; i += 1)
{
/* ----------------
* get the attribute number and make sure it's valid
@ -367,11 +379,14 @@ ConstructTupleDescriptor(Oid heapoid,
if (atnum > natts)
elog(WARN, "Cannot create index: attribute %d does not exist",
atnum);
if (attributeList) {
IndexKey = (IndexElem*) lfirst(attributeList);
if (attributeList)
{
IndexKey = (IndexElem *) lfirst(attributeList);
attributeList = lnext(attributeList);
IndexKeyType = IndexKey->tname;
} else {
}
else
{
IndexKeyType = NULL;
}
@ -381,7 +396,8 @@ ConstructTupleDescriptor(Oid heapoid,
* determine which tuple descriptor to copy
* ----------------
*/
if (!AttrNumberIsForUserDefinedAttr(atnum)) {
if (!AttrNumberIsForUserDefinedAttr(atnum))
{
/* ----------------
* here we are indexing on a system attribute (-1...-12)
@ -390,13 +406,15 @@ ConstructTupleDescriptor(Oid heapoid,
* tuple descriptor information for system attributes.
* ----------------
*/
if (atnum <= FirstLowInvalidHeapAttributeNumber || atnum >= 0 )
if (atnum <= FirstLowInvalidHeapAttributeNumber || atnum >= 0)
elog(WARN, "Cannot create index on system attribute: attribute number out of range (%d)", atnum);
atind = (-atnum) - 1;
from = (char *) (& sysatts[atind]);
from = (char *) (&sysatts[atind]);
} else {
}
else
{
/* ----------------
* here we are indexing on a normal attribute (1...n)
* ----------------
@ -405,7 +423,7 @@ ConstructTupleDescriptor(Oid heapoid,
heapTupDesc = RelationGetTupleDescriptor(heapRelation);
atind = AttrNumberGetAttrOffset(atnum);
from = (char *) (heapTupDesc->attrs[ atind ]);
from = (char *) (heapTupDesc->attrs[atind]);
}
/* ----------------
@ -414,33 +432,37 @@ ConstructTupleDescriptor(Oid heapoid,
* ----------------
*/
to = (char *) (indexTupDesc->attrs[ i ]);
to = (char *) (indexTupDesc->attrs[i]);
memcpy(to, from, ATTRIBUTE_TUPLE_SIZE);
((AttributeTupleForm) to)->attnum = i+1;
((AttributeTupleForm) to)->attnum = i + 1;
((AttributeTupleForm) to)->attcacheoff = -1;
((AttributeTupleForm) to)->attnotnull = false;
((AttributeTupleForm) to)->atthasdef = false;
/* if the keytype is defined, we need to change the tuple form's
atttypid & attlen field to match that of the key's type */
if (IndexKeyType != NULL) {
/*
* if the keytype is defined, we need to change the tuple form's
* atttypid & attlen field to match that of the key's type
*/
if (IndexKeyType != NULL)
{
HeapTuple tup;
tup = SearchSysCacheTuple(TYPNAME,
PointerGetDatum(IndexKeyType->name),
0,0,0);
if(!HeapTupleIsValid(tup))
0, 0, 0);
if (!HeapTupleIsValid(tup))
elog(WARN, "create index: type '%s' undefined",
IndexKeyType->name);
((AttributeTupleForm) to)->atttypid = tup->t_oid;
((AttributeTupleForm) to)->attbyval =
((TypeTupleForm) ((char *)tup + tup->t_hoff))->typbyval;
((TypeTupleForm) ((char *) tup + tup->t_hoff))->typbyval;
if (IndexKeyType->typlen > 0)
((AttributeTupleForm) to)->attlen = IndexKeyType->typlen;
else ((AttributeTupleForm) to)->attlen =
((TypeTupleForm) ((char *)tup + tup->t_hoff))->typlen;
else
((AttributeTupleForm) to)->attlen =
((TypeTupleForm) ((char *) tup + tup->t_hoff))->typlen;
}
@ -490,13 +512,14 @@ AccessMethodObjectIdGetAccessMethodTupleForm(Oid accessMethodObjectId)
pg_am_desc = heap_openr(AccessMethodRelationName);
pg_am_scan = heap_beginscan(pg_am_desc, 0, NowTimeQual, 1, &key);
pg_am_tuple = heap_getnext(pg_am_scan, 0, (Buffer *)NULL);
pg_am_tuple = heap_getnext(pg_am_scan, 0, (Buffer *) NULL);
/* ----------------
* return NULL if not found
* ----------------
*/
if (! HeapTupleIsValid(pg_am_tuple)) {
if (!HeapTupleIsValid(pg_am_tuple))
{
heap_endscan(pg_am_scan);
heap_close(pg_am_desc);
return (NULL);
@ -506,7 +529,7 @@ AccessMethodObjectIdGetAccessMethodTupleForm(Oid accessMethodObjectId)
* if found am tuple, then copy the form and return the copy
* ----------------
*/
form = (Form_pg_am)palloc(sizeof *form);
form = (Form_pg_am) palloc(sizeof *form);
memcpy(form, GETSTRUCT(pg_am_tuple), sizeof *form);
heap_endscan(pg_am_scan);
@ -534,7 +557,7 @@ ConstructIndexReldesc(Relation indexRelation, Oid amoid)
if (!CacheCxt)
CacheCxt = CreateGlobalMemory("Cache");
oldcxt = MemoryContextSwitchTo((MemoryContext)CacheCxt);
oldcxt = MemoryContextSwitchTo((MemoryContext) CacheCxt);
indexRelation->rd_am =
AccessMethodObjectIdGetAccessMethodTupleForm(amoid);
@ -591,7 +614,8 @@ UpdateRelationRelation(Relation indexRelation)
* just before exiting.
*/
if (!IsBootstrapProcessingMode()) {
if (!IsBootstrapProcessingMode())
{
CatalogOpenIndices(Num_pg_class_indices, Name_pg_class_indices, idescs);
CatalogIndexInsert(idescs, Num_pg_class_indices, pg_class, tuple);
CatalogCloseIndices(Num_pg_class_indices, idescs);
@ -601,7 +625,7 @@ UpdateRelationRelation(Relation indexRelation)
pfree(tuple);
heap_close(pg_class);
return(tupleOid);
return (tupleOid);
}
/* ----------------------------------------------------------------
@ -637,9 +661,9 @@ AppendAttributeTuples(Relation indexRelation, int numatts)
bool hasind;
Relation idescs[Num_pg_attr_indices];
Datum value[ Natts_pg_attribute ];
char nullv[ Natts_pg_attribute ];
char replace[ Natts_pg_attribute ];
Datum value[Natts_pg_attribute];
char nullv[Natts_pg_attribute];
char replace[Natts_pg_attribute];
TupleDesc indexTupDesc;
int i;
@ -663,18 +687,19 @@ AppendAttributeTuples(Relation indexRelation, int numatts)
* XXX For now, only change the ATTNUM attribute value
* ----------------
*/
replace[ Anum_pg_attribute_attnum - 1 ] = 'r';
replace[ Anum_pg_attribute_attcacheoff - 1 ] = 'r';
replace[Anum_pg_attribute_attnum - 1] = 'r';
replace[Anum_pg_attribute_attcacheoff - 1] = 'r';
value[ Anum_pg_attribute_attnum - 1 ] = Int16GetDatum(1);
value[ Anum_pg_attribute_attcacheoff - 1 ] = Int32GetDatum(-1);
value[Anum_pg_attribute_attnum - 1] = Int16GetDatum(1);
value[Anum_pg_attribute_attcacheoff - 1] = Int32GetDatum(-1);
tuple = heap_addheader(Natts_pg_attribute,
sizeof *(indexRelation->rd_att->attrs[0]),
(char *)(indexRelation->rd_att->attrs[0]));
(char *) (indexRelation->rd_att->attrs[0]));
hasind = false;
if (!IsBootstrapProcessingMode() && pg_attribute->rd_rel->relhasindex) {
if (!IsBootstrapProcessingMode() && pg_attribute->rd_rel->relhasindex)
{
hasind = true;
CatalogOpenIndices(Num_pg_attr_indices, Name_pg_attr_indices, idescs);
}
@ -701,16 +726,17 @@ AppendAttributeTuples(Relation indexRelation, int numatts)
*/
indexTupDesc = RelationGetTupleDescriptor(indexRelation);
for (i = 1; i < numatts; i += 1) {
for (i = 1; i < numatts; i += 1)
{
/* ----------------
* process the remaining attributes...
* ----------------
*/
memmove(GETSTRUCT(tuple),
(char *)indexTupDesc->attrs[i],
sizeof (FormData_pg_attribute));
(char *) indexTupDesc->attrs[i],
sizeof(FormData_pg_attribute));
value[ Anum_pg_attribute_attnum - 1 ] = Int16GetDatum(i + 1);
value[Anum_pg_attribute_attnum - 1] = Int16GetDatum(i + 1);
newtuple = heap_modifytuple(tuple,
InvalidBuffer,
@ -751,12 +777,12 @@ AppendAttributeTuples(Relation indexRelation, int numatts)
static void
UpdateIndexRelation(Oid indexoid,
Oid heapoid,
FuncIndexInfo *funcInfo,
FuncIndexInfo * funcInfo,
int natts,
AttrNumber attNums[],
Oid classOids[],
Node *predicate,
List *attributeList,
Node * predicate,
List * attributeList,
bool islossy,
bool unique)
{
@ -764,7 +790,8 @@ UpdateIndexRelation(Oid indexoid,
IndexElem *IndexKey;
char *predString;
text *predText;
int predLen, itupLen;
int predLen,
itupLen;
Relation pg_index;
HeapTuple tuple;
int i;
@ -774,18 +801,21 @@ UpdateIndexRelation(Oid indexoid,
* index-predicate (if any) in string form
* ----------------
*/
if (predicate != NULL) {
if (predicate != NULL)
{
predString = nodeToString(predicate);
predText = (text *)fmgr(F_TEXTIN, predString);
predText = (text *) fmgr(F_TEXTIN, predString);
pfree(predString);
} else {
predText = (text *)fmgr(F_TEXTIN, "");
}
else
{
predText = (text *) fmgr(F_TEXTIN, "");
}
predLen = VARSIZE(predText);
itupLen = predLen + sizeof(FormData_pg_index);
indexForm = (IndexTupleForm) palloc(itupLen);
memmove((char *)& indexForm->indpred, (char *)predText, predLen);
memmove((char *) &indexForm->indpred, (char *) predText, predLen);
/* ----------------
* store the oid information into the index tuple form
@ -799,10 +829,10 @@ UpdateIndexRelation(Oid indexoid,
indexForm->indisunique = unique;
indexForm->indhaskeytype = 0;
while (attributeList != NIL )
while (attributeList != NIL)
{
IndexKey = (IndexElem*) lfirst(attributeList);
if ( IndexKey->tname != NULL )
IndexKey = (IndexElem *) lfirst(attributeList);
if (IndexKey->tname != NULL)
{
indexForm->indhaskeytype = 1;
break;
@ -810,23 +840,25 @@ UpdateIndexRelation(Oid indexoid,
attributeList = lnext(attributeList);
}
memset((char *)& indexForm->indkey[0], 0, sizeof indexForm->indkey);
memset((char *)& indexForm->indclass[0], 0, sizeof indexForm->indclass);
memset((char *) &indexForm->indkey[0], 0, sizeof indexForm->indkey);
memset((char *) &indexForm->indclass[0], 0, sizeof indexForm->indclass);
/* ----------------
* copy index key and op class information
* ----------------
*/
for (i = 0; i < natts; i += 1) {
for (i = 0; i < natts; i += 1)
{
indexForm->indkey[i] = attNums[i];
indexForm->indclass[i] = classOids[i];
}
/*
* If we have a functional index, add all attribute arguments
*/
if (PointerIsValid(funcInfo))
{
for (i=1; i < FIgetnArgs(funcInfo); i++)
for (i = 1; i < FIgetnArgs(funcInfo); i++)
indexForm->indkey[i] = attNums[i];
}
@ -845,7 +877,7 @@ UpdateIndexRelation(Oid indexoid,
*/
tuple = heap_addheader(Natts_pg_index,
itupLen,
(char *)indexForm);
(char *) indexForm);
/* ----------------
* insert the tuple into the pg_index
@ -869,7 +901,7 @@ UpdateIndexRelation(Oid indexoid,
* ----------------------------------------------------------------
*/
void
UpdateIndexPredicate(Oid indexoid, Node *oldPred, Node *predicate)
UpdateIndexPredicate(Oid indexoid, Node * oldPred, Node * predicate)
{
Node *newPred;
char *predString;
@ -897,21 +929,25 @@ UpdateIndexPredicate(Oid indexoid, Node *oldPred, Node *predicate)
* changing "a>2 OR TRUE" to "TRUE". --Nels, Jan '93
*/
newPred = NULL;
if (predicate != NULL) {
if (predicate != NULL)
{
newPred =
(Node*)make_orclause(lcons(make_andclause((List*)predicate),
lcons(make_andclause((List*)oldPred),
(Node *) make_orclause(lcons(make_andclause((List *) predicate),
lcons(make_andclause((List *) oldPred),
NIL)));
newPred = (Node*)cnfify((Expr*)newPred, true);
newPred = (Node *) cnfify((Expr *) newPred, true);
}
/* translate the index-predicate to string form */
if (newPred != NULL) {
if (newPred != NULL)
{
predString = nodeToString(newPred);
predText = (text *)fmgr(F_TEXTIN, predString);
predText = (text *) fmgr(F_TEXTIN, predString);
pfree(predString);
} else {
predText = (text *)fmgr(F_TEXTIN, "");
}
else
{
predText = (text *) fmgr(F_TEXTIN, "");
}
/* open the index system catalog relation */
@ -925,8 +961,9 @@ UpdateIndexPredicate(Oid indexoid, Node *oldPred, Node *predicate)
tuple = heap_getnext(scan, 0, &buffer);
heap_endscan(scan);
for (i = 0; i < Natts_pg_index; i++) {
nulls[i] = heap_attisnull(tuple, i+1) ? 'n' : ' ';
for (i = 0; i < Natts_pg_index; i++)
{
nulls[i] = heap_attisnull(tuple, i + 1) ? 'n' : ' ';
replace[i] = ' ';
values[i] = (Datum) NULL;
}
@ -985,13 +1022,16 @@ InitIndexStrategy(int numatts,
CacheCxt = CreateGlobalMemory("Cache");
strategy = (IndexStrategy)
MemoryContextAlloc((MemoryContext)CacheCxt, strsize);
MemoryContextAlloc((MemoryContext) CacheCxt, strsize);
if (amsupport > 0) {
if (amsupport > 0)
{
strsize = numatts * (amsupport * sizeof(RegProcedure));
support = (RegProcedure *) MemoryContextAlloc((MemoryContext)CacheCxt,
support = (RegProcedure *) MemoryContextAlloc((MemoryContext) CacheCxt,
strsize);
} else {
}
else
{
support = (RegProcedure *) NULL;
}
@ -1025,15 +1065,15 @@ InitIndexStrategy(int numatts,
void
index_create(char *heapRelationName,
char *indexRelationName,
FuncIndexInfo *funcInfo,
List *attributeList,
FuncIndexInfo * funcInfo,
List * attributeList,
Oid accessMethodObjectId,
int numatts,
AttrNumber attNums[],
Oid classObjectId[],
uint16 parameterCount,
Datum *parameter,
Node *predicate,
Datum * parameter,
Node * predicate,
bool islossy,
bool unique)
{
@ -1118,7 +1158,8 @@ index_create(char *heapRelationName,
PointerGetDatum(FIgetArglist(funcInfo)),
0);
if (!HeapTupleIsValid(proc_tup)) {
if (!HeapTupleIsValid(proc_tup))
{
func_error("index_create", FIgetname(funcInfo),
FIgetnArgs(funcInfo),
FIgetArglist(funcInfo));
@ -1151,7 +1192,7 @@ index_create(char *heapRelationName,
numatts, attNums, classObjectId, predicate,
attributeList, islossy, unique);
predInfo = (PredInfo*)palloc(sizeof(PredInfo));
predInfo = (PredInfo *) palloc(sizeof(PredInfo));
predInfo->pred = predicate;
predInfo->oldPred = NULL;
@ -1162,16 +1203,19 @@ index_create(char *heapRelationName,
InitIndexStrategy(numatts, indexRelation, accessMethodObjectId);
/*
* If this is bootstrap (initdb) time, then we don't actually
* fill in the index yet. We'll be creating more indices and classes
* later, so we delay filling them in until just before we're done
* with bootstrapping. Otherwise, we call the routine that constructs
* the index. The heap and index relations are closed by index_build().
* If this is bootstrap (initdb) time, then we don't actually fill in
* the index yet. We'll be creating more indices and classes later,
* so we delay filling them in until just before we're done with
* bootstrapping. Otherwise, we call the routine that constructs the
* index. The heap and index relations are closed by index_build().
*/
if (IsBootstrapProcessingMode()) {
if (IsBootstrapProcessingMode())
{
index_register(heapRelationName, indexRelationName, numatts, attNums,
parameterCount, parameter, funcInfo, predInfo);
} else {
}
else
{
heapRelation = heap_openr(heapRelationName);
index_build(heapRelation, indexRelation, numatts, attNums,
parameterCount, parameter, funcInfo, predInfo);
@ -1208,7 +1252,7 @@ index_destroy(Oid indexId)
ObjectIdGetDatum(indexId));;
scan = heap_beginscan(catalogRelation, 0, NowTimeQual, 1, &entry);
tuple = heap_getnext(scan, 0, (Buffer *)NULL);
tuple = heap_getnext(scan, 0, (Buffer *) NULL);
AssertState(HeapTupleIsValid(tuple));
@ -1226,8 +1270,9 @@ index_destroy(Oid indexId)
scan = heap_beginscan(catalogRelation, 0, NowTimeQual, 1, &entry);
while (tuple = heap_getnext(scan, 0, (Buffer *)NULL),
HeapTupleIsValid(tuple)) {
while (tuple = heap_getnext(scan, 0, (Buffer *) NULL),
HeapTupleIsValid(tuple))
{
heap_delete(catalogRelation, &tuple->t_ctid);
}
@ -1243,8 +1288,9 @@ index_destroy(Oid indexId)
entry.sk_attno = Anum_pg_index_indexrelid;
scan = heap_beginscan(catalogRelation, 0, NowTimeQual, 1, &entry);
tuple = heap_getnext(scan, 0, (Buffer *)NULL);
if (! HeapTupleIsValid(tuple)) {
tuple = heap_getnext(scan, 0, (Buffer *) NULL);
if (!HeapTupleIsValid(tuple))
{
elog(NOTICE, "IndexRelationDestroy: %s's INDEX tuple missing",
RelationGetRelationName(indexRelation));
}
@ -1275,7 +1321,7 @@ FormIndexDatum(int numberOfAttributes,
HeapTuple heapTuple,
TupleDesc heapDescriptor,
Buffer buffer,
Datum *datum,
Datum * datum,
char *nullv,
FuncIndexInfoPtr fInfo)
{
@ -1290,19 +1336,20 @@ FormIndexDatum(int numberOfAttributes,
* ----------------
*/
for (i = 1; i <= numberOfAttributes; i += 1) {
for (i = 1; i <= numberOfAttributes; i += 1)
{
offset = AttrNumberGetAttrOffset(i);
datum[ offset ] =
PointerGetDatum( GetIndexValue(heapTuple,
datum[offset] =
PointerGetDatum(GetIndexValue(heapTuple,
heapDescriptor,
offset,
attributeNumber,
fInfo,
&isNull,
buffer) );
buffer));
nullv[ offset ] = (isNull) ? 'n' : ' ';
nullv[offset] = (isNull) ? 'n' : ' ';
}
}
@ -1326,13 +1373,13 @@ UpdateStats(Oid relid, long reltuples, bool hasindex)
Relation idescs[Num_pg_class_indices];
static ScanKeyData key[1] = {
{ 0, ObjectIdAttributeNumber, ObjectIdEqualRegProcedure }
{0, ObjectIdAttributeNumber, ObjectIdEqualRegProcedure}
};
Datum values[Natts_pg_class];
char nulls[Natts_pg_class];
char replace[Natts_pg_class];
fmgr_info(ObjectIdEqualRegProcedure, (func_ptr *) &key[0].sk_func,
fmgr_info(ObjectIdEqualRegProcedure, (func_ptr *) & key[0].sk_func,
&key[0].sk_nargs);
/* ----------------
@ -1363,7 +1410,8 @@ UpdateStats(Oid relid, long reltuples, bool hasindex)
* ----------------
*/
pg_class = heap_openr(RelationRelationName);
if (! RelationIsValid(pg_class)) {
if (!RelationIsValid(pg_class))
{
elog(WARN, "UpdateStats: could not open RELATION relation");
}
key[0].sk_argument = ObjectIdGetDatum(relid);
@ -1371,7 +1419,8 @@ UpdateStats(Oid relid, long reltuples, bool hasindex)
pg_class_scan =
heap_beginscan(pg_class, 0, NowTimeQual, 1, key);
if (! HeapScanIsValid(pg_class_scan)) {
if (!HeapScanIsValid(pg_class_scan))
{
heap_close(pg_class);
elog(WARN, "UpdateStats: cannot scan RELATION relation");
}
@ -1387,17 +1436,18 @@ UpdateStats(Oid relid, long reltuples, bool hasindex)
relpages = RelationGetNumberOfBlocks(whichRel);
/*
* We shouldn't have to do this, but we do... Modify the reldesc
* in place with the new values so that the cache contains the
* latest copy.
* We shouldn't have to do this, but we do... Modify the reldesc in
* place with the new values so that the cache contains the latest
* copy.
*/
whichRel->rd_rel->relhasindex = hasindex;
whichRel->rd_rel->relpages = relpages;
whichRel->rd_rel->reltuples = reltuples;
for (i = 0; i < Natts_pg_class; i++) {
nulls[i] = heap_attisnull(htup, i+1) ? 'n' : ' ';
for (i = 0; i < Natts_pg_class; i++)
{
nulls[i] = heap_attisnull(htup, i + 1) ? 'n' : ' ';
replace[i] = ' ';
values[i] = (Datum) NULL;
}
@ -1406,25 +1456,28 @@ UpdateStats(Oid relid, long reltuples, bool hasindex)
* If reltuples wasn't supplied take an educated guess.
*/
if (reltuples == 0)
reltuples = relpages*NTUPLES_PER_PAGE(whichRel->rd_rel->relnatts);
reltuples = relpages * NTUPLES_PER_PAGE(whichRel->rd_rel->relnatts);
if (IsBootstrapProcessingMode()) {
if (IsBootstrapProcessingMode())
{
/*
* At bootstrap time, we don't need to worry about concurrency
* or visibility of changes, so we cheat.
* At bootstrap time, we don't need to worry about concurrency or
* visibility of changes, so we cheat.
*/
rd_rel = (Form_pg_class) GETSTRUCT(htup);
rd_rel->relpages = relpages;
rd_rel->reltuples = reltuples;
rd_rel->relhasindex = hasindex;
} else {
}
else
{
/* during normal processing, work harder */
replace[Anum_pg_class_relpages - 1] = 'r';
values[Anum_pg_class_relpages - 1] = (Datum)relpages;
values[Anum_pg_class_relpages - 1] = (Datum) relpages;
replace[Anum_pg_class_reltuples - 1] = 'r';
values[Anum_pg_class_reltuples - 1] = (Datum)reltuples;
values[Anum_pg_class_reltuples - 1] = (Datum) reltuples;
replace[Anum_pg_class_relhasindex - 1] = 'r';
values[Anum_pg_class_relhasindex - 1] = CharGetDatum(hasindex);
@ -1448,8 +1501,8 @@ UpdateStats(Oid relid, long reltuples, bool hasindex)
* -------------------------
*/
void
FillDummyExprContext(ExprContext *econtext,
TupleTableSlot *slot,
FillDummyExprContext(ExprContext * econtext,
TupleTableSlot * slot,
TupleDesc tupdesc,
Buffer buffer)
{
@ -1479,7 +1532,7 @@ DefaultBuild(Relation heapRelation,
uint16 parameterCount, /* not used */
Datum parameter[], /* not used */
FuncIndexInfoPtr funcInfo,
PredInfo *predInfo)
PredInfo * predInfo)
{
HeapScanDesc scan;
HeapTuple heapTuple;
@ -1490,11 +1543,14 @@ DefaultBuild(Relation heapRelation,
TupleDesc indexDescriptor;
Datum *datum;
char *nullv;
long reltuples, indtuples;
long reltuples,
indtuples;
#ifndef OMIT_PARTIAL_INDEX
ExprContext *econtext;
TupleTable tupleTable;
TupleTableSlot *slot;
#endif
Node *predicate;
Node *oldPred;
@ -1524,18 +1580,20 @@ DefaultBuild(Relation heapRelation,
nullv = (char *) palloc(numberOfAttributes * sizeof *nullv);
/*
* If this is a predicate (partial) index, we will need to evaluate the
* predicate using ExecQual, which requires the current tuple to be in a
* slot of a TupleTable. In addition, ExecQual must have an ExprContext
* referring to that slot. Here, we initialize dummy TupleTable and
* ExprContext objects for this purpose. --Nels, Feb '92
* If this is a predicate (partial) index, we will need to evaluate
* the predicate using ExecQual, which requires the current tuple to
* be in a slot of a TupleTable. In addition, ExecQual must have an
* ExprContext referring to that slot. Here, we initialize dummy
* TupleTable and ExprContext objects for this purpose. --Nels, Feb
* '92
*/
predicate = predInfo->pred;
oldPred = predInfo->oldPred;
#ifndef OMIT_PARTIAL_INDEX
if (predicate != NULL || oldPred != NULL) {
if (predicate != NULL || oldPred != NULL)
{
tupleTable = ExecCreateTupleTable(1);
slot = ExecAllocTableSlot(tupleTable);
econtext = makeNode(ExprContext);
@ -1569,7 +1627,8 @@ DefaultBuild(Relation heapRelation,
* ----------------
*/
while (heapTuple = heap_getnext(scan, 0, &buffer),
HeapTupleIsValid(heapTuple)) {
HeapTupleIsValid(heapTuple))
{
reltuples++;
@ -1577,23 +1636,29 @@ DefaultBuild(Relation heapRelation,
* If oldPred != NULL, this is an EXTEND INDEX command, so skip
* this tuple if it was already in the existing partial index
*/
if (oldPred != NULL) {
if (oldPred != NULL)
{
#ifndef OMIT_PARTIAL_INDEX
/*SetSlotContents(slot, heapTuple); */
/* SetSlotContents(slot, heapTuple); */
slot->val = heapTuple;
if (ExecQual((List*)oldPred, econtext) == true) {
if (ExecQual((List *) oldPred, econtext) == true)
{
indtuples++;
continue;
}
#endif /* OMIT_PARTIAL_INDEX */
}
/* Skip this tuple if it doesn't satisfy the partial-index predicate */
if (predicate != NULL) {
/*
* Skip this tuple if it doesn't satisfy the partial-index
* predicate
*/
if (predicate != NULL)
{
#ifndef OMIT_PARTIAL_INDEX
/*SetSlotContents(slot, heapTuple); */
/* SetSlotContents(slot, heapTuple); */
slot->val = heapTuple;
if (ExecQual((List*)predicate, econtext) == false)
if (ExecQual((List *) predicate, econtext) == false)
continue;
#endif /* OMIT_PARTIAL_INDEX */
}
@ -1623,13 +1688,15 @@ DefaultBuild(Relation heapRelation,
insertResult = index_insert(indexRelation, datum, nullv,
&(heapTuple->t_ctid), heapRelation);
if (insertResult) pfree(insertResult);
if (insertResult)
pfree(insertResult);
pfree(indexTuple);
}
heap_endscan(scan);
if (predicate != NULL || oldPred != NULL) {
if (predicate != NULL || oldPred != NULL)
{
#ifndef OMIT_PARTIAL_INDEX
ExecDestroyTupleTable(tupleTable, false);
#endif /* OMIT_PARTIAL_INDEX */
@ -1639,16 +1706,18 @@ DefaultBuild(Relation heapRelation,
pfree(datum);
/*
* Okay, now update the reltuples and relpages statistics for both
* the heap relation and the index. These statistics are used by
* the planner to choose a scan type. They are maintained generally
* by the vacuum daemon, but we update them here to make the index
* useful as soon as possible.
* Okay, now update the reltuples and relpages statistics for both the
* heap relation and the index. These statistics are used by the
* planner to choose a scan type. They are maintained generally by
* the vacuum daemon, but we update them here to make the index useful
* as soon as possible.
*/
UpdateStats(heapRelation->rd_id, reltuples, true);
UpdateStats(indexRelation->rd_id, indtuples, false);
if (oldPred != NULL) {
if (indtuples == reltuples) predicate = NULL;
if (oldPred != NULL)
{
if (indtuples == reltuples)
predicate = NULL;
UpdateIndexPredicate(indexRelation->rd_id, oldPred, predicate);
}
}
@ -1663,9 +1732,9 @@ index_build(Relation heapRelation,
int numberOfAttributes,
AttrNumber attributeNumber[],
uint16 parameterCount,
Datum *parameter,
FuncIndexInfo *funcInfo,
PredInfo *predInfo)
Datum * parameter,
FuncIndexInfo * funcInfo,
PredInfo * predInfo)
{
RegProcedure procedure;
@ -1717,12 +1786,13 @@ IndexIsUnique(Oid indexId)
tuple = SearchSysCacheTuple(INDEXRELID,
ObjectIdGetDatum(indexId),
0,0,0);
if(!HeapTupleIsValid(tuple)) {
0, 0, 0);
if (!HeapTupleIsValid(tuple))
{
elog(WARN, "IndexIsUnique: can't find index id %d",
indexId);
}
index = (IndexTupleForm)GETSTRUCT(tuple);
index = (IndexTupleForm) GETSTRUCT(tuple);
Assert(index->indexrelid == indexId);
return index->indisunique;
@ -1752,23 +1822,24 @@ IndexIsUniqueNoCache(Oid indexId)
pg_index = heap_openr(IndexRelationName);
ScanKeyEntryInitialize(&skey[0], (bits16)0x0,
ScanKeyEntryInitialize(&skey[0], (bits16) 0x0,
Anum_pg_index_indexrelid,
(RegProcedure)ObjectIdEqualRegProcedure,
(RegProcedure) ObjectIdEqualRegProcedure,
ObjectIdGetDatum(indexId));
scandesc = heap_beginscan(pg_index, 0, SelfTimeQual, 1, skey);
tuple = heap_getnext(scandesc, 0, NULL);
if(!HeapTupleIsValid(tuple)) {
if (!HeapTupleIsValid(tuple))
{
elog(WARN, "IndexIsUniqueNoCache: can't find index id %d",
indexId);
}
index = (IndexTupleForm)GETSTRUCT(tuple);
index = (IndexTupleForm) GETSTRUCT(tuple);
Assert(index->indexrelid == indexId);
isunique = index->indisunique;
heap_endscan (scandesc);
heap_close (pg_index);
heap_endscan(scandesc);
heap_close(pg_index);
return isunique;
}

View File

@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/catalog/indexing.c,v 1.11 1997/08/31 09:56:18 vadim Exp $
* $Header: /cvsroot/pgsql/src/backend/catalog/indexing.c,v 1.12 1997/09/07 04:40:21 momjian Exp $
*
*-------------------------------------------------------------------------
*/
@ -46,22 +46,23 @@
char *Name_pg_attr_indices[Num_pg_attr_indices] = {AttributeNameIndex,
AttributeNumIndex,
AttributeRelidIndex};
char *Name_pg_proc_indices[Num_pg_proc_indices] = { ProcedureNameIndex,
AttributeRelidIndex};
char *Name_pg_proc_indices[Num_pg_proc_indices] = {ProcedureNameIndex,
ProcedureOidIndex,
ProcedureSrcIndex};
char *Name_pg_type_indices[Num_pg_type_indices] = { TypeNameIndex,
TypeOidIndex};
char *Name_pg_class_indices[Num_pg_class_indices]= { ClassNameIndex,
ClassOidIndex};
char *Name_pg_attrdef_indices[Num_pg_attrdef_indices]= { AttrDefaultIndex };
ProcedureSrcIndex};
char *Name_pg_type_indices[Num_pg_type_indices] = {TypeNameIndex,
TypeOidIndex};
char *Name_pg_class_indices[Num_pg_class_indices] = {ClassNameIndex,
ClassOidIndex};
char *Name_pg_attrdef_indices[Num_pg_attrdef_indices] = {AttrDefaultIndex};
char *Name_pg_relcheck_indices[Num_pg_relcheck_indices]= { RelCheckIndex };
char *Name_pg_relcheck_indices[Num_pg_relcheck_indices] = {RelCheckIndex};
char *Name_pg_trigger_indices[Num_pg_trigger_indices]= { TriggerRelidIndex };
char *Name_pg_trigger_indices[Num_pg_trigger_indices] = {TriggerRelidIndex};
static HeapTuple CatalogIndexFetchTuple(Relation heapRelation,
static HeapTuple
CatalogIndexFetchTuple(Relation heapRelation,
Relation idesc,
ScanKey skey);
@ -77,7 +78,7 @@ CatalogOpenIndices(int nIndices, char *names[], Relation idescs[])
{
int i;
for (i=0; i<nIndices; i++)
for (i = 0; i < nIndices; i++)
{
idescs[i] = index_openr(names[i]);
}
@ -87,11 +88,11 @@ CatalogOpenIndices(int nIndices, char *names[], Relation idescs[])
* This is the inverse routine to CatalogOpenIndices()
*/
void
CatalogCloseIndices(int nIndices, Relation *idescs)
CatalogCloseIndices(int nIndices, Relation * idescs)
{
int i;
for (i=0; i<nIndices; i++)
for (i = 0; i < nIndices; i++)
index_close(idescs[i]);
}
@ -102,7 +103,7 @@ CatalogCloseIndices(int nIndices, Relation *idescs)
* each catalog index.
*/
void
CatalogIndexInsert(Relation *idescs,
CatalogIndexInsert(Relation * idescs,
int nIndices,
Relation heapRelation,
HeapTuple heapTuple)
@ -113,13 +114,14 @@ CatalogIndexInsert(Relation *idescs,
Datum datum;
int natts;
AttrNumber *attnumP;
FuncIndexInfo finfo, *finfoP;
FuncIndexInfo finfo,
*finfoP;
char nulls[INDEX_MAX_KEYS];
int i;
heapDescriptor = RelationGetTupleDescriptor(heapRelation);
for (i=0; i<nIndices; i++)
for (i = 0; i < nIndices; i++)
{
TupleDesc indexDescriptor;
InsertIndexResult indexRes;
@ -127,16 +129,15 @@ CatalogIndexInsert(Relation *idescs,
indexDescriptor = RelationGetTupleDescriptor(idescs[i]);
pgIndexTup = SearchSysCacheTuple(INDEXRELID,
Int32GetDatum(idescs[i]->rd_id),
0,0,0);
0, 0, 0);
Assert(pgIndexTup);
pgIndexP = (IndexTupleForm)GETSTRUCT(pgIndexTup);
pgIndexP = (IndexTupleForm) GETSTRUCT(pgIndexTup);
/*
* Compute the number of attributes we are indexing upon.
* very important - can't assume one if this is a functional
* index.
* Compute the number of attributes we are indexing upon. very
* important - can't assume one if this is a functional index.
*/
for (attnumP=(&pgIndexP->indkey[0]), natts=0;
for (attnumP = (&pgIndexP->indkey[0]), natts = 0;
*attnumP != InvalidAttrNumber;
attnumP++, natts++)
;
@ -150,10 +151,10 @@ CatalogIndexInsert(Relation *idescs,
finfoP = &finfo;
}
else
finfoP = (FuncIndexInfo *)NULL;
finfoP = (FuncIndexInfo *) NULL;
FormIndexDatum(natts,
(AttrNumber *)&pgIndexP->indkey[0],
(AttrNumber *) & pgIndexP->indkey[0],
heapTuple,
heapDescriptor,
InvalidBuffer,
@ -163,7 +164,8 @@ CatalogIndexInsert(Relation *idescs,
indexRes = index_insert(idescs[i], &datum, nulls,
&(heapTuple->t_ctid), heapRelation);
if (indexRes) pfree(indexRes);
if (indexRes)
pfree(indexRes);
}
}
@ -187,9 +189,11 @@ CatalogHasIndex(char *catName, Oid catId)
if (IsBootstrapProcessingMode())
return false;
if (IsInitProcessingMode()) {
for (i = 0; IndexedCatalogNames[i] != NULL; i++) {
if ( strcmp(IndexedCatalogNames[i], catName) == 0)
if (IsInitProcessingMode())
{
for (i = 0; IndexedCatalogNames[i] != NULL; i++)
{
if (strcmp(IndexedCatalogNames[i], catName) == 0)
return (true);
}
return (false);
@ -199,12 +203,13 @@ CatalogHasIndex(char *catName, Oid catId)
htup = ClassOidIndexScan(pg_class, catId);
heap_close(pg_class);
if (! HeapTupleIsValid(htup)) {
if (!HeapTupleIsValid(htup))
{
elog(NOTICE, "CatalogHasIndex: no relation with oid %d", catId);
return false;
}
pgRelP = (Form_pg_class)GETSTRUCT(htup);
pgRelP = (Form_pg_class) GETSTRUCT(htup);
return (pgRelP->relhasindex);
}
@ -227,21 +232,25 @@ CatalogIndexFetchTuple(Relation heapRelation,
Buffer buffer;
sd = index_beginscan(idesc, false, 1, skey);
tuple = (HeapTuple)NULL;
tuple = (HeapTuple) NULL;
do {
do
{
indexRes = index_getnext(sd, ForwardScanDirection);
if (indexRes) {
if (indexRes)
{
ItemPointer iptr;
iptr = &indexRes->heap_iptr;
tuple = heap_fetch(heapRelation, NowTimeQual, iptr, &buffer);
pfree(indexRes);
} else
}
else
break;
} while (!HeapTupleIsValid(tuple));
if (HeapTupleIsValid(tuple)) {
if (HeapTupleIsValid(tuple))
{
tuple = heap_copytuple(tuple);
ReleaseBuffer(buffer);
}
@ -269,10 +278,10 @@ AttributeNameIndexScan(Relation heapRelation,
keyarg = mkoidname(relid, attname);
ScanKeyEntryInitialize(&skey,
(bits16)0x0,
(AttrNumber)1,
(RegProcedure)OidNameEqRegProcedure,
(Datum)keyarg);
(bits16) 0x0,
(AttrNumber) 1,
(RegProcedure) OidNameEqRegProcedure,
(Datum) keyarg);
idesc = index_openr(AttributeNameIndex);
tuple = CatalogIndexFetchTuple(heapRelation, idesc, &skey);
@ -293,12 +302,12 @@ AttributeNumIndexScan(Relation heapRelation,
OidInt2 keyarg;
HeapTuple tuple;
keyarg = mkoidint2(relid, (uint16)attnum);
keyarg = mkoidint2(relid, (uint16) attnum);
ScanKeyEntryInitialize(&skey,
(bits16)0x0,
(AttrNumber)1,
(RegProcedure)OidInt2EqRegProcedure,
(Datum)keyarg);
(bits16) 0x0,
(AttrNumber) 1,
(RegProcedure) OidInt2EqRegProcedure,
(Datum) keyarg);
idesc = index_openr(AttributeNumIndex);
tuple = CatalogIndexFetchTuple(heapRelation, idesc, &skey);
@ -317,10 +326,10 @@ ProcedureOidIndexScan(Relation heapRelation, Oid procId)
HeapTuple tuple;
ScanKeyEntryInitialize(&skey,
(bits16)0x0,
(AttrNumber)1,
(RegProcedure)ObjectIdEqualRegProcedure,
(Datum)procId);
(bits16) 0x0,
(AttrNumber) 1,
(RegProcedure) ObjectIdEqualRegProcedure,
(Datum) procId);
idesc = index_openr(ProcedureOidIndex);
tuple = CatalogIndexFetchTuple(heapRelation, idesc, &skey);
@ -336,71 +345,87 @@ HeapTuple
ProcedureNameIndexScan(Relation heapRelation,
char *procName,
int nargs,
Oid *argTypes)
Oid * argTypes)
{
Relation idesc;
ScanKeyData skey;
HeapTuple tuple; /* tuple being tested */
HeapTuple return_tuple; /* The tuple pointer we eventually return */
HeapTuple return_tuple; /* The tuple pointer we eventually
* return */
IndexScanDesc sd;
RetrieveIndexResult indexRes;
Buffer buffer;
Form_pg_proc pgProcP;
bool ScanComplete;
/* The index scan is complete, i.e. we've scanned everything there
is to scan.
/*
* The index scan is complete, i.e. we've scanned everything there is
* to scan.
*/
bool FoundMatch;
/* In scanning pg_proc, we have found a row that meets our search
criteria.
/*
* In scanning pg_proc, we have found a row that meets our search
* criteria.
*/
ScanKeyEntryInitialize(&skey,
(bits16)0x0,
(AttrNumber)1,
(RegProcedure)NameEqualRegProcedure,
(Datum)procName);
(bits16) 0x0,
(AttrNumber) 1,
(RegProcedure) NameEqualRegProcedure,
(Datum) procName);
idesc = index_openr(ProcedureNameIndex);
sd = index_beginscan(idesc, false, 1, &skey);
/*
* for now, we do the work usually done by CatalogIndexFetchTuple
* by hand, so that we can check that the other keys match. when
* for now, we do the work usually done by CatalogIndexFetchTuple by
* hand, so that we can check that the other keys match. when
* multi-key indices are added, they will be used here.
*/
tuple = (HeapTuple) NULL; /* initial value */
ScanComplete = false; /* Scan hasn't begun yet */
FoundMatch = false; /* No match yet; haven't even looked. */
while (!FoundMatch && !ScanComplete) {
while (!FoundMatch && !ScanComplete)
{
indexRes = index_getnext(sd, ForwardScanDirection);
if (indexRes) {
if (indexRes)
{
ItemPointer iptr;
iptr = &indexRes->heap_iptr;
tuple = heap_fetch(heapRelation, NowTimeQual, iptr, &buffer);
pfree(indexRes);
if (HeapTupleIsValid(tuple)) {
/* Here's a row for a procedure that has the sought procedure
name. To be a match, though, we need it to have the
right number and type of arguments too, so we check that
now.
if (HeapTupleIsValid(tuple))
{
/*
* Here's a row for a procedure that has the sought
* procedure name. To be a match, though, we need it to
* have the right number and type of arguments too, so we
* check that now.
*/
pgProcP = (Form_pg_proc)GETSTRUCT(tuple);
pgProcP = (Form_pg_proc) GETSTRUCT(tuple);
if (pgProcP->pronargs == nargs &&
oid8eq(&(pgProcP->proargtypes[0]), argTypes))
FoundMatch = true;
else ReleaseBuffer(buffer);
else
ReleaseBuffer(buffer);
}
} else ScanComplete = true;
}
else
ScanComplete = true;
}
if (FoundMatch) {
if (FoundMatch)
{
Assert(HeapTupleIsValid(tuple));
return_tuple = heap_copytuple(tuple);
ReleaseBuffer(buffer);
} else return_tuple = (HeapTuple)NULL;
}
else
return_tuple = (HeapTuple) NULL;
index_endscan(sd);
index_close(idesc);
@ -411,7 +436,7 @@ ProcedureNameIndexScan(Relation heapRelation,
HeapTuple
ProcedureSrcIndexScan(Relation heapRelation, text *procSrc)
ProcedureSrcIndexScan(Relation heapRelation, text * procSrc)
{
Relation idesc;
IndexScanDesc sd;
@ -421,25 +446,28 @@ ProcedureSrcIndexScan(Relation heapRelation, text *procSrc)
Buffer buffer;
ScanKeyEntryInitialize(&skey,
(bits16)0x0,
(AttrNumber)Anum_pg_proc_prosrc,
(RegProcedure)TextEqualRegProcedure,
(Datum)procSrc);
(bits16) 0x0,
(AttrNumber) Anum_pg_proc_prosrc,
(RegProcedure) TextEqualRegProcedure,
(Datum) procSrc);
idesc = index_openr(ProcedureSrcIndex);
sd = index_beginscan(idesc, false, 1, &skey);
indexRes = index_getnext(sd, ForwardScanDirection);
if (indexRes) {
if (indexRes)
{
ItemPointer iptr;
iptr = &indexRes->heap_iptr;
tuple = heap_fetch(heapRelation, NowTimeQual, iptr, &buffer);
pfree(indexRes);
} else
tuple = (HeapTuple)NULL;
}
else
tuple = (HeapTuple) NULL;
if (HeapTupleIsValid(tuple)) {
if (HeapTupleIsValid(tuple))
{
tuple = heap_copytuple(tuple);
ReleaseBuffer(buffer);
}
@ -457,10 +485,10 @@ TypeOidIndexScan(Relation heapRelation, Oid typeId)
HeapTuple tuple;
ScanKeyEntryInitialize(&skey,
(bits16)0x0,
(AttrNumber)1,
(RegProcedure)ObjectIdEqualRegProcedure,
(Datum)typeId);
(bits16) 0x0,
(AttrNumber) 1,
(RegProcedure) ObjectIdEqualRegProcedure,
(Datum) typeId);
idesc = index_openr(TypeOidIndex);
tuple = CatalogIndexFetchTuple(heapRelation, idesc, &skey);
@ -478,10 +506,10 @@ TypeNameIndexScan(Relation heapRelation, char *typeName)
HeapTuple tuple;
ScanKeyEntryInitialize(&skey,
(bits16)0x0,
(AttrNumber)1,
(RegProcedure)NameEqualRegProcedure,
(Datum)typeName);
(bits16) 0x0,
(AttrNumber) 1,
(RegProcedure) NameEqualRegProcedure,
(Datum) typeName);
idesc = index_openr(TypeNameIndex);
tuple = CatalogIndexFetchTuple(heapRelation, idesc, &skey);
@ -499,10 +527,10 @@ ClassNameIndexScan(Relation heapRelation, char *relName)
HeapTuple tuple;
ScanKeyEntryInitialize(&skey,
(bits16)0x0,
(AttrNumber)1,
(RegProcedure)NameEqualRegProcedure,
(Datum)relName);
(bits16) 0x0,
(AttrNumber) 1,
(RegProcedure) NameEqualRegProcedure,
(Datum) relName);
idesc = index_openr(ClassNameIndex);
@ -520,10 +548,10 @@ ClassOidIndexScan(Relation heapRelation, Oid relId)
HeapTuple tuple;
ScanKeyEntryInitialize(&skey,
(bits16)0x0,
(AttrNumber)1,
(RegProcedure)ObjectIdEqualRegProcedure,
(Datum)relId);
(bits16) 0x0,
(AttrNumber) 1,
(RegProcedure) ObjectIdEqualRegProcedure,
(Datum) relId);
idesc = index_openr(ClassOidIndex);
tuple = CatalogIndexFetchTuple(heapRelation, idesc, &skey);

View File

@ -7,7 +7,7 @@
*
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/catalog/pg_aggregate.c,v 1.5 1997/07/24 20:11:47 momjian Exp $
* $Header: /cvsroot/pgsql/src/backend/catalog/pg_aggregate.c,v 1.6 1997/09/07 04:40:24 momjian Exp $
*
*-------------------------------------------------------------------------
*/
@ -24,9 +24,9 @@
#include <catalog/pg_aggregate.h>
#include <miscadmin.h>
#ifndef HAVE_MEMMOVE
# include <regex/utils.h>
#include <regex/utils.h>
#else
# include <string.h>
#include <string.h>
#endif
/* ----------------
@ -91,16 +91,17 @@ AggregateCreate(char *aggName,
tup = SearchSysCacheTuple(TYPNAME,
PointerGetDatum(aggbasetypeName),
0,0,0);
if(!HeapTupleIsValid(tup))
elog(WARN, "AggregateCreate: Type '%s' undefined",aggbasetypeName);
0, 0, 0);
if (!HeapTupleIsValid(tup))
elog(WARN, "AggregateCreate: Type '%s' undefined", aggbasetypeName);
xbase = tup->t_oid;
if (aggtransfn1Name) {
if (aggtransfn1Name)
{
tup = SearchSysCacheTuple(TYPNAME,
PointerGetDatum(aggtransfn1typeName),
0,0,0);
if(!HeapTupleIsValid(tup))
0, 0, 0);
if (!HeapTupleIsValid(tup))
elog(WARN, "AggregateCreate: Type '%s' undefined",
aggtransfn1typeName);
xret1 = tup->t_oid;
@ -112,7 +113,7 @@ AggregateCreate(char *aggName,
Int32GetDatum(2),
PointerGetDatum(fnArgs),
0);
if(!HeapTupleIsValid(tup))
if (!HeapTupleIsValid(tup))
elog(WARN, "AggregateCreate: '%s('%s', '%s') does not exist",
aggtransfn1Name, aggtransfn1typeName, aggbasetypeName);
if (((Form_pg_proc) GETSTRUCT(tup))->prorettype != xret1)
@ -125,11 +126,12 @@ AggregateCreate(char *aggName,
elog(WARN, "AggregateCreate: bogus function '%s'", aggfinalfnName);
}
if (aggtransfn2Name) {
if (aggtransfn2Name)
{
tup = SearchSysCacheTuple(TYPNAME,
PointerGetDatum(aggtransfn2typeName),
0,0,0);
if(!HeapTupleIsValid(tup))
0, 0, 0);
if (!HeapTupleIsValid(tup))
elog(WARN, "AggregateCreate: Type '%s' undefined",
aggtransfn2typeName);
xret2 = tup->t_oid;
@ -141,7 +143,7 @@ AggregateCreate(char *aggName,
Int32GetDatum(1),
PointerGetDatum(fnArgs),
0);
if(!HeapTupleIsValid(tup))
if (!HeapTupleIsValid(tup))
elog(WARN, "AggregateCreate: '%s'('%s') does not exist",
aggtransfn2Name, aggtransfn2typeName);
if (((Form_pg_proc) GETSTRUCT(tup))->prorettype != xret2)
@ -149,12 +151,12 @@ AggregateCreate(char *aggName,
aggtransfn2Name, aggtransfn2typeName);
xfn2 = tup->t_oid;
if (!OidIsValid(xfn2) || !OidIsValid(xret2))
elog(WARN, "AggregateCreate: bogus function '%s'",aggfinalfnName);
elog(WARN, "AggregateCreate: bogus function '%s'", aggfinalfnName);
}
tup = SearchSysCacheTuple(AGGNAME, PointerGetDatum(aggName),
ObjectIdGetDatum(xbase),
0,0);
0, 0);
if (HeapTupleIsValid(tup))
elog(WARN,
"AggregateCreate: aggregate '%s' with base type '%s' already exists",
@ -167,7 +169,8 @@ AggregateCreate(char *aggName,
if ((!aggtransfn1Name || !aggtransfn2Name) && aggfinalfnName)
elog(WARN, "AggregateCreate: Aggregate cannot have final function without both transition functions");
if (aggfinalfnName) {
if (aggfinalfnName)
{
fnArgs[0] = xret1;
fnArgs[1] = xret2;
tup = SearchSysCacheTuple(PRONAME,
@ -175,7 +178,7 @@ AggregateCreate(char *aggName,
Int32GetDatum(2),
PointerGetDatum(fnArgs),
0);
if(!HeapTupleIsValid(tup))
if (!HeapTupleIsValid(tup))
elog(WARN, "AggregateCreate: '%s'('%s','%s') does not exist",
aggfinalfnName, aggtransfn1typeName, aggtransfn2typeName);
ffn = tup->t_oid;
@ -194,56 +197,60 @@ AggregateCreate(char *aggName,
elog(WARN, "AggregateCreate: transition function 2 MUST have an initial value");
/* initialize nulls and values */
for(i=0; i < Natts_pg_aggregate; i++) {
for (i = 0; i < Natts_pg_aggregate; i++)
{
nulls[i] = ' ';
values[i] = (Datum)NULL;
values[i] = (Datum) NULL;
}
values[Anum_pg_aggregate_aggname-1] = PointerGetDatum(aggName);
values[Anum_pg_aggregate_aggowner-1] =
values[Anum_pg_aggregate_aggname - 1] = PointerGetDatum(aggName);
values[Anum_pg_aggregate_aggowner - 1] =
Int32GetDatum(GetUserId());
values[Anum_pg_aggregate_aggtransfn1-1] =
values[Anum_pg_aggregate_aggtransfn1 - 1] =
ObjectIdGetDatum(xfn1);
values[Anum_pg_aggregate_aggtransfn2-1] =
values[Anum_pg_aggregate_aggtransfn2 - 1] =
ObjectIdGetDatum(xfn2);
values[Anum_pg_aggregate_aggfinalfn-1] =
values[Anum_pg_aggregate_aggfinalfn - 1] =
ObjectIdGetDatum(ffn);
values[Anum_pg_aggregate_aggbasetype-1] =
values[Anum_pg_aggregate_aggbasetype - 1] =
ObjectIdGetDatum(xbase);
if (!OidIsValid(xfn1)) {
values[Anum_pg_aggregate_aggtranstype1-1] =
if (!OidIsValid(xfn1))
{
values[Anum_pg_aggregate_aggtranstype1 - 1] =
ObjectIdGetDatum(InvalidOid);
values[Anum_pg_aggregate_aggtranstype2-1] =
values[Anum_pg_aggregate_aggtranstype2 - 1] =
ObjectIdGetDatum(xret2);
values[Anum_pg_aggregate_aggfinaltype-1] =
values[Anum_pg_aggregate_aggfinaltype - 1] =
ObjectIdGetDatum(xret2);
}
else if (!OidIsValid(xfn2)) {
values[Anum_pg_aggregate_aggtranstype1-1] =
else if (!OidIsValid(xfn2))
{
values[Anum_pg_aggregate_aggtranstype1 - 1] =
ObjectIdGetDatum(xret1);
values[Anum_pg_aggregate_aggtranstype2-1] =
values[Anum_pg_aggregate_aggtranstype2 - 1] =
ObjectIdGetDatum(InvalidOid);
values[Anum_pg_aggregate_aggfinaltype-1] =
values[Anum_pg_aggregate_aggfinaltype - 1] =
ObjectIdGetDatum(xret1);
}
else {
values[Anum_pg_aggregate_aggtranstype1-1] =
else
{
values[Anum_pg_aggregate_aggtranstype1 - 1] =
ObjectIdGetDatum(xret1);
values[Anum_pg_aggregate_aggtranstype2-1] =
values[Anum_pg_aggregate_aggtranstype2 - 1] =
ObjectIdGetDatum(xret2);
values[Anum_pg_aggregate_aggfinaltype-1] =
values[Anum_pg_aggregate_aggfinaltype - 1] =
ObjectIdGetDatum(fret);
}
if (agginitval1)
values[Anum_pg_aggregate_agginitval1-1] = PointerGetDatum(textin(agginitval1));
values[Anum_pg_aggregate_agginitval1 - 1] = PointerGetDatum(textin(agginitval1));
else
nulls[Anum_pg_aggregate_agginitval1-1] = 'n';
nulls[Anum_pg_aggregate_agginitval1 - 1] = 'n';
if (agginitval2)
values[Anum_pg_aggregate_agginitval2-1] = PointerGetDatum(textin(agginitval2));
values[Anum_pg_aggregate_agginitval2 - 1] = PointerGetDatum(textin(agginitval2));
else
nulls[Anum_pg_aggregate_agginitval2-1] = 'n';
nulls[Anum_pg_aggregate_agginitval2 - 1] = 'n';
if (!RelationIsValid(aggdesc = heap_openr(AggregateRelationName)))
elog(WARN, "AggregateCreate: could not open '%s'",
@ -261,14 +268,15 @@ AggregateCreate(char *aggName,
}
char *
AggNameGetInitVal(char *aggName, Oid basetype, int xfuncno, bool *isNull)
AggNameGetInitVal(char *aggName, Oid basetype, int xfuncno, bool * isNull)
{
HeapTuple tup;
Relation aggRel;
int initValAttno;
Oid transtype;
text *textInitVal;
char *strInitVal, *initVal;
char *strInitVal,
*initVal;
Assert(PointerIsValid(aggName));
Assert(PointerIsValid(isNull));
@ -277,15 +285,18 @@ AggNameGetInitVal(char *aggName, Oid basetype, int xfuncno, bool *isNull)
tup = SearchSysCacheTuple(AGGNAME,
PointerGetDatum(aggName),
PointerGetDatum(basetype),
0,0);
0, 0);
if (!HeapTupleIsValid(tup))
elog(WARN, "AggNameGetInitVal: cache lookup failed for aggregate '%s'",
aggName);
if (xfuncno == 1) {
if (xfuncno == 1)
{
transtype = ((Form_pg_aggregate) GETSTRUCT(tup))->aggtranstype1;
initValAttno = Anum_pg_aggregate_agginitval1;
}
else /* can only be 1 or 2 */ {
else
/* can only be 1 or 2 */
{
transtype = ((Form_pg_aggregate) GETSTRUCT(tup))->aggtranstype2;
initValAttno = Anum_pg_aggregate_agginitval2;
}
@ -294,28 +305,32 @@ AggNameGetInitVal(char *aggName, Oid basetype, int xfuncno, bool *isNull)
if (!RelationIsValid(aggRel))
elog(WARN, "AggNameGetInitVal: could not open \"%-.*s\"",
AggregateRelationName);
/*
* must use fastgetattr in case one or other of the init values is NULL
* must use fastgetattr in case one or other of the init values is
* NULL
*/
textInitVal = (text *) fastgetattr(tup, initValAttno,
RelationGetTupleDescriptor(aggRel),
isNull);
if (!PointerIsValid(textInitVal))
*isNull = true;
if (*isNull) {
if (*isNull)
{
heap_close(aggRel);
return((char *) NULL);
return ((char *) NULL);
}
strInitVal = textout(textInitVal);
heap_close(aggRel);
tup = SearchSysCacheTuple(TYPOID, ObjectIdGetDatum(transtype),
0,0,0);
if (!HeapTupleIsValid(tup)) {
0, 0, 0);
if (!HeapTupleIsValid(tup))
{
pfree(strInitVal);
elog(WARN, "AggNameGetInitVal: cache lookup failed on aggregate transition function return type");
}
initVal = fmgr(((TypeTupleForm) GETSTRUCT(tup))->typinput, strInitVal, -1);
pfree(strInitVal);
return(initVal);
return (initVal);
}

View File

@ -7,7 +7,7 @@
*
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/catalog/pg_operator.c,v 1.11 1997/08/18 20:52:04 momjian Exp $
* $Header: /cvsroot/pgsql/src/backend/catalog/pg_operator.c,v 1.12 1997/09/07 04:40:27 momjian Exp $
*
* NOTES
* these routines moved here from commands/define.c and somewhat cleaned up.
@ -26,28 +26,33 @@
#include <fmgr.h>
#include <miscadmin.h>
#ifndef HAVE_MEMMOVE
# include <regex/utils.h>
#include <regex/utils.h>
#else
# include <string.h>
#include <string.h>
#endif
static Oid OperatorGetWithOpenRelation(Relation pg_operator_desc,
static Oid
OperatorGetWithOpenRelation(Relation pg_operator_desc,
const char *operatorName,
Oid leftObjectId,
Oid rightObjectId );
static Oid OperatorGet(char *operatorName,
Oid rightObjectId);
static Oid
OperatorGet(char *operatorName,
char *leftTypeName,
char *rightTypeName );
char *rightTypeName);
static Oid OperatorShellMakeWithOpenRelation(Relation pg_operator_desc,
static Oid
OperatorShellMakeWithOpenRelation(Relation pg_operator_desc,
char *operatorName,
Oid leftObjectId,
Oid rightObjectId );
static Oid OperatorShellMake(char *operatorName,
Oid rightObjectId);
static Oid
OperatorShellMake(char *operatorName,
char *leftTypeName,
char *rightTypeName );
char *rightTypeName);
static void OperatorDef(char *operatorName,
static void
OperatorDef(char *operatorName,
int definedOK,
char *leftTypeName,
char *rightTypeName,
@ -60,8 +65,8 @@ static void OperatorDef(char *operatorName,
char *oinName,
bool canHash,
char *leftSortName,
char *rightSortName );
static void OperatorUpd(Oid baseId , Oid commId , Oid negId );
char *rightSortName);
static void OperatorUpd(Oid baseId, Oid commId, Oid negId);
/* ----------------------------------------------------------------
* OperatorGetWithOpenRelation
@ -85,9 +90,9 @@ OperatorGetWithOpenRelation(Relation pg_operator_desc,
HeapTuple tup;
static ScanKeyData opKey[3] = {
{ 0, Anum_pg_operator_oprname, NameEqualRegProcedure },
{ 0, Anum_pg_operator_oprleft, ObjectIdEqualRegProcedure },
{ 0, Anum_pg_operator_oprright, ObjectIdEqualRegProcedure },
{0, Anum_pg_operator_oprname, NameEqualRegProcedure},
{0, Anum_pg_operator_oprleft, ObjectIdEqualRegProcedure},
{0, Anum_pg_operator_oprright, ObjectIdEqualRegProcedure},
};
fmgr_info(NameEqualRegProcedure,
@ -159,14 +164,16 @@ OperatorGet(char *operatorName,
* Note: types must be defined before operators
* ----------------
*/
if (leftTypeName) {
if (leftTypeName)
{
leftObjectId = TypeGet(leftTypeName, &leftDefined);
if (!OidIsValid(leftObjectId) || !leftDefined)
elog(WARN, "OperatorGet: left type '%s' nonexistent",leftTypeName);
elog(WARN, "OperatorGet: left type '%s' nonexistent", leftTypeName);
}
if (rightTypeName) {
if (rightTypeName)
{
rightObjectId = TypeGet(rightTypeName, &rightDefined);
if (!OidIsValid(rightObjectId) || !rightDefined)
@ -217,8 +224,8 @@ OperatorShellMakeWithOpenRelation(Relation pg_operator_desc,
{
register int i;
HeapTuple tup;
Datum values[ Natts_pg_operator ];
char nulls[ Natts_pg_operator ];
Datum values[Natts_pg_operator];
char nulls[Natts_pg_operator];
Oid operatorObjectId;
TupleDesc tupDesc;
@ -226,9 +233,10 @@ OperatorShellMakeWithOpenRelation(Relation pg_operator_desc,
* initialize our nulls[] and values[] arrays
* ----------------
*/
for (i = 0; i < Natts_pg_operator; ++i) {
for (i = 0; i < Natts_pg_operator; ++i)
{
nulls[i] = ' ';
values[i] = (Datum)NULL; /* redundant, but safe */
values[i] = (Datum) NULL; /* redundant, but safe */
}
/* ----------------
@ -240,7 +248,7 @@ OperatorShellMakeWithOpenRelation(Relation pg_operator_desc,
values[i++] = Int32GetDatum(GetUserId());
values[i++] = (Datum) (uint16) 0;
values[i++] = (Datum)'b'; /* fill oprkind with a bogus value */
values[i++] = (Datum) 'b'; /* fill oprkind with a bogus value */
values[i++] = (Datum) (bool) 0;
values[i++] = (Datum) (bool) 0;
@ -442,16 +450,17 @@ OperatorDef(char *operatorName,
char *leftSortName,
char *rightSortName)
{
register i, j;
register i,
j;
Relation pg_operator_desc;
HeapScanDesc pg_operator_scan;
HeapTuple tup;
Buffer buffer;
ItemPointerData itemPointerData;
char nulls[ Natts_pg_operator ];
char replaces[ Natts_pg_operator ];
Datum values[ Natts_pg_operator ];
char nulls[Natts_pg_operator];
char replaces[Natts_pg_operator];
Datum values[Natts_pg_operator];
Oid other_oid = 0;
Oid operatorObjectId;
Oid leftTypeId = InvalidOid;
@ -466,9 +475,9 @@ OperatorDef(char *operatorName,
TupleDesc tupDesc;
static ScanKeyData opKey[3] = {
{ 0, Anum_pg_operator_oprname, NameEqualRegProcedure },
{ 0, Anum_pg_operator_oprleft, ObjectIdEqualRegProcedure },
{ 0, Anum_pg_operator_oprright, ObjectIdEqualRegProcedure },
{0, Anum_pg_operator_oprname, NameEqualRegProcedure},
{0, Anum_pg_operator_oprleft, ObjectIdEqualRegProcedure},
{0, Anum_pg_operator_oprright, ObjectIdEqualRegProcedure},
};
fmgr_info(NameEqualRegProcedure,
@ -496,8 +505,9 @@ OperatorDef(char *operatorName,
(OidIsValid(rightTypeId && rightDefined))))
elog(WARN, "OperatorGet: no argument types??");
for (i = 0; i < Natts_pg_operator; ++i) {
values[i] = (Datum)NULL;
for (i = 0; i < Natts_pg_operator; ++i)
{
values[i] = (Datum) NULL;
replaces[i] = 'r';
nulls[i] = ' ';
}
@ -510,15 +520,18 @@ OperatorDef(char *operatorName,
* ----------------
*/
memset(typeId, 0, 8 * sizeof(Oid));
if (!leftTypeName) {
if (!leftTypeName)
{
typeId[0] = rightTypeId;
nargs = 1;
}
else if (!rightTypeName) {
else if (!rightTypeName)
{
typeId[0] = leftTypeId;
nargs = 1;
}
else {
else
{
typeId[0] = leftTypeId;
typeId[1] = rightTypeId;
nargs = 2;
@ -532,8 +545,8 @@ OperatorDef(char *operatorName,
if (!PointerIsValid(tup))
func_error("OperatorDef", procedureName, nargs, typeId);
values[ Anum_pg_operator_oprcode-1 ] = ObjectIdGetDatum(tup->t_oid);
values[ Anum_pg_operator_oprresult-1 ] =
values[Anum_pg_operator_oprcode - 1] = ObjectIdGetDatum(tup->t_oid);
values[Anum_pg_operator_oprresult - 1] =
ObjectIdGetDatum(((Form_pg_proc)
GETSTRUCT(tup))->prorettype);
@ -541,7 +554,8 @@ OperatorDef(char *operatorName,
* find restriction
* ----------------
*/
if (restrictionName) { /* optional */
if (restrictionName)
{ /* optional */
memset(typeId, 0, 8 * sizeof(Oid));
typeId[0] = OIDOID; /* operator OID */
typeId[1] = OIDOID; /* relation OID */
@ -556,15 +570,17 @@ OperatorDef(char *operatorName,
if (!HeapTupleIsValid(tup))
func_error("OperatorDef", restrictionName, 5, typeId);
values[ Anum_pg_operator_oprrest-1 ] = ObjectIdGetDatum(tup->t_oid);
} else
values[ Anum_pg_operator_oprrest-1 ] = ObjectIdGetDatum(InvalidOid);
values[Anum_pg_operator_oprrest - 1] = ObjectIdGetDatum(tup->t_oid);
}
else
values[Anum_pg_operator_oprrest - 1] = ObjectIdGetDatum(InvalidOid);
/* ----------------
* find join - only valid for binary operators
* ----------------
*/
if (joinName) { /* optional */
if (joinName)
{ /* optional */
memset(typeId, 0, 8 * sizeof(Oid));
typeId[0] = OIDOID; /* operator OID */
typeId[1] = OIDOID; /* relation OID 1 */
@ -580,9 +596,10 @@ OperatorDef(char *operatorName,
if (!HeapTupleIsValid(tup))
func_error("OperatorDef", joinName, 5, typeId);
values[Anum_pg_operator_oprjoin-1] = ObjectIdGetDatum(tup->t_oid);
} else
values[Anum_pg_operator_oprjoin-1] = ObjectIdGetDatum(InvalidOid);
values[Anum_pg_operator_oprjoin - 1] = ObjectIdGetDatum(tup->t_oid);
}
else
values[Anum_pg_operator_oprjoin - 1] = ObjectIdGetDatum(InvalidOid);
/* ----------------
* set up values in the operator tuple
@ -601,39 +618,48 @@ OperatorDef(char *operatorName,
++i; /* Skip "prorettype", this was done above */
/*
* Set up the other operators. If they do not currently exist,
* set up shells in order to get ObjectId's and call OperatorDef
* again later to fill in the shells.
* Set up the other operators. If they do not currently exist, set up
* shells in order to get ObjectId's and call OperatorDef again later
* to fill in the shells.
*/
name[0] = commutatorName;
name[1] = negatorName;
name[2] = leftSortName;
name[3] = rightSortName;
for (j = 0; j < 4; ++j) {
if (name[j]) {
for (j = 0; j < 4; ++j)
{
if (name[j])
{
/* for the commutator, switch order of arguments */
if (j == 0) {
other_oid = OperatorGet(name[j], rightTypeName,leftTypeName);
if (j == 0)
{
other_oid = OperatorGet(name[j], rightTypeName, leftTypeName);
commutatorId = other_oid;
} else {
other_oid = OperatorGet(name[j], leftTypeName,rightTypeName);
}
else
{
other_oid = OperatorGet(name[j], leftTypeName, rightTypeName);
if (j == 1)
negatorId = other_oid;
}
if (OidIsValid(other_oid)) /* already in catalogs */
values[i++] = ObjectIdGetDatum(other_oid);
else if (strcmp(operatorName, name[j]) != 0) {
else if (strcmp(operatorName, name[j]) != 0)
{
/* not in catalogs, different from operator */
/* for the commutator, switch order of arguments */
if (j == 0) {
if (j == 0)
{
other_oid = OperatorShellMake(name[j],
rightTypeName,
leftTypeName);
} else {
}
else
{
other_oid = OperatorShellMake(name[j],
leftTypeName,
rightTypeName);
@ -645,22 +671,26 @@ OperatorDef(char *operatorName,
name[j]);
values[i++] = ObjectIdGetDatum(other_oid);
} else /* not in catalogs, same as operator ??? */
}
else
/* not in catalogs, same as operator ??? */
values[i++] = ObjectIdGetDatum(InvalidOid);
} else /* new operator is optional */
}
else
/* new operator is optional */
values[i++] = ObjectIdGetDatum(InvalidOid);
}
/* last three fields were filled in first */
/*
* If we are adding to an operator shell, get its t_ctid and a
* buffer.
* If we are adding to an operator shell, get its t_ctid and a buffer.
*/
pg_operator_desc = heap_openr(OperatorRelationName);
if (operatorObjectId) {
if (operatorObjectId)
{
opKey[0].sk_argument = PointerGetDatum(operatorName);
opKey[1].sk_argument = ObjectIdGetDatum(leftTypeId);
opKey[2].sk_argument = ObjectIdGetDatum(rightTypeId);
@ -672,7 +702,8 @@ OperatorDef(char *operatorName,
opKey);
tup = heap_getnext(pg_operator_scan, 0, &buffer);
if (HeapTupleIsValid(tup)) {
if (HeapTupleIsValid(tup))
{
tup = heap_modifytuple(tup,
buffer,
pg_operator_desc,
@ -684,12 +715,15 @@ OperatorDef(char *operatorName,
setheapoverride(true);
heap_replace(pg_operator_desc, &itemPointerData, tup);
setheapoverride(false);
} else
}
else
elog(WARN, "OperatorDef: no operator %d", other_oid);
heap_endscan(pg_operator_scan);
} else {
}
else
{
tupDesc = pg_operator_desc->rd_att;
tup = heap_formtuple(tupDesc, values, nulls);
@ -700,17 +734,17 @@ OperatorDef(char *operatorName,
heap_close(pg_operator_desc);
/*
* It's possible that we're creating a skeleton operator here for
* the commute or negate attributes of a real operator. If we are,
* then we're done. If not, we may need to update the negator and
* It's possible that we're creating a skeleton operator here for the
* commute or negate attributes of a real operator. If we are, then
* we're done. If not, we may need to update the negator and
* commutator for this attribute. The reason for this is that the
* user may want to create two operators (say < and >=). When he
* defines <, if he uses >= as the negator or commutator, he won't
* be able to insert it later, since (for some reason) define operator
* defines <, if he uses >= as the negator or commutator, he won't be
* able to insert it later, since (for some reason) define operator
* defines it for him. So what he does is to define > without a
* negator or commutator. Then he defines >= with < as the negator
* and commutator. As a side effect, this will update the > tuple
* if it has no commutator or negator defined.
* and commutator. As a side effect, this will update the > tuple if
* it has no commutator or negator defined.
*
* Alstublieft, Tom Vijlbrief.
*/
@ -737,19 +771,20 @@ OperatorUpd(Oid baseId, Oid commId, Oid negId)
HeapTuple tup;
Buffer buffer;
ItemPointerData itemPointerData;
char nulls[ Natts_pg_operator ];
char replaces[ Natts_pg_operator ];
Datum values[ Natts_pg_operator ];
char nulls[Natts_pg_operator];
char replaces[Natts_pg_operator];
Datum values[Natts_pg_operator];
static ScanKeyData opKey[1] = {
{ 0, ObjectIdAttributeNumber, ObjectIdEqualRegProcedure },
{0, ObjectIdAttributeNumber, ObjectIdEqualRegProcedure},
};
fmgr_info(ObjectIdEqualRegProcedure,
&opKey[0].sk_func, &opKey[0].sk_nargs);
for (i = 0; i < Natts_pg_operator; ++i) {
values[i] = (Datum)NULL;
for (i = 0; i < Natts_pg_operator; ++i)
{
values[i] = (Datum) NULL;
replaces[i] = ' ';
nulls[i] = ' ';
}
@ -768,24 +803,29 @@ OperatorUpd(Oid baseId, Oid commId, Oid negId)
tup = heap_getnext(pg_operator_scan, 0, &buffer);
/* if the commutator and negator are the same operator, do one update */
if (commId == negId) {
if (HeapTupleIsValid(tup)) {
if (commId == negId)
{
if (HeapTupleIsValid(tup))
{
OperatorTupleForm t;
t = (OperatorTupleForm) GETSTRUCT(tup);
if (!OidIsValid(t->oprcom)
|| !OidIsValid(t->oprnegate)) {
|| !OidIsValid(t->oprnegate))
{
if (!OidIsValid(t->oprnegate)) {
if (!OidIsValid(t->oprnegate))
{
values[Anum_pg_operator_oprnegate - 1] =
ObjectIdGetDatum(baseId);
replaces[ Anum_pg_operator_oprnegate - 1 ] = 'r';
replaces[Anum_pg_operator_oprnegate - 1] = 'r';
}
if (!OidIsValid(t->oprcom)) {
if (!OidIsValid(t->oprcom))
{
values[Anum_pg_operator_oprcom - 1] =
ObjectIdGetDatum(baseId);
replaces[ Anum_pg_operator_oprcom - 1 ] = 'r';
replaces[Anum_pg_operator_oprcom - 1] = 'r';
}
tup = heap_modifytuple(tup,
@ -816,9 +856,10 @@ OperatorUpd(Oid baseId, Oid commId, Oid negId)
/* if commutator and negator are different, do two updates */
if (HeapTupleIsValid(tup) &&
!(OidIsValid(((OperatorTupleForm) GETSTRUCT(tup))->oprcom))) {
values[ Anum_pg_operator_oprcom - 1] = ObjectIdGetDatum(baseId);
replaces[ Anum_pg_operator_oprcom - 1] = 'r';
!(OidIsValid(((OperatorTupleForm) GETSTRUCT(tup))->oprcom)))
{
values[Anum_pg_operator_oprcom - 1] = ObjectIdGetDatum(baseId);
replaces[Anum_pg_operator_oprcom - 1] = 'r';
tup = heap_modifytuple(tup,
buffer,
pg_operator_desc,
@ -831,8 +872,8 @@ OperatorUpd(Oid baseId, Oid commId, Oid negId)
heap_replace(pg_operator_desc, &itemPointerData, tup);
setheapoverride(false);
values[ Anum_pg_operator_oprcom - 1 ] = (Datum)NULL;
replaces[ Anum_pg_operator_oprcom - 1 ] = ' ';
values[Anum_pg_operator_oprcom - 1] = (Datum) NULL;
replaces[Anum_pg_operator_oprcom - 1] = ' ';
/* release the buffer properly */
if (BufferIsValid(buffer))
@ -851,9 +892,10 @@ OperatorUpd(Oid baseId, Oid commId, Oid negId)
tup = heap_getnext(pg_operator_scan, 0, &buffer);
if (HeapTupleIsValid(tup) &&
!(OidIsValid(((OperatorTupleForm) GETSTRUCT(tup))->oprnegate))) {
values[Anum_pg_operator_oprnegate-1] = ObjectIdGetDatum(baseId);
replaces[ Anum_pg_operator_oprnegate - 1 ] = 'r';
!(OidIsValid(((OperatorTupleForm) GETSTRUCT(tup))->oprnegate)))
{
values[Anum_pg_operator_oprnegate - 1] = ObjectIdGetDatum(baseId);
replaces[Anum_pg_operator_oprnegate - 1] = 'r';
tup = heap_modifytuple(tup,
buffer,
pg_operator_desc,
@ -943,8 +985,10 @@ OperatorCreate(char *operatorName,
char *leftSortName,
char *rightSortName)
{
Oid commObjectId, negObjectId;
Oid leftSortObjectId, rightSortObjectId;
Oid commObjectId,
negObjectId;
Oid leftSortObjectId,
rightSortObjectId;
int definedOK;
if (!leftTypeName && !rightTypeName)
@ -958,25 +1002,29 @@ OperatorCreate(char *operatorName,
commObjectId = OperatorGet(commutatorName, /* commute type order */
rightTypeName,
leftTypeName);
else commObjectId = 0;
else
commObjectId = 0;
if (negatorName)
negObjectId = OperatorGet(negatorName,
leftTypeName,
rightTypeName);
else negObjectId = 0;
else
negObjectId = 0;
if (leftSortName)
leftSortObjectId = OperatorGet(leftSortName,
leftTypeName,
rightTypeName);
else leftSortObjectId = 0;
else
leftSortObjectId = 0;
if (rightSortName)
rightSortObjectId = OperatorGet(rightSortName,
rightTypeName,
leftTypeName);
else rightSortObjectId = 0;
else
rightSortObjectId = 0;
/* ----------------
* Use OperatorDef() to define the specified operator and

View File

@ -7,7 +7,7 @@
*
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/catalog/pg_proc.c,v 1.5 1996/11/08 00:44:34 scrappy Exp $
* $Header: /cvsroot/pgsql/src/backend/catalog/pg_proc.c,v 1.6 1997/09/07 04:40:30 momjian Exp $
*
*-------------------------------------------------------------------------
*/
@ -30,9 +30,9 @@
#include <utils/lsyscache.h>
#include <miscadmin.h>
#ifndef HAVE_MEMMOVE
# include <regex/utils.h>
#include <regex/utils.h>
#else
# include <string.h>
#include <string.h>
#endif
/* ----------------------------------------------------------------
@ -52,7 +52,7 @@ ProcedureCreate(char *procedureName,
int32 perbyte_cpu,
int32 percall_cpu,
int32 outin_ratio,
List *argList,
List * argList,
CommandDest dest)
{
register i;
@ -60,8 +60,8 @@ ProcedureCreate(char *procedureName,
HeapTuple tup;
bool defined;
uint16 parameterCount;
char nulls[ Natts_pg_proc ];
Datum values[ Natts_pg_proc ];
char nulls[Natts_pg_proc];
Datum values[Natts_pg_proc];
Oid languageObjectId;
Oid typeObjectId;
List *x;
@ -82,26 +82,33 @@ ProcedureCreate(char *procedureName,
parameterCount = 0;
memset(typev, 0, 8 * sizeof(Oid));
foreach (x, argList) {
foreach(x, argList)
{
Value *t = lfirst(x);
if (parameterCount == 8)
elog(WARN, "Procedures cannot take more than 8 arguments");
if (strcmp(strVal(t), "opaque") == 0) {
if (strcmp(languageName, "sql") == 0) {
if (strcmp(strVal(t), "opaque") == 0)
{
if (strcmp(languageName, "sql") == 0)
{
elog(WARN, "ProcedureDefine: sql functions cannot take type \"opaque\"");
}
toid = 0;
} else {
}
else
{
toid = TypeGet(strVal(t), &defined);
if (!OidIsValid(toid)) {
if (!OidIsValid(toid))
{
elog(WARN, "ProcedureCreate: arg type '%s' is not defined",
strVal(t));
}
if (!defined) {
if (!defined)
{
elog(NOTICE, "ProcedureCreate: arg type '%s' is only a shell",
strVal(t));
}
@ -120,17 +127,21 @@ ProcedureCreate(char *procedureName,
elog(WARN, "ProcedureCreate: procedure %s already exists with same arguments",
procedureName);
if (!strcmp(languageName, "sql")) {
/* If this call is defining a set, check if the set is already
if (!strcmp(languageName, "sql"))
{
/*
* If this call is defining a set, check if the set is already
* defined by looking to see whether this call's function text
* matches a function already in pg_proc. If so just return the
* OID of the existing set.
*/
if (!strcmp(procedureName, GENERICSETNAME)) {
if (!strcmp(procedureName, GENERICSETNAME))
{
prosrctext = textin(prosrc);
tup = SearchSysCacheTuple(PROSRC,
PointerGetDatum(prosrctext),
0,0,0);
0, 0, 0);
if (HeapTupleIsValid(tup))
return tup->t_oid;
}
@ -138,7 +149,7 @@ ProcedureCreate(char *procedureName,
tup = SearchSysCacheTuple(LANNAME,
PointerGetDatum(languageName),
0,0,0);
0, 0, 0);
if (!HeapTupleIsValid(tup))
elog(WARN, "ProcedureCreate: no such language %s",
@ -146,17 +157,21 @@ ProcedureCreate(char *procedureName,
languageObjectId = tup->t_oid;
if (strcmp(returnTypeName, "opaque") == 0) {
if (strcmp(languageName, "sql") == 0) {
if (strcmp(returnTypeName, "opaque") == 0)
{
if (strcmp(languageName, "sql") == 0)
{
elog(WARN, "ProcedureCreate: sql functions cannot return type \"opaque\"");
}
typeObjectId = 0;
}
else {
else
{
typeObjectId = TypeGet(returnTypeName, &defined);
if (!OidIsValid(typeObjectId)) {
if (!OidIsValid(typeObjectId))
{
elog(NOTICE, "ProcedureCreate: type '%s' is not yet defined",
returnTypeName);
#if 0
@ -164,20 +179,24 @@ ProcedureCreate(char *procedureName,
returnTypeName);
#endif
typeObjectId = TypeShellMake(returnTypeName);
if (!OidIsValid(typeObjectId)) {
if (!OidIsValid(typeObjectId))
{
elog(WARN, "ProcedureCreate: could not create type '%s'",
returnTypeName);
}
}
else if (!defined) {
else if (!defined)
{
elog(NOTICE, "ProcedureCreate: return type '%s' is only a shell",
returnTypeName);
}
}
/* don't allow functions of complex types that have the same name as
existing attributes of the type */
/*
* don't allow functions of complex types that have the same name as
* existing attributes of the type
*/
if (parameterCount == 1 &&
(toid = TypeGet(strVal(lfirst(argList)), &defined)) &&
defined &&
@ -188,13 +207,14 @@ ProcedureCreate(char *procedureName,
/*
* If this is a postquel procedure, we parse it here in order to
* be sure that it contains no syntax errors. We should store
* the plan in an Inversion file for use later, but for now, we
* just store the procedure's text in the prosrc attribute.
* If this is a postquel procedure, we parse it here in order to be
* sure that it contains no syntax errors. We should store the plan
* in an Inversion file for use later, but for now, we just store the
* procedure's text in the prosrc attribute.
*/
if (strcmp(languageName, "sql") == 0) {
if (strcmp(languageName, "sql") == 0)
{
plan_list = pg_plan(prosrc, typev, parameterCount,
&querytree_list, dest);
@ -202,9 +222,10 @@ ProcedureCreate(char *procedureName,
pg_checkretval(typeObjectId, querytree_list);
}
for (i = 0; i < Natts_pg_proc; ++i) {
for (i = 0; i < Natts_pg_proc; ++i)
{
nulls[i] = ' ';
values[i] = (Datum)NULL;
values[i] = (Datum) NULL;
}
i = 0;
@ -225,6 +246,7 @@ ProcedureCreate(char *procedureName,
values[i++] = ObjectIdGetDatum(typeObjectId);
values[i++] = (Datum) typev;
/*
* The following assignments of constants are made. The real values
* will have to be extracted from the arglist someday soon.
@ -234,8 +256,8 @@ ProcedureCreate(char *procedureName,
values[i++] = Int32GetDatum(percall_cpu); /* propercall_cpu */
values[i++] = Int32GetDatum(outin_ratio); /* prooutin_ratio */
values[i++] = (Datum)fmgr(TextInRegProcedure, prosrc); /* prosrc */
values[i++] = (Datum)fmgr(TextInRegProcedure, probin); /* probin */
values[i++] = (Datum) fmgr(TextInRegProcedure, prosrc); /* prosrc */
values[i++] = (Datum) fmgr(TextInRegProcedure, probin); /* probin */
rdesc = heap_openr(ProcedureRelationName);
@ -257,4 +279,3 @@ ProcedureCreate(char *procedureName,
heap_close(rdesc);
return tup->t_oid;
}

View File

@ -7,7 +7,7 @@
*
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/catalog/pg_type.c,v 1.7 1997/08/19 21:30:38 momjian Exp $
* $Header: /cvsroot/pgsql/src/backend/catalog/pg_type.c,v 1.8 1997/09/07 04:40:31 momjian Exp $
*
*-------------------------------------------------------------------------
*/
@ -25,12 +25,13 @@
#include <storage/lmgr.h>
#include <miscadmin.h>
#ifndef HAVE_MEMMOVE
# include <regex/utils.h>
#include <regex/utils.h>
#else
# include <string.h>
#include <string.h>
#endif
static Oid TypeShellMakeWithOpenRelation(Relation pg_type_desc,
static Oid
TypeShellMakeWithOpenRelation(Relation pg_type_desc,
char *typeName);
/* ----------------------------------------------------------------
@ -45,14 +46,14 @@ static Oid TypeShellMakeWithOpenRelation(Relation pg_type_desc,
*/
static Oid
TypeGetWithOpenRelation(Relation pg_type_desc,
char* typeName,
bool *defined)
char *typeName,
bool * defined)
{
HeapScanDesc scan;
HeapTuple tup;
static ScanKeyData typeKey[1] = {
{ 0, Anum_pg_type_typname, NameEqualRegProcedure }
{0, Anum_pg_type_typname, NameEqualRegProcedure}
};
/* ----------------
@ -80,7 +81,8 @@ TypeGetWithOpenRelation(Relation pg_type_desc,
* end the scan and return appropriate information.
* ----------------
*/
if (! HeapTupleIsValid(tup)) {
if (!HeapTupleIsValid(tup))
{
heap_endscan(scan);
*defined = false;
return InvalidOid;
@ -113,8 +115,8 @@ TypeGetWithOpenRelation(Relation pg_type_desc,
* ----------------------------------------------------------------
*/
Oid
TypeGet(char* typeName, /* name of type to be fetched */
bool *defined) /* has the type been defined? */
TypeGet(char *typeName, /* name of type to be fetched */
bool * defined) /* has the type been defined? */
{
Relation pg_type_desc;
Oid typeoid;
@ -153,8 +155,8 @@ TypeShellMakeWithOpenRelation(Relation pg_type_desc, char *typeName)
{
register int i;
HeapTuple tup;
Datum values[ Natts_pg_type ];
char nulls[ Natts_pg_type ];
Datum values[Natts_pg_type];
char nulls[Natts_pg_type];
Oid typoid;
TupleDesc tupDesc;
@ -162,9 +164,10 @@ TypeShellMakeWithOpenRelation(Relation pg_type_desc, char *typeName)
* initialize our nulls[] and values[] arrays
* ----------------
*/
for (i = 0; i < Natts_pg_type; ++i) {
for (i = 0; i < Natts_pg_type; ++i)
{
nulls[i] = ' ';
values[i] = (Datum)NULL; /* redundant, but safe */
values[i] = (Datum) NULL; /* redundant, but safe */
}
/* ----------------
@ -192,7 +195,7 @@ TypeShellMakeWithOpenRelation(Relation pg_type_desc, char *typeName)
* ... and fill typdefault with a bogus value
*/
values[i++] =
(Datum)fmgr(TextInRegProcedure, typeName); /* 15 */
(Datum) fmgr(TextInRegProcedure, typeName); /* 15 */
/* ----------------
* create a new type tuple with FormHeapTuple
@ -292,7 +295,8 @@ TypeCreate(char *typeName,
bool passedByValue,
char alignment)
{
register i, j;
register i,
j;
Relation pg_type_desc;
HeapScanDesc pg_type_scan;
@ -315,7 +319,7 @@ TypeCreate(char *typeName,
static ScanKeyData typeKey[1] = {
{ 0, Anum_pg_type_typname, NameEqualRegProcedure }
{0, Anum_pg_type_typname, NameEqualRegProcedure}
};
fmgr_info(NameEqualRegProcedure,
@ -326,7 +330,8 @@ TypeCreate(char *typeName,
* ----------------
*/
typeObjectId = TypeGet(typeName, &defined);
if (OidIsValid(typeObjectId) && defined) {
if (OidIsValid(typeObjectId) && defined)
{
elog(WARN, "TypeCreate: type %s already defined", typeName);
}
@ -335,9 +340,11 @@ TypeCreate(char *typeName,
* it is defined.
* ----------------
*/
if (elementTypeName) {
if (elementTypeName)
{
elementObjectId = TypeGet(elementTypeName, &defined);
if (!defined) {
if (!defined)
{
elog(WARN, "TypeCreate: type %s is not defined", elementTypeName);
}
}
@ -346,7 +353,8 @@ TypeCreate(char *typeName,
* XXX comment me
* ----------------
*/
if (externalSize == 0) {
if (externalSize == 0)
{
externalSize = -1; /* variable length */
}
@ -354,10 +362,11 @@ TypeCreate(char *typeName,
* initialize arrays needed by FormHeapTuple
* ----------------
*/
for (i = 0; i < Natts_pg_type; ++i) {
for (i = 0; i < Natts_pg_type; ++i)
{
nulls[i] = ' ';
replaces[i] = 'r';
values[i] = (Datum)NULL; /* redundant, but nice */
values[i] = (Datum) NULL; /* redundant, but nice */
}
/*
@ -397,7 +406,8 @@ TypeCreate(char *typeName,
procs[2] = (receiveProcedure) ? receiveProcedure : inputProcedure;
procs[3] = (sendProcedure) ? sendProcedure : outputProcedure;
for (j = 0; j < 4; ++j) {
for (j = 0; j < 4; ++j)
{
procname = procs[j];
tup = SearchSysCacheTuple(PRONAME,
@ -406,40 +416,45 @@ TypeCreate(char *typeName,
PointerGetDatum(argList),
0);
if (!HeapTupleIsValid(tup)) {
if (!HeapTupleIsValid(tup))
{
/*
* it is possible for the input/output procedure
* to take two arguments, where the second argument
* is the element type (eg array_in/array_out)
* it is possible for the input/output procedure to take two
* arguments, where the second argument is the element type
* (eg array_in/array_out)
*/
if (OidIsValid(elementObjectId)) {
if (OidIsValid(elementObjectId))
{
tup = SearchSysCacheTuple(PRONAME,
PointerGetDatum(procname),
Int32GetDatum(2),
PointerGetDatum(argList),
0);
}
if (!HeapTupleIsValid(tup)) {
if (!HeapTupleIsValid(tup))
{
func_error("TypeCreate", procname, 1, argList);
}
}
values[i++] = (Datum)tup->t_oid; /* 11 - 14 */
values[i++] = (Datum) tup->t_oid; /* 11 - 14 */
}
/* ----------------
* set default alignment
* ----------------
*/
values[i++] = (Datum)alignment; /* 15 */
values[i++] = (Datum) alignment; /* 15 */
/* ----------------
* initialize the default value for this type.
* ----------------
*/
values[i] = (Datum)fmgr(TextInRegProcedure, /* 16 */
values[i] = (Datum) fmgr(TextInRegProcedure, /* 16 */
PointerIsValid(defaultTypeValue)
? defaultTypeValue : "-"); /* XXX default typdefault */
? defaultTypeValue : "-"); /* XXX default
* typdefault */
/* ----------------
* open pg_type and begin a scan for the type name.
@ -468,7 +483,8 @@ TypeCreate(char *typeName,
* ----------------
*/
tup = heap_getnext(pg_type_scan, 0, &buffer);
if (HeapTupleIsValid(tup)) {
if (HeapTupleIsValid(tup))
{
tup = heap_modifytuple(tup,
buffer,
pg_type_desc,
@ -484,7 +500,9 @@ TypeCreate(char *typeName,
setheapoverride(false);
typeObjectId = tup->t_oid;
} else {
}
else
{
tupDesc = pg_type_desc->rd_att;
tup = heap_formtuple(tupDesc,
@ -536,7 +554,8 @@ TypeRename(char *oldTypeName, char *newTypeName)
/* check that that the new type is not already defined */
type_oid = TypeGet(newTypeName, &defined);
if (OidIsValid(type_oid) && defined) {
if (OidIsValid(type_oid) && defined)
{
elog(WARN, "TypeRename: type %s already defined", newTypeName);
}
@ -548,9 +567,10 @@ TypeRename(char *oldTypeName, char *newTypeName)
* change the name of the type
* ----------------
*/
if (HeapTupleIsValid(tup)) {
if (HeapTupleIsValid(tup))
{
namestrcpy(& (((TypeTupleForm) GETSTRUCT(tup))->typname),newTypeName);
namestrcpy(&(((TypeTupleForm) GETSTRUCT(tup))->typname), newTypeName);
ItemPointerCopy(&tup->t_ctid, &itemPointerData);
@ -566,7 +586,9 @@ TypeRename(char *oldTypeName, char *newTypeName)
/* all done */
pfree(tup);
} else {
}
else
{
elog(WARN, "TypeRename: type %s not defined", oldTypeName);
}
@ -581,15 +603,16 @@ TypeRename(char *oldTypeName, char *newTypeName)
* the CALLER is responsible for pfreeing the
*/
char*
makeArrayTypeName(char* typeName)
char *
makeArrayTypeName(char *typeName)
{
char *arr;
if (!typeName) return NULL;
arr = palloc (strlen(typeName) + 2);
if (!typeName)
return NULL;
arr = palloc(strlen(typeName) + 2);
arr[0] = '_';
strcpy(arr+1, typeName);
strcpy(arr + 1, typeName);
return arr;

View File

@ -10,7 +10,7 @@
*
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/commands/_deadcode/Attic/version.c,v 1.5 1997/08/19 21:30:47 momjian Exp $
* $Header: /cvsroot/pgsql/src/backend/commands/_deadcode/Attic/version.c,v 1.6 1997/09/07 04:41:04 momjian Exp $
*
* NOTES
* At the point the version is defined, 2 physical relations are created
@ -35,8 +35,10 @@
#define MAX_QUERY_LEN 1024
char rule_buf[MAX_QUERY_LEN];
#ifdef NOT_USED
static char attr_list[MAX_QUERY_LEN];
#endif
/*
@ -86,13 +88,15 @@ static char attr_list[MAX_QUERY_LEN];
static void
eval_as_new_xact(char *query)
{
/* WARNING! do not uncomment the following lines WARNING!
* CommitTransactionCommand();
* StartTransactionCommand();
/*
* WARNING! do not uncomment the following lines WARNING!
* CommitTransactionCommand(); StartTransactionCommand();
*/
CommandCounterIncrement();
pg_eval(query, (char **) NULL, (Oid *) NULL, 0);
}
#endif
/*
* Define a version.
@ -105,12 +109,15 @@ DefineVersion(char *name, char *fromRelname, char *date)
static char saved_basename[512];
static char saved_snapshot[512];
if (date == NULL) {
if (date == NULL)
{
/* no time ranges */
bname = fromRelname;
strcpy(saved_basename, (char *) bname);
*saved_snapshot = (char)NULL;
} else {
*saved_snapshot = (char) NULL;
}
else
{
/* version is a snapshot */
bname = fromRelname;
strcpy(saved_basename, (char *) bname);
@ -119,19 +126,19 @@ DefineVersion(char *name, char *fromRelname, char *date)
/*
* Calls the routine ``GetAttrList'' get the list of attributes
* from the base relation.
* Code is put here so that we only need to look up the attribute once for
* both appends and replaces.
* Calls the routine ``GetAttrList'' get the list of attributes from
* the base relation. Code is put here so that we only need to look up
* the attribute once for both appends and replaces.
*/
setAttrList(bname);
VersionCreate (name, saved_basename);
VersionAppend (name, saved_basename);
VersionDelete (name, saved_basename,saved_snapshot);
VersionReplace (name, saved_basename,saved_snapshot);
VersionRetrieve (name, saved_basename, saved_snapshot);
VersionCreate(name, saved_basename);
VersionAppend(name, saved_basename);
VersionDelete(name, saved_basename, saved_snapshot);
VersionReplace(name, saved_basename, saved_snapshot);
VersionRetrieve(name, saved_basename, saved_snapshot);
}
#endif
/*
@ -141,7 +148,7 @@ DefineVersion(char *name, char *fromRelname, char *date)
void
VersionCreate(char *vname, char *bname)
{
static char query_buf [MAX_QUERY_LEN];
static char query_buf[MAX_QUERY_LEN];
/*
* Creating the dummy version relation for triggering rules.
@ -149,21 +156,22 @@ VersionCreate(char *vname, char *bname)
sprintf(query_buf, "SELECT * INTO TABLE %s from %s where 1 =2",
vname, bname);
pg_eval (query_buf, (char **) NULL, (Oid *) NULL, 0);
pg_eval(query_buf, (char **) NULL, (Oid *) NULL, 0);
/*
* Creating the ``v_added'' relation
*/
sprintf (query_buf, "SELECT * INTO TABLE %s_added from %s where 1 = 2",
sprintf(query_buf, "SELECT * INTO TABLE %s_added from %s where 1 = 2",
vname, bname);
eval_as_new_xact (query_buf);
eval_as_new_xact(query_buf);
/*
* Creating the ``v_deleted'' relation.
*/
sprintf (query_buf, "CREATE TABLE %s_del (DOID oid)", vname);
eval_as_new_xact (query_buf);
sprintf(query_buf, "CREATE TABLE %s_del (DOID oid)", vname);
eval_as_new_xact(query_buf);
}
#endif
@ -184,20 +192,25 @@ setAttrList(char *bname)
int notfirst = 0;
rdesc = heap_openr(bname);
if (rdesc == NULL ) {
elog(WARN,"Unable to expand all -- amopenr failed ");
if (rdesc == NULL)
{
elog(WARN, "Unable to expand all -- amopenr failed ");
return;
}
maxattrs = RelationGetNumberOfAttributes(rdesc);
attr_list[0] = '\0';
for ( i = maxattrs-1 ; i > -1 ; --i ) {
for (i = maxattrs - 1; i > -1; --i)
{
attrname = (rdesc->rd_att->attrs[i]->attname).data;
if (notfirst == 1) {
if (notfirst == 1)
{
sprintf(temp_buf, ", %s = new.%s", attrname, attrname);
} else {
}
else
{
sprintf(temp_buf, "%s = new.%s", attrname, attrname);
notfirst = 1;
}
@ -208,6 +221,7 @@ setAttrList(char *bname)
return;
}
#endif
/*
@ -225,6 +239,7 @@ VersionAppend(char *vname, char *bname)
eval_as_new_xact(rule_buf);
}
#endif
/*
@ -253,6 +268,7 @@ where _%s.oid !!= '%s_del.DOID'",
/* printf("%s\n",rule_buf); */
}
#endif
/*
@ -276,8 +292,8 @@ VersionDelete(char *vname, char *bname, char *snapshot)
[delete %s_added where current.oid = %s_added.oid\n \
append %s_del(DOID = current.oid) from _%s in %s%s \
where current.oid = _%s.oid] \n",
vname,vname,vname,vname,vname,
bname,bname,snapshot,bname);
vname, vname, vname, vname, vname,
bname, bname, snapshot, bname);
eval_as_new_xact(rule_buf);
#ifdef OLD_REWRITE
@ -285,11 +301,12 @@ bname,bname,snapshot,bname);
"define rewrite rule %s_delete2 is on delete to %s do instead \n \
append %s_del(DOID = current.oid) from _%s in %s%s \
where current.oid = _%s.oid \n",
vname,vname,vname,bname,bname,snapshot,bname);
vname, vname, vname, bname, bname, snapshot, bname);
eval_as_new_xact(rule_buf);
#endif /* OLD_REWRITE */
}
#endif
/*
@ -315,9 +332,9 @@ VersionReplace(char *vname, char *bname, char *snapshot)
where current.oid = _%s.oid\n\
append %s_added(%s) from _%s in %s%s \
where current.oid !!= '%s_added.oid' and current.oid = _%s.oid]\n",
vname,vname,vname,attr_list,vname,
vname,bname,bname,snapshot,bname,
vname,attr_list,bname,bname,snapshot,vname,bname);
vname, vname, vname, attr_list, vname,
vname, bname, bname, snapshot, bname,
vname, attr_list, bname, bname, snapshot, vname, bname);
eval_as_new_xact(rule_buf);
@ -327,7 +344,7 @@ vname,attr_list,bname,bname,snapshot,vname,bname);
"define rewrite rule %s_replace2 is on replace to %s do \n\
append %s_del(DOID = current.oid) from _%s in %s%s \
where current.oid = _%s.oid\n",
vname,vname,vname,bname,bname,snapshot,bname);
vname, vname, vname, bname, bname, snapshot, bname);
eval_as_new_xact(rule_buf);
@ -336,7 +353,7 @@ vname,attr_list,bname,bname,snapshot,vname,bname);
append %s_added(%s) from _%s in %s%s \
where current.oid !!= '%s_added.oid' and current.oid = \
_%s.oid\n",
vname,vname, vname,attr_list,bname,bname,snapshot,vname,bname);
vname, vname, vname, attr_list, bname, bname, snapshot, vname, bname);
eval_as_new_xact(rule_buf);
#endif /* OLD_REWRITE */

View File

@ -7,7 +7,7 @@
*
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/commands/async.c,v 1.17 1997/08/19 21:30:42 momjian Exp $
* $Header: /cvsroot/pgsql/src/backend/commands/async.c,v 1.18 1997/09/07 04:40:35 momjian Exp $
*
*-------------------------------------------------------------------------
*/
@ -122,14 +122,17 @@ Async_NotifyHandler(SIGNAL_ARGS)
extern TransactionState CurrentTransactionState;
if ((CurrentTransactionState->state == TRANS_DEFAULT) &&
(CurrentTransactionState->blockState == TRANS_DEFAULT)) {
(CurrentTransactionState->blockState == TRANS_DEFAULT))
{
#ifdef ASYNC_DEBUG
elog(DEBUG, "Waking up sleeping backend process");
#endif
Async_NotifyFrontEnd();
}else {
}
else
{
#ifdef ASYNC_DEBUG
elog(DEBUG, "Process is in the middle of another transaction, state = %d, block state = %d",
CurrentTransactionState->state,
@ -166,20 +169,23 @@ void
Async_Notify(char *relname)
{
HeapTuple lTuple, rTuple;
HeapTuple lTuple,
rTuple;
Relation lRel;
HeapScanDesc sRel;
TupleDesc tdesc;
ScanKeyData key;
Buffer b;
Datum d, value[3];
Datum d,
value[3];
bool isnull;
char repl[3], nulls[3];
char repl[3],
nulls[3];
char *notifyName;
#ifdef ASYNC_DEBUG
elog(DEBUG,"Async_Notify: %s",relname);
elog(DEBUG, "Async_Notify: %s", relname);
#endif
if (!pendingNotifies)
@ -208,10 +214,12 @@ Async_Notify(char *relname)
value[0] = value[1] = value[2] = (Datum) 0;
value[Anum_pg_listener_notify - 1] = Int32GetDatum(1);
while (HeapTupleIsValid(lTuple = heap_getnext(sRel, 0, &b))) {
while (HeapTupleIsValid(lTuple = heap_getnext(sRel, 0, &b)))
{
d = (Datum) heap_getattr(lTuple, b, Anum_pg_listener_notify,
tdesc, &isnull);
if (!DatumGetInt32(d)) {
if (!DatumGetInt32(d))
{
rTuple = heap_modifytuple(lTuple, b, lRel, value, nulls, repl);
heap_replace(lRel, &lTuple->t_ctid, rTuple);
}
@ -263,9 +271,11 @@ Async_NotifyAtCommit()
pendingNotifies = DLNewList();
if ((CurrentTransactionState->state == TRANS_DEFAULT) &&
(CurrentTransactionState->blockState == TRANS_DEFAULT)) {
(CurrentTransactionState->blockState == TRANS_DEFAULT))
{
if (notifyIssued) { /* 'notify <relname>' issued by us */
if (notifyIssued)
{ /* 'notify <relname>' issued by us */
notifyIssued = 0;
StartTransactionCommand();
#ifdef ASYNC_DEBUG
@ -281,26 +291,33 @@ Async_NotifyAtCommit()
tdesc = RelationGetTupleDescriptor(lRel);
ourpid = getpid();
while (HeapTupleIsValid(lTuple = heap_getnext(sRel,0, &b))) {
while (HeapTupleIsValid(lTuple = heap_getnext(sRel, 0, &b)))
{
d = (Datum) heap_getattr(lTuple, b, Anum_pg_listener_relname,
tdesc, &isnull);
if (AsyncExistsPendingNotify((char *) DatumGetPointer(d))) {
if (AsyncExistsPendingNotify((char *) DatumGetPointer(d)))
{
d = (Datum) heap_getattr(lTuple, b, Anum_pg_listener_pid,
tdesc, &isnull);
if (ourpid == DatumGetInt32(d)) {
if (ourpid == DatumGetInt32(d))
{
#ifdef ASYNC_DEBUG
elog(DEBUG, "Notifying self, setting notifyFronEndPending to 1");
#endif
notifyFrontEndPending = 1;
} else {
}
else
{
#ifdef ASYNC_DEBUG
elog(DEBUG, "Notifying others");
#endif
#ifdef HAVE_KILL
if (kill(DatumGetInt32(d), SIGUSR2) < 0) {
if (errno == ESRCH) {
if (kill(DatumGetInt32(d), SIGUSR2) < 0)
{
if (errno == ESRCH)
{
heap_delete(lRel, &lTuple->t_ctid);
}
}
@ -317,8 +334,9 @@ Async_NotifyAtCommit()
ClearPendingNotify();
}
if (notifyFrontEndPending) { /* we need to notify the frontend of
all pending notifies. */
if (notifyFrontEndPending)
{ /* we need to notify the frontend of all
* pending notifies. */
notifyFrontEndPending = 1;
Async_NotifyFrontEnd();
}
@ -346,7 +364,8 @@ Async_NotifyAtAbort()
{
extern TransactionState CurrentTransactionState;
if (notifyIssued) {
if (notifyIssued)
{
ClearPendingNotify();
}
notifyIssued = 0;
@ -355,8 +374,10 @@ Async_NotifyAtAbort()
pendingNotifies = DLNewList();
if ((CurrentTransactionState->state == TRANS_DEFAULT) &&
(CurrentTransactionState->blockState == TRANS_DEFAULT)) {
if (notifyFrontEndPending) { /* don't forget to notify front end */
(CurrentTransactionState->blockState == TRANS_DEFAULT))
{
if (notifyFrontEndPending)
{ /* don't forget to notify front end */
Async_NotifyFrontEnd();
}
}
@ -389,7 +410,8 @@ Async_Listen(char *relname, int pid)
char nulls[Natts_pg_listener];
TupleDesc tdesc;
HeapScanDesc s;
HeapTuple htup,tup;
HeapTuple htup,
tup;
Relation lDesc;
Buffer b;
Datum d;
@ -401,9 +423,10 @@ Async_Listen(char *relname, int pid)
TupleDesc tupDesc;
#ifdef ASYNC_DEBUG
elog(DEBUG,"Async_Listen: %s",relname);
elog(DEBUG, "Async_Listen: %s", relname);
#endif
for (i = 0 ; i < Natts_pg_listener; i++) {
for (i = 0; i < Natts_pg_listener; i++)
{
nulls[i] = ' ';
values[i] = PointerGetDatum(NULL);
}
@ -418,15 +441,18 @@ Async_Listen(char *relname, int pid)
/* is someone already listening. One listener per relation */
tdesc = RelationGetTupleDescriptor(lDesc);
s = heap_beginscan(lDesc,0,NowTimeQual,0,(ScanKey)NULL);
while (HeapTupleIsValid(htup = heap_getnext(s,0,&b))) {
d = (Datum) heap_getattr(htup,b,Anum_pg_listener_relname,tdesc,
s = heap_beginscan(lDesc, 0, NowTimeQual, 0, (ScanKey) NULL);
while (HeapTupleIsValid(htup = heap_getnext(s, 0, &b)))
{
d = (Datum) heap_getattr(htup, b, Anum_pg_listener_relname, tdesc,
&isnull);
relnamei = DatumGetPointer(d);
if (!strncmp(relnamei,relname, NAMEDATALEN)) {
d = (Datum) heap_getattr(htup,b,Anum_pg_listener_pid,tdesc,&isnull);
if (!strncmp(relnamei, relname, NAMEDATALEN))
{
d = (Datum) heap_getattr(htup, b, Anum_pg_listener_pid, tdesc, &isnull);
pid = DatumGetInt32(d);
if (pid == ourPid) {
if (pid == ourPid)
{
alreadyListener = 1;
}
}
@ -434,7 +460,8 @@ Async_Listen(char *relname, int pid)
}
heap_endscan(s);
if (alreadyListener) {
if (alreadyListener)
{
elog(NOTICE, "Async_Listen: We are already listening on %s",
relname);
return;
@ -447,19 +474,21 @@ Async_Listen(char *relname, int pid)
heap_insert(lDesc, tup);
pfree(tup);
/* if (alreadyListener) {
elog(NOTICE,"Async_Listen: already one listener on %s (possibly dead)",relname);
}*/
/*
* if (alreadyListener) { elog(NOTICE,"Async_Listen: already one
* listener on %s (possibly dead)",relname); }
*/
RelationUnsetLockForWrite(lDesc);
heap_close(lDesc);
/*
* now that we are listening, we should make a note to ourselves
* to unlisten prior to dying.
* now that we are listening, we should make a note to ourselves to
* unlisten prior to dying.
*/
relnamei = malloc(NAMEDATALEN); /* persists to process exit */
strNcpy(relnamei, relname, NAMEDATALEN-1);
strNcpy(relnamei, relname, NAMEDATALEN - 1);
on_exitpg(Async_UnlistenOnExit, (caddr_t) relnamei);
}
@ -489,12 +518,13 @@ Async_Unlisten(char *relname, int pid)
lTuple = SearchSysCacheTuple(LISTENREL, PointerGetDatum(relname),
Int32GetDatum(pid),
0,0);
0, 0);
lDesc = heap_openr(ListenerRelationName);
RelationSetLockForWrite(lDesc);
if (lTuple != NULL) {
heap_delete(lDesc,&lTuple->t_ctid);
if (lTuple != NULL)
{
heap_delete(lDesc, &lTuple->t_ctid);
}
RelationUnsetLockForWrite(lDesc);
@ -536,13 +566,16 @@ static void
Async_NotifyFrontEnd()
{
extern CommandDest whereToSendOutput;
HeapTuple lTuple, rTuple;
HeapTuple lTuple,
rTuple;
Relation lRel;
HeapScanDesc sRel;
TupleDesc tdesc;
ScanKeyData key[2];
Datum d, value[3];
char repl[3], nulls[3];
Datum d,
value[3];
char repl[3],
nulls[3];
Buffer b;
int ourpid;
bool isnull;
@ -574,7 +607,8 @@ Async_NotifyFrontEnd()
value[0] = value[1] = value[2] = (Datum) 0;
value[Anum_pg_listener_notify - 1] = Int32GetDatum(0);
while (HeapTupleIsValid(lTuple = heap_getnext(sRel, 0,&b))) {
while (HeapTupleIsValid(lTuple = heap_getnext(sRel, 0, &b)))
{
d = (Datum) heap_getattr(lTuple, b, Anum_pg_listener_relname,
tdesc, &isnull);
rTuple = heap_modifytuple(lTuple, b, lRel, value, nulls, repl);
@ -582,12 +616,15 @@ Async_NotifyFrontEnd()
/* notifying the front end */
if (whereToSendOutput == Remote) {
if (whereToSendOutput == Remote)
{
pq_putnchar("A", 1);
pq_putint(ourpid, 4);
pq_putstr(DatumGetName(d)->data);
pq_flush();
} else {
}
else
{
elog(NOTICE, "Async_NotifyFrontEnd: no asynchronous notification to frontend on interactive sessions");
}
ReleaseBuffer(b);
@ -598,10 +635,12 @@ Async_NotifyFrontEnd()
static int
AsyncExistsPendingNotify(char *relname)
{
Dlelem* p;
Dlelem *p;
for (p = DLGetHead(pendingNotifies);
p != NULL;
p = DLGetSucc(p)) {
p = DLGetSucc(p))
{
/* Use NAMEDATALEN for relname comparison. DZ - 26-08-1996 */
if (!strncmp(DLE_VAL(p), relname, NAMEDATALEN))
return 1;
@ -613,8 +652,8 @@ AsyncExistsPendingNotify(char *relname)
static void
ClearPendingNotify()
{
Dlelem* p;
while ( (p = DLRemHead(pendingNotifies)) != NULL)
Dlelem *p;
while ((p = DLRemHead(pendingNotifies)) != NULL)
free(DLE_VAL(p));
}

View File

@ -14,7 +14,7 @@
*
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/commands/cluster.c,v 1.13 1997/08/19 21:30:45 momjian Exp $
* $Header: /cvsroot/pgsql/src/backend/commands/cluster.c,v 1.14 1997/09/07 04:40:36 momjian Exp $
*
*-------------------------------------------------------------------------
*/
@ -82,9 +82,12 @@ static void rebuildheap(Oid OIDNewHeap, Oid OIDOldHeap, Oid OIDOldIndex);
void
cluster(char oldrelname[], char oldindexname[])
{
Oid OIDOldHeap, OIDOldIndex, OIDNewHeap;
Oid OIDOldHeap,
OIDOldIndex,
OIDNewHeap;
Relation OldHeap, OldIndex;
Relation OldHeap,
OldIndex;
Relation NewHeap;
char NewIndexName[NAMEDATALEN];
@ -93,40 +96,43 @@ cluster(char oldrelname[], char oldindexname[])
char saveoldindexname[NAMEDATALEN];
/* Save the old names because they will get lost when the old relations
* are destroyed.
/*
* Save the old names because they will get lost when the old
* relations are destroyed.
*/
strcpy(saveoldrelname, oldrelname);
strcpy(saveoldindexname, oldindexname);
/*
*
* I'm going to force all checking back into the commands.c function.
*
* Get the list if indicies for this relation. If the index we want
* is among them, do not add it to the 'kill' list, as it will be
* handled by the 'clean up' code which commits this transaction.
* Get the list if indicies for this relation. If the index we want is
* among them, do not add it to the 'kill' list, as it will be handled
* by the 'clean up' code which commits this transaction.
*
* I'm not using the SysCache, because this will happen but
* once, and the slow way is the sure way in this case.
* I'm not using the SysCache, because this will happen but once, and the
* slow way is the sure way in this case.
*
*/
/*
* Like vacuum, cluster spans transactions, so I'm going to handle it in
* the same way.
* Like vacuum, cluster spans transactions, so I'm going to handle it
* in the same way.
*/
/* matches the StartTransaction in PostgresMain() */
OldHeap = heap_openr(oldrelname);
if (!RelationIsValid(OldHeap)) {
if (!RelationIsValid(OldHeap))
{
elog(WARN, "cluster: unknown relation: \"%s\"",
oldrelname);
}
OIDOldHeap = OldHeap->rd_id; /* Get OID for the index scan */
OIDOldHeap = OldHeap->rd_id;/* Get OID for the index scan */
OldIndex=index_openr(oldindexname);/* Open old index relation */
if (!RelationIsValid(OldIndex)) {
OldIndex = index_openr(oldindexname); /* Open old index relation */
if (!RelationIsValid(OldIndex))
{
elog(WARN, "cluster: unknown index: \"%s\"",
oldindexname);
}
@ -137,14 +143,15 @@ cluster(char oldrelname[], char oldindexname[])
/*
* I need to build the copies of the heap and the index. The Commit()
* between here is *very* bogus. If someone is appending stuff, they will
* get the lock after being blocked and add rows which won't be present in
* the new table. Bleagh! I'd be best to try and ensure that no-one's
* in the tables for the entire duration of this process with a pg_vlock.
* between here is *very* bogus. If someone is appending stuff, they
* will get the lock after being blocked and add rows which won't be
* present in the new table. Bleagh! I'd be best to try and ensure
* that no-one's in the tables for the entire duration of this process
* with a pg_vlock.
*/
NewHeap = copy_heap(OIDOldHeap);
OIDNewHeap = NewHeap->rd_id;
strcpy(NewHeapName,NewHeap->rd_rel->relname.data);
strcpy(NewHeapName, NewHeap->rd_rel->relname.data);
/* To make the new heap visible (which is until now empty). */
@ -160,8 +167,8 @@ cluster(char oldrelname[], char oldindexname[])
sprintf(NewIndexName, "temp_%x", OIDOldIndex);
/*
* make this really happen. Flush all the buffers.
* (Believe me, it is necessary ... ended up in a mess without it.)
* make this really happen. Flush all the buffers. (Believe me, it is
* necessary ... ended up in a mess without it.)
*/
CommitTransactionCommand();
StartTransactionCommand();
@ -186,18 +193,20 @@ static Relation
copy_heap(Oid OIDOldHeap)
{
char NewName[NAMEDATALEN];
TupleDesc OldHeapDesc, tupdesc;
TupleDesc OldHeapDesc,
tupdesc;
Oid OIDNewHeap;
Relation NewHeap, OldHeap;
Relation NewHeap,
OldHeap;
/*
* Create a new heap relation with a temporary name, which has the
* same tuple description as the old one.
*/
sprintf(NewName,"temp_%x", OIDOldHeap);
sprintf(NewName, "temp_%x", OIDOldHeap);
OldHeap= heap_open(OIDOldHeap);
OldHeapDesc= RelationGetTupleDescriptor(OldHeap);
OldHeap = heap_open(OIDOldHeap);
OldHeapDesc = RelationGetTupleDescriptor(OldHeap);
/*
* Need to make a copy of the tuple descriptor, heap_create modifies
@ -206,16 +215,16 @@ copy_heap(Oid OIDOldHeap)
tupdesc = CreateTupleDescCopy(OldHeapDesc);
OIDNewHeap=heap_create(NewName,
OIDNewHeap = heap_create(NewName,
NULL,
OldHeap->rd_rel->relarch,
OldHeap->rd_rel->relsmgr,
tupdesc);
if (!OidIsValid(OIDNewHeap))
elog(WARN,"clusterheap: cannot create temporary heap relation\n");
elog(WARN, "clusterheap: cannot create temporary heap relation\n");
NewHeap=heap_open(OIDNewHeap);
NewHeap = heap_open(OIDNewHeap);
heap_close(NewHeap);
heap_close(OldHeap);
@ -226,49 +235,51 @@ copy_heap(Oid OIDOldHeap)
static void
copy_index(Oid OIDOldIndex, Oid OIDNewHeap)
{
Relation OldIndex, NewHeap;
HeapTuple Old_pg_index_Tuple, Old_pg_index_relation_Tuple, pg_proc_Tuple;
Relation OldIndex,
NewHeap;
HeapTuple Old_pg_index_Tuple,
Old_pg_index_relation_Tuple,
pg_proc_Tuple;
IndexTupleForm Old_pg_index_Form;
Form_pg_class Old_pg_index_relation_Form;
Form_pg_proc pg_proc_Form;
char *NewIndexName;
AttrNumber *attnumP;
int natts;
FuncIndexInfo * finfo;
FuncIndexInfo *finfo;
NewHeap = heap_open(OIDNewHeap);
OldIndex = index_open(OIDOldIndex);
/*
* OK. Create a new (temporary) index for the one that's already
* here. To do this I get the info from pg_index, re-build the
* FunctInfo if I have to, and add a new index with a temporary
* name.
* OK. Create a new (temporary) index for the one that's already here.
* To do this I get the info from pg_index, re-build the FunctInfo if
* I have to, and add a new index with a temporary name.
*/
Old_pg_index_Tuple =
SearchSysCacheTuple(INDEXRELID,
ObjectIdGetDatum(OldIndex->rd_id),
0,0,0);
0, 0, 0);
Assert(Old_pg_index_Tuple);
Old_pg_index_Form = (IndexTupleForm)GETSTRUCT(Old_pg_index_Tuple);
Old_pg_index_Form = (IndexTupleForm) GETSTRUCT(Old_pg_index_Tuple);
Old_pg_index_relation_Tuple =
SearchSysCacheTuple(RELOID,
ObjectIdGetDatum(OldIndex->rd_id),
0,0,0);
0, 0, 0);
Assert(Old_pg_index_relation_Tuple);
Old_pg_index_relation_Form =
(Form_pg_class)GETSTRUCT(Old_pg_index_relation_Tuple);
(Form_pg_class) GETSTRUCT(Old_pg_index_relation_Tuple);
NewIndexName = palloc(NAMEDATALEN); /* XXX */
sprintf(NewIndexName, "temp_%x", OIDOldIndex); /* Set the name. */
/*
* Ugly as it is, the only way I have of working out the number of
* attribues is to count them. Mostly there'll be just one but
* I've got to be sure.
* attribues is to count them. Mostly there'll be just one but I've
* got to be sure.
*/
for (attnumP = &(Old_pg_index_Form->indkey[0]), natts = 0;
*attnumP != InvalidAttrNumber;
@ -278,7 +289,8 @@ copy_index(Oid OIDOldIndex, Oid OIDNewHeap)
* If this is a functional index, I need to rebuild the functional
* component to pass it to the defining procedure.
*/
if (Old_pg_index_Form->indproc != InvalidOid) {
if (Old_pg_index_Form->indproc != InvalidOid)
{
finfo = (FuncIndexInfo *) palloc(sizeof(FuncIndexInfo));
FIgetnArgs(finfo) = natts;
FIgetProcOid(finfo) = Old_pg_index_Form->indproc;
@ -286,12 +298,14 @@ copy_index(Oid OIDOldIndex, Oid OIDNewHeap)
pg_proc_Tuple =
SearchSysCacheTuple(PROOID,
ObjectIdGetDatum(Old_pg_index_Form->indproc),
0,0,0);
0, 0, 0);
Assert(pg_proc_Tuple);
pg_proc_Form = (Form_pg_proc)GETSTRUCT(pg_proc_Tuple);
pg_proc_Form = (Form_pg_proc) GETSTRUCT(pg_proc_Tuple);
namecpy(&(finfo->funcName), &(pg_proc_Form->proname));
} else {
}
else
{
finfo = (FuncIndexInfo *) NULL;
natts = 1;
}
@ -304,7 +318,7 @@ copy_index(Oid OIDOldIndex, Oid OIDNewHeap)
natts,
Old_pg_index_Form->indkey,
Old_pg_index_Form->indclass,
(uint16)0, (Datum) NULL, NULL,
(uint16) 0, (Datum) NULL, NULL,
Old_pg_index_Form->indislossy,
Old_pg_index_Form->indisunique);
@ -316,7 +330,9 @@ copy_index(Oid OIDOldIndex, Oid OIDNewHeap)
static void
rebuildheap(Oid OIDNewHeap, Oid OIDOldHeap, Oid OIDOldIndex)
{
Relation LocalNewHeap, LocalOldHeap, LocalOldIndex;
Relation LocalNewHeap,
LocalOldHeap,
LocalOldIndex;
IndexScanDesc ScanDesc;
RetrieveIndexResult ScanResult;
ItemPointer HeapTid;
@ -325,17 +341,18 @@ rebuildheap(Oid OIDNewHeap, Oid OIDOldHeap, Oid OIDOldIndex)
Oid OIDNewHeapInsert;
/*
* Open the relations I need. Scan through the OldHeap on the OldIndex and
* insert each tuple into the NewHeap.
* Open the relations I need. Scan through the OldHeap on the OldIndex
* and insert each tuple into the NewHeap.
*/
LocalNewHeap=(Relation)heap_open(OIDNewHeap);
LocalOldHeap=(Relation)heap_open(OIDOldHeap);
LocalOldIndex=(Relation)index_open(OIDOldIndex);
LocalNewHeap = (Relation) heap_open(OIDNewHeap);
LocalOldHeap = (Relation) heap_open(OIDOldHeap);
LocalOldIndex = (Relation) index_open(OIDOldIndex);
ScanDesc=index_beginscan(LocalOldIndex, false, 0, (ScanKey) NULL);
ScanDesc = index_beginscan(LocalOldIndex, false, 0, (ScanKey) NULL);
while ((ScanResult =
index_getnext(ScanDesc, ForwardScanDirection)) != NULL) {
index_getnext(ScanDesc, ForwardScanDirection)) != NULL)
{
HeapTid = &ScanResult->heap_iptr;
LocalHeapTuple = heap_fetch(LocalOldHeap, 0, HeapTid, &LocalBuffer);
@ -350,4 +367,3 @@ rebuildheap(Oid OIDNewHeap, Oid OIDOldHeap, Oid OIDOldIndex)
heap_close(LocalOldHeap);
heap_close(LocalNewHeap);
}

View File

@ -7,7 +7,7 @@
*
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/commands/Attic/command.c,v 1.13 1997/08/22 14:22:07 vadim Exp $
* $Header: /cvsroot/pgsql/src/backend/commands/Attic/command.c,v 1.14 1997/09/07 04:40:38 momjian Exp $
*
* NOTES
* The PortalExecutorHeapMemory crap needs to be eliminated
@ -106,7 +106,8 @@ PerformPortalFetch(char *name,
* sanity checks
* ----------------
*/
if (name == NULL) {
if (name == NULL)
{
elog(NOTICE, "PerformPortalFetch: blank portal unsupported");
return;
}
@ -116,7 +117,8 @@ PerformPortalFetch(char *name,
* ----------------
*/
portal = GetPortalByName(name);
if (! PortalIsValid(portal)) {
if (!PortalIsValid(portal))
{
elog(NOTICE, "PerformPortalFetch: portal \"%s\" not found",
name);
return;
@ -126,10 +128,10 @@ PerformPortalFetch(char *name,
* switch into the portal context
* ----------------
*/
context= MemoryContextSwitchTo((MemoryContext)PortalGetHeapMemory(portal));
context = MemoryContextSwitchTo((MemoryContext) PortalGetHeapMemory(portal));
AssertState(context ==
(MemoryContext)PortalGetHeapMemory(GetPortalByName(NULL)));
(MemoryContext) PortalGetHeapMemory(GetPortalByName(NULL)));
/* ----------------
* setup "feature" to tell the executor what direction and
@ -148,9 +150,12 @@ PerformPortalFetch(char *name,
queryDesc = PortalGetQueryDesc(portal);
BeginCommand(name,
queryDesc->operation,
portal->attinfo,/* QueryDescGetTypeInfo(queryDesc), */
false, /* portal fetches don't end up in relations */
false, /* this is a portal fetch, not a "retrieve portal" */
portal->attinfo, /* QueryDescGetTypeInfo(queryDesc),
* */
false, /* portal fetches don't end up in
* relations */
false, /* this is a portal fetch, not a "retrieve
* portal" */
tag,
dest);
@ -175,7 +180,7 @@ PerformPortalFetch(char *name,
* ----------------
*/
MemoryContextSwitchTo(
(MemoryContext)PortalGetHeapMemory(GetPortalByName(NULL)));
(MemoryContext) PortalGetHeapMemory(GetPortalByName(NULL)));
}
/* --------------------------------
@ -191,7 +196,8 @@ PerformPortalClose(char *name, CommandDest dest)
* sanity checks
* ----------------
*/
if (name == NULL) {
if (name == NULL)
{
elog(NOTICE, "PerformPortalClose: blank portal unsupported");
return;
}
@ -201,7 +207,8 @@ PerformPortalClose(char *name, CommandDest dest)
* ----------------
*/
portal = GetPortalByName(name);
if (! PortalIsValid(portal)) {
if (!PortalIsValid(portal))
{
elog(NOTICE, "PerformPortalClose: portal \"%s\" not found",
name);
return;
@ -248,16 +255,18 @@ void
PerformAddAttribute(char *relationName,
char *userName,
bool inherits,
ColumnDef *colDef)
ColumnDef * colDef)
{
Relation relrdesc, attrdesc;
Relation relrdesc,
attrdesc;
HeapScanDesc attsdesc;
HeapTuple reltup;
HeapTuple attributeTuple;
AttributeTupleForm attribute;
FormData_pg_attribute attributeD;
int i;
int minattnum, maxatts;
int minattnum,
maxatts;
HeapTuple tup;
ScanKeyData key[2];
ItemPointerData oldTID;
@ -279,29 +288,36 @@ PerformAddAttribute(char *relationName,
elog(WARN, "PerformAddAttribute: you do not own class \"%s\"",
relationName);
#endif
/*
* we can't add a not null attribute
*/
if (colDef->is_not_null)
elog(WARN,"Can't add a not null attribute to a existent relation");
elog(WARN, "Can't add a not null attribute to a existent relation");
if (colDef->defval)
elog(WARN,"ADD ATTRIBUTE: DEFAULT is not implemented, yet");
elog(WARN, "ADD ATTRIBUTE: DEFAULT is not implemented, yet");
/*
* if the first element in the 'schema' list is a "*" then we are
* supposed to add this attribute to all classes that inherit from
* 'relationName' (as well as to 'relationName').
*
* any permissions or problems with duplicate attributes will cause
* the whole transaction to abort, which is what we want -- all or
* any permissions or problems with duplicate attributes will cause the
* whole transaction to abort, which is what we want -- all or
* nothing.
*/
if (colDef != NULL) {
if (inherits) {
Oid myrelid, childrelid;
List *child, *children;
if (colDef != NULL)
{
if (inherits)
{
Oid myrelid,
childrelid;
List *child,
*children;
relrdesc = heap_openr(relationName);
if (!RelationIsValid(relrdesc)) {
if (!RelationIsValid(relrdesc))
{
elog(WARN, "PerformAddAttribute: unknown relation: \"%s\"",
relationName);
}
@ -309,19 +325,21 @@ PerformAddAttribute(char *relationName,
heap_close(relrdesc);
/* this routine is actually in the planner */
children = find_all_inheritors(lconsi(myrelid,NIL), NIL);
children = find_all_inheritors(lconsi(myrelid, NIL), NIL);
/*
* find_all_inheritors does the recursive search of the
* inheritance hierarchy, so all we have to do is process
* all of the relids in the list that it returns.
* inheritance hierarchy, so all we have to do is process all
* of the relids in the list that it returns.
*/
foreach (child, children) {
foreach(child, children)
{
childrelid = lfirsti(child);
if (childrelid == myrelid)
continue;
relrdesc = heap_open(childrelid);
if (!RelationIsValid(relrdesc)) {
if (!RelationIsValid(relrdesc))
{
elog(WARN, "PerformAddAttribute: can't find catalog entry for inheriting class with oid %d",
childrelid);
}
@ -335,15 +353,18 @@ PerformAddAttribute(char *relationName,
relrdesc = heap_openr(RelationRelationName);
reltup = ClassNameIndexScan(relrdesc, relationName);
if (!PointerIsValid(reltup)) {
if (!PointerIsValid(reltup))
{
heap_close(relrdesc);
elog(WARN, "PerformAddAttribute: relation \"%s\" not found",
relationName);
}
/*
* XXX is the following check sufficient?
*/
if (((Form_pg_class) GETSTRUCT(reltup))->relkind == RELKIND_INDEX) {
if (((Form_pg_class) GETSTRUCT(reltup))->relkind == RELKIND_INDEX)
{
elog(WARN, "PerformAddAttribute: index relation \"%s\" not changed",
relationName);
return;
@ -351,7 +372,8 @@ PerformAddAttribute(char *relationName,
minattnum = ((Form_pg_class) GETSTRUCT(reltup))->relnatts;
maxatts = minattnum + 1;
if (maxatts > MaxHeapAttributeNumber) {
if (maxatts > MaxHeapAttributeNumber)
{
pfree(reltup); /* XXX temp */
heap_close(relrdesc); /* XXX temp */
elog(WARN, "PerformAddAttribute: relations limited to %d attributes",
@ -374,13 +396,13 @@ PerformAddAttribute(char *relationName,
ScanKeyEntryInitialize(&key[0],
(bits16) NULL,
(AttrNumber) Anum_pg_attribute_attrelid,
(RegProcedure)ObjectIdEqualRegProcedure,
(RegProcedure) ObjectIdEqualRegProcedure,
(Datum) reltup->t_oid);
ScanKeyEntryInitialize(&key[1],
(bits16) NULL,
(AttrNumber) Anum_pg_attribute_attname,
(RegProcedure)NameEqualRegProcedure,
(RegProcedure) NameEqualRegProcedure,
(Datum) NULL);
attributeD.attrelid = reltup->t_oid;
@ -389,9 +411,9 @@ PerformAddAttribute(char *relationName,
attributeTuple = heap_addheader(Natts_pg_attribute,
sizeof attributeD,
(char *)&attributeD);
(char *) &attributeD);
attribute = (AttributeTupleForm)GETSTRUCT(attributeTuple);
attribute = (AttributeTupleForm) GETSTRUCT(attributeTuple);
i = 1 + minattnum;
@ -404,12 +426,13 @@ PerformAddAttribute(char *relationName,
/*
* XXX use syscache here as an optimization
*/
key[1].sk_argument = (Datum)colDef->colname;
key[1].sk_argument = (Datum) colDef->colname;
attsdesc = heap_beginscan(attrdesc, 0, NowTimeQual, 2, key);
tup = heap_getnext(attsdesc, 0, (Buffer *) NULL);
if (HeapTupleIsValid(tup)) {
if (HeapTupleIsValid(tup))
{
pfree(reltup); /* XXX temp */
heap_endscan(attsdesc); /* XXX temp */
heap_close(attrdesc); /* XXX temp */
@ -437,17 +460,19 @@ PerformAddAttribute(char *relationName,
typeTuple = SearchSysCacheTuple(TYPNAME,
PointerGetDatum(p),
0,0,0);
form = (TypeTupleForm)GETSTRUCT(typeTuple);
0, 0, 0);
form = (TypeTupleForm) GETSTRUCT(typeTuple);
if (!HeapTupleIsValid(typeTuple)) {
if (!HeapTupleIsValid(typeTuple))
{
elog(WARN, "Add: type \"%s\" nonexistent", p);
}
namestrcpy(&(attribute->attname), (char*) key[1].sk_argument);
namestrcpy(&(attribute->attname), (char *) key[1].sk_argument);
attribute->atttypid = typeTuple->t_oid;
if (colDef->typename->typlen > 0)
attribute->attlen = colDef->typename->typlen;
else /* bpchar, varchar, text */
else
/* bpchar, varchar, text */
attribute->attlen = form->typlen;
attribute->attnum = i;
attribute->attbyval = form->typbyval;

File diff suppressed because it is too large Load Diff

View File

@ -7,7 +7,7 @@
*
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/commands/Attic/creatinh.c,v 1.14 1997/08/22 03:03:56 vadim Exp $
* $Header: /cvsroot/pgsql/src/backend/commands/Attic/creatinh.c,v 1.15 1997/09/07 04:40:42 momjian Exp $
*
*-------------------------------------------------------------------------
*/
@ -33,10 +33,11 @@
* ----------------
*/
static int checkAttrExists(char *attributeName,
char *attributeType, List *schema);
static List *MergeAttributes(List *schema, List *supers, List **supconstr);
static void StoreCatalogInheritance(Oid relationId, List *supers);
static int
checkAttrExists(char *attributeName,
char *attributeType, List * schema);
static List *MergeAttributes(List * schema, List * supers, List ** supconstr);
static void StoreCatalogInheritance(Oid relationId, List * supers);
/* ----------------------------------------------------------------
* DefineRelation --
@ -44,7 +45,7 @@ static void StoreCatalogInheritance(Oid relationId, List *supers);
* ----------------------------------------------------------------
*/
void
DefineRelation(CreateStmt *stmt)
DefineRelation(CreateStmt * stmt)
{
char *relname = palloc(NAMEDATALEN);
List *schema = stmt->tableElts;
@ -55,14 +56,17 @@ DefineRelation(CreateStmt *stmt)
char *archiveName = NULL;
TupleDesc descriptor;
List *constraints;
int heaploc, archloc;
int heaploc,
archloc;
char* typename = NULL; /* the typename of this relation. not useod for now */
char *typename = NULL; /* the typename of this relation.
* not useod for now */
if ( strlen(stmt->relname) >= NAMEDATALEN)
if (strlen(stmt->relname) >= NAMEDATALEN)
elog(WARN, "the relation name %s is >= %d characters long", stmt->relname,
NAMEDATALEN);
strNcpy(relname,stmt->relname,NAMEDATALEN-1); /* make full length for copy */
strNcpy(relname, stmt->relname, NAMEDATALEN - 1); /* make full length for
* copy */
/* ----------------
* Handle parameters
@ -78,7 +82,8 @@ DefineRelation(CreateStmt *stmt)
*/
archChar = 'n';
switch (stmt->archiveType) {
switch (stmt->archiveType)
{
case ARCH_NONE:
archChar = 'n';
break;
@ -100,13 +105,17 @@ DefineRelation(CreateStmt *stmt)
heaploc = stmt->location;
/*
* For now, any user-defined relation defaults to the magnetic
* disk storgage manager. --mao 2 july 91
* For now, any user-defined relation defaults to the magnetic disk
* storgage manager. --mao 2 july 91
*/
if (stmt->archiveLoc == -1) {
if (stmt->archiveLoc == -1)
{
archloc = 0;
} else {
if (archChar == 'n') {
}
else
{
if (archChar == 'n')
{
elog(WARN, "Set archive location, but not mode, for %s",
relname);
}
@ -118,10 +127,11 @@ DefineRelation(CreateStmt *stmt)
* ----------------
*/
schema = MergeAttributes(schema, inheritList, &constraints);
constraints = nconc (constraints, stmt->constraints);
constraints = nconc(constraints, stmt->constraints);
numberOfAttributes = length(schema);
if (numberOfAttributes <= 0) {
if (numberOfAttributes <= 0)
{
elog(WARN, "DefineRelation: %s",
"please inherit from a relation or define an attribute");
}
@ -133,44 +143,44 @@ DefineRelation(CreateStmt *stmt)
*/
descriptor = BuildDescForRelation(schema, relname);
if ( constraints != NIL )
if (constraints != NIL)
{
List *entry;
int nconstr = length (constraints);
ConstrCheck *check = (ConstrCheck *) palloc (nconstr * sizeof (ConstrCheck));
int nconstr = length(constraints);
ConstrCheck *check = (ConstrCheck *) palloc(nconstr * sizeof(ConstrCheck));
int ncheck = 0;
int i;
foreach (entry, constraints)
foreach(entry, constraints)
{
ConstraintDef *cdef = (ConstraintDef *) lfirst (entry);
ConstraintDef *cdef = (ConstraintDef *) lfirst(entry);
if ( cdef->type == CONSTR_CHECK )
if (cdef->type == CONSTR_CHECK)
{
if ( cdef->name != NULL )
if (cdef->name != NULL)
{
for (i = 0; i < ncheck; i++)
{
if ( strcmp (check[i].ccname, cdef->name) == 0 )
elog (WARN, "DefineRelation: name (%s) of CHECK constraint duplicated", cdef->name);
if (strcmp(check[i].ccname, cdef->name) == 0)
elog(WARN, "DefineRelation: name (%s) of CHECK constraint duplicated", cdef->name);
}
check[ncheck].ccname = cdef->name;
}
else
{
check[ncheck].ccname = (char*) palloc (NAMEDATALEN);
sprintf (check[ncheck].ccname, "$%d", ncheck + 1);
check[ncheck].ccname = (char *) palloc(NAMEDATALEN);
sprintf(check[ncheck].ccname, "$%d", ncheck + 1);
}
check[ncheck].ccbin = NULL;
check[ncheck].ccsrc = (char*) cdef->def;
check[ncheck].ccsrc = (char *) cdef->def;
ncheck++;
}
}
if ( ncheck > 0 )
if (ncheck > 0)
{
if ( ncheck < nconstr )
check = (ConstrCheck *) repalloc (check, ncheck * sizeof (ConstrCheck));
if ( descriptor->constr == NULL )
if (ncheck < nconstr)
check = (ConstrCheck *) repalloc(check, ncheck * sizeof(ConstrCheck));
if (descriptor->constr == NULL)
{
descriptor->constr = (TupleConstr *) palloc(sizeof(TupleConstr));
descriptor->constr->num_defval = 0;
@ -195,24 +205,26 @@ DefineRelation(CreateStmt *stmt)
if (archChar != 'n')
{
TupleDesc tupdesc;
/*
* Need to create an archive relation for this heap relation.
* We cobble up the command by hand, and increment the command
* Need to create an archive relation for this heap relation. We
* cobble up the command by hand, and increment the command
* counter ourselves.
*/
CommandCounterIncrement();
archiveName = MakeArchiveName(relationId);
tupdesc = CreateTupleDescCopy (descriptor); /* get rid of constraints */
tupdesc = CreateTupleDescCopy(descriptor); /* get rid of
* constraints */
(void) heap_create(archiveName,
typename,
'n', /* archive isn't archived */
archloc,
tupdesc);
FreeTupleDesc (tupdesc);
FreeTupleDesc (descriptor);
FreeTupleDesc(tupdesc);
FreeTupleDesc(descriptor);
pfree(archiveName);
}
}
@ -268,37 +280,44 @@ RemoveRelation(char *name)
* stud_emp {7:percent}
*/
static List *
MergeAttributes(List *schema, List *supers, List **supconstr)
MergeAttributes(List * schema, List * supers, List ** supconstr)
{
List *entry;
List *inhSchema = NIL;
List *constraints = NIL;
/*
* Validates that there are no duplications.
* Validity checking of types occurs later.
* Validates that there are no duplications. Validity checking of
* types occurs later.
*/
foreach (entry, schema) {
foreach(entry, schema)
{
List *rest;
ColumnDef *coldef = lfirst(entry);
foreach (rest, lnext(entry)) {
foreach(rest, lnext(entry))
{
/*
* check for duplicated relation names
*/
ColumnDef *restdef = lfirst(rest);
if (!strcmp(coldef->colname, restdef->colname)) {
if (!strcmp(coldef->colname, restdef->colname))
{
elog(WARN, "attribute \"%s\" duplicated",
coldef->colname);
}
}
}
foreach (entry, supers) {
foreach(entry, supers)
{
List *rest;
foreach (rest, lnext(entry)) {
if (!strcmp(strVal(lfirst(entry)), strVal(lfirst(rest)))) {
foreach(rest, lnext(entry))
{
if (!strcmp(strVal(lfirst(entry)), strVal(lfirst(rest))))
{
elog(WARN, "relation \"%s\" duplicated",
strVal(lfirst(entry)));
}
@ -308,7 +327,8 @@ MergeAttributes(List *schema, List *supers, List **supconstr)
/*
* merge the inherited attributes into the schema
*/
foreach (entry, supers) {
foreach(entry, supers)
{
char *name = strVal(lfirst(entry));
Relation relation;
List *partialResult = NIL;
@ -317,12 +337,13 @@ MergeAttributes(List *schema, List *supers, List **supconstr)
TupleConstr *constr;
relation = heap_openr(name);
if (relation==NULL) {
if (relation == NULL)
{
elog(WARN,
"MergeAttr: Can't inherit from non-existent superclass '%s'",
name);
}
if ( relation->rd_rel->relkind == 'S' )
if (relation->rd_rel->relkind == 'S')
{
elog(WARN, "MergeAttr: Can't inherit from sequence superclass '%s'",
name);
@ -330,7 +351,8 @@ MergeAttributes(List *schema, List *supers, List **supconstr)
tupleDesc = RelationGetTupleDescriptor(relation);
constr = tupleDesc->constr;
for (attrno = relation->rd_rel->relnatts - 1; attrno >= 0; attrno--) {
for (attrno = relation->rd_rel->relnatts - 1; attrno >= 0; attrno--)
{
AttributeTupleForm attribute = tupleDesc->attrs[attrno];
char *attributeName;
char *attributeType;
@ -345,16 +367,19 @@ MergeAttributes(List *schema, List *supers, List **supconstr)
tuple =
SearchSysCacheTuple(TYPOID,
ObjectIdGetDatum(attribute->atttypid),
0,0,0);
0, 0, 0);
AssertState(HeapTupleIsValid(tuple));
attributeType =
(((TypeTupleForm)GETSTRUCT(tuple))->typname).data;
(((TypeTupleForm) GETSTRUCT(tuple))->typname).data;
/*
* check validity
*
*/
if (checkAttrExists(attributeName, attributeType, inhSchema) ||
checkAttrExists(attributeName, attributeType, schema)) {
checkAttrExists(attributeName, attributeType, schema))
{
/*
* this entry already exists
*/
@ -371,41 +396,41 @@ MergeAttributes(List *schema, List *supers, List **supconstr)
def->typename = typename;
def->is_not_null = attribute->attnotnull;
def->defval = NULL;
if ( attribute->atthasdef )
if (attribute->atthasdef)
{
AttrDefault *attrdef = constr->defval;
int i;
Assert ( constr != NULL && constr->num_defval > 0 );
Assert(constr != NULL && constr->num_defval > 0);
for (i = 0; i < constr->num_defval; i++)
{
if ( attrdef[i].adnum != attrno + 1 )
if (attrdef[i].adnum != attrno + 1)
continue;
def->defval = pstrdup (attrdef[i].adsrc);
def->defval = pstrdup(attrdef[i].adsrc);
break;
}
Assert ( def->defval != NULL );
Assert(def->defval != NULL);
}
partialResult = lcons(def, partialResult);
}
if ( constr && constr->num_check > 0 )
if (constr && constr->num_check > 0)
{
ConstrCheck *check = constr->check;
int i;
for (i = 0; i < constr->num_check; i++)
{
ConstraintDef *cdef = (ConstraintDef *) palloc (sizeof (ConstraintDef));
ConstraintDef *cdef = (ConstraintDef *) palloc(sizeof(ConstraintDef));
cdef->type = CONSTR_CHECK;
if ( check[i].ccname[0] == '$' )
if (check[i].ccname[0] == '$')
cdef->name = NULL;
else
cdef->name = pstrdup (check[i].ccname);
cdef->def = (void*) pstrdup (check[i].ccsrc);
constraints = lappend (constraints, cdef);
cdef->name = pstrdup(check[i].ccname);
cdef->def = (void *) pstrdup(check[i].ccsrc);
constraints = lappend(constraints, cdef);
}
}
@ -434,7 +459,7 @@ MergeAttributes(List *schema, List *supers, List **supconstr)
* Updates the system catalogs with proper inheritance information.
*/
static void
StoreCatalogInheritance(Oid relationId, List *supers)
StoreCatalogInheritance(Oid relationId, List * supers)
{
Relation relation;
TupleDesc desc;
@ -449,25 +474,26 @@ StoreCatalogInheritance(Oid relationId, List *supers)
*/
AssertArg(OidIsValid(relationId));
if (supers==NIL)
if (supers == NIL)
return;
/* ----------------
* Catalog INHERITS information.
* ----------------
*/
relation = heap_openr( InheritsRelationName );
relation = heap_openr(InheritsRelationName);
desc = RelationGetTupleDescriptor(relation);
seqNumber = 1;
idList = NIL;
foreach (entry, supers) {
Datum datum[ Natts_pg_inherits ];
char nullarr[ Natts_pg_inherits ];
foreach(entry, supers)
{
Datum datum[Natts_pg_inherits];
char nullarr[Natts_pg_inherits];
tuple = SearchSysCacheTuple(RELNAME,
PointerGetDatum(strVal(lfirst(entry))),
0,0,0);
0, 0, 0);
AssertArg(HeapTupleIsValid(tuple));
/*
@ -483,7 +509,7 @@ StoreCatalogInheritance(Oid relationId, List *supers)
nullarr[1] = ' ';
nullarr[2] = ' ';
tuple = heap_formtuple(desc,datum, nullarr);
tuple = heap_formtuple(desc, datum, nullarr);
heap_insert(relation, tuple);
pfree(tuple);
@ -508,24 +534,26 @@ StoreCatalogInheritance(Oid relationId, List *supers)
* 1.
* ----------------
*/
foreach (entry, idList) {
foreach(entry, idList)
{
HeapTuple tuple;
Oid id;
int16 number;
List *next;
List *current;
id = (Oid)lfirsti(entry);
id = (Oid) lfirsti(entry);
current = entry;
next = lnext(entry);
for (number = 1; ; number += 1) {
for (number = 1;; number += 1)
{
tuple = SearchSysCacheTuple(INHRELID,
ObjectIdGetDatum(id),
Int16GetDatum(number),
0,0);
0, 0);
if (! HeapTupleIsValid(tuple))
if (!HeapTupleIsValid(tuple))
break;
lnext(current) =
@ -542,20 +570,25 @@ StoreCatalogInheritance(Oid relationId, List *supers)
* 2.
* ----------------
*/
foreach (entry, idList) {
foreach(entry, idList)
{
Oid name;
List *rest;
bool found = false;
again:
again:
name = lfirsti(entry);
foreach (rest, lnext(entry)) {
if (name == lfirsti(rest)) {
foreach(rest, lnext(entry))
{
if (name == lfirsti(rest))
{
found = true;
break;
}
}
if (found) {
if (found)
{
/*
* entry list must be of length >= 2 or else no match
*
@ -573,25 +606,26 @@ StoreCatalogInheritance(Oid relationId, List *supers)
* 3.
* ----------------
*/
relation = heap_openr( InheritancePrecidenceListRelationName );
relation = heap_openr(InheritancePrecidenceListRelationName);
desc = RelationGetTupleDescriptor(relation);
seqNumber = 1;
foreach (entry, idList) {
Datum datum[ Natts_pg_ipl ];
char nullarr[ Natts_pg_ipl ];
foreach(entry, idList)
{
Datum datum[Natts_pg_ipl];
char nullarr[Natts_pg_ipl];
datum[0] = ObjectIdGetDatum(relationId); /* iplrel */
datum[1] = ObjectIdGetDatum(lfirsti(entry));
/*iplinherits*/
/* iplinherits */
datum[2] = Int16GetDatum(seqNumber); /* iplseqno */
nullarr[0] = ' ';
nullarr[1] = ' ';
nullarr[2] = ' ';
tuple = heap_formtuple( desc, datum, nullarr);
tuple = heap_formtuple(desc, datum, nullarr);
heap_insert(relation, tuple);
pfree(tuple);
@ -606,18 +640,22 @@ StoreCatalogInheritance(Oid relationId, List *supers)
* returns 1 if attribute already exists in schema, 0 otherwise.
*/
static int
checkAttrExists(char *attributeName, char *attributeType, List *schema)
checkAttrExists(char *attributeName, char *attributeType, List * schema)
{
List *s;
foreach (s, schema) {
foreach(s, schema)
{
ColumnDef *def = lfirst(s);
if (!strcmp(attributeName, def->colname)) {
if (!strcmp(attributeName, def->colname))
{
/*
* attribute exists. Make sure the types are the same.
*/
if (strcmp(attributeType, def->typename->name) != 0) {
if (strcmp(attributeType, def->typename->name) != 0)
{
elog(WARN, "%s and %s conflict for %s",
attributeType, def->typename->name, attributeName);
}
@ -634,18 +672,18 @@ checkAttrExists(char *attributeName, char *attributeType, List *schema)
* the CALLER is responsible for freeing the memory allocated
*/
char*
char *
MakeArchiveName(Oid relationId)
{
char *arch;
/*
* Archive relations are named a,XXXXX where XXXXX == the OID
* of the relation they archive. Create a string containing
* this name and find the reldesc for the archive relation.
* Archive relations are named a,XXXXX where XXXXX == the OID of the
* relation they archive. Create a string containing this name and
* find the reldesc for the archive relation.
*/
arch = palloc(NAMEDATALEN);
sprintf(arch, "a,%d",relationId);
sprintf(arch, "a,%d", relationId);
return arch;
}

View File

@ -7,7 +7,7 @@
*
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/commands/Attic/defind.c,v 1.12 1997/03/26 03:05:28 vadim Exp $
* $Header: /cvsroot/pgsql/src/backend/commands/Attic/defind.c,v 1.13 1997/09/07 04:40:43 momjian Exp $
*
*-------------------------------------------------------------------------
*/
@ -39,15 +39,18 @@
#define IsFuncIndex(ATTR_LIST) (((IndexElem*)lfirst(ATTR_LIST))->args!=NULL)
/* non-export function prototypes */
static void CheckPredicate(List *predList, List *rangeTable, Oid baseRelOid);
static void CheckPredExpr(Node *predicate, List *rangeTable,
static void CheckPredicate(List * predList, List * rangeTable, Oid baseRelOid);
static void
CheckPredExpr(Node * predicate, List * rangeTable,
Oid baseRelOid);
static void
CheckPredClause(Expr *predicate, List *rangeTable, Oid baseRelOid);
static void FuncIndexArgs(IndexElem *funcIndex, AttrNumber *attNumP,
Oid *argTypes, Oid *opOidP, Oid relId);
static void NormIndexAttrs(List *attList, AttrNumber *attNumP,
Oid *opOidP, Oid relId);
CheckPredClause(Expr * predicate, List * rangeTable, Oid baseRelOid);
static void
FuncIndexArgs(IndexElem * funcIndex, AttrNumber * attNumP,
Oid * argTypes, Oid * opOidP, Oid relId);
static void
NormIndexAttrs(List * attList, AttrNumber * attNumP,
Oid * opOidP, Oid relId);
static char *GetDefaultOpClass(Oid atttypid);
/*
@ -67,11 +70,11 @@ void
DefineIndex(char *heapRelationName,
char *indexRelationName,
char *accessMethodName,
List *attributeList,
List *parameterList,
List * attributeList,
List * parameterList,
bool unique,
Expr *predicate,
List *rangetable)
Expr * predicate,
List * rangetable)
{
Oid *classObjectId;
Oid accessMethodId;
@ -90,7 +93,8 @@ DefineIndex(char *heapRelationName,
* Handle attributes
*/
numberOfAttributes = length(attributeList);
if (numberOfAttributes <= 0) {
if (numberOfAttributes <= 0)
{
elog(WARN, "DefineIndex: must specify at least one attribute");
}
@ -99,25 +103,27 @@ DefineIndex(char *heapRelationName,
*/
tuple = SearchSysCacheTuple(RELNAME,
PointerGetDatum(heapRelationName),
0,0,0);
if (!HeapTupleIsValid(tuple)) {
0, 0, 0);
if (!HeapTupleIsValid(tuple))
{
elog(WARN, "DefineIndex: %s relation not found",
heapRelationName);
}
relationId = tuple->t_oid;
if (unique && strcmp(accessMethodName,"btree") != 0)
if (unique && strcmp(accessMethodName, "btree") != 0)
elog(WARN, "DefineIndex: unique indices are only available with the btree access method");
if (numberOfAttributes > 1 && strcmp(accessMethodName,"btree") != 0)
if (numberOfAttributes > 1 && strcmp(accessMethodName, "btree") != 0)
elog(WARN, "DefineIndex: multi-column indices are only available with the btree access method");
/*
* compute access method id
*/
tuple = SearchSysCacheTuple(AMNAME, PointerGetDatum(accessMethodName),
0,0,0);
if (!HeapTupleIsValid(tuple)) {
0, 0, 0);
if (!HeapTupleIsValid(tuple))
{
elog(WARN, "DefineIndex: %s access method not found",
accessMethodName);
}
@ -125,14 +131,14 @@ DefineIndex(char *heapRelationName,
/*
* Handle parameters
* [param list is now different (NOT USED, really) - ay 10/94]
* Handle parameters [param list is now different (NOT USED, really) -
* ay 10/94]
*
* WITH clause reinstated to handle lossy indices.
* -- JMH, 7/22/96
* WITH clause reinstated to handle lossy indices. -- JMH, 7/22/96
*/
foreach(pl, parameterList) {
ParamString *param = (ParamString*)lfirst(pl);
foreach(pl, parameterList)
{
ParamString *param = (ParamString *) lfirst(pl);
if (!strcasecmp(param->name, "islossy"))
lossy = TRUE;
@ -141,37 +147,40 @@ DefineIndex(char *heapRelationName,
/*
* Convert the partial-index predicate from parsetree form to plan
* form, so it can be readily evaluated during index creation.
* Note: "predicate" comes in as a list containing (1) the predicate
* itself (a where_clause), and (2) a corresponding range table.
* form, so it can be readily evaluated during index creation. Note:
* "predicate" comes in as a list containing (1) the predicate itself
* (a where_clause), and (2) a corresponding range table.
*
* [(1) is 'predicate' and (2) is 'rangetable' now. - ay 10/94]
*/
if (predicate != NULL && rangetable != NIL) {
cnfPred = cnfify((Expr*)copyObject(predicate), true);
if (predicate != NULL && rangetable != NIL)
{
cnfPred = cnfify((Expr *) copyObject(predicate), true);
fix_opids(cnfPred);
CheckPredicate(cnfPred, rangetable, relationId);
}
if (IsFuncIndex(attributeList)) {
IndexElem *funcIndex= lfirst(attributeList);
if (IsFuncIndex(attributeList))
{
IndexElem *funcIndex = lfirst(attributeList);
int nargs;
nargs = length(funcIndex->args);
if (nargs > INDEX_MAX_KEYS) {
if (nargs > INDEX_MAX_KEYS)
{
elog(WARN,
"Too many args to function, limit of %d",
INDEX_MAX_KEYS);
}
FIsetnArgs(&fInfo,nargs);
FIsetnArgs(&fInfo, nargs);
strcpy(FIgetname(&fInfo), funcIndex->name);
attributeNumberA =
(AttrNumber *)palloc(nargs * sizeof attributeNumberA[0]);
(AttrNumber *) palloc(nargs * sizeof attributeNumberA[0]);
classObjectId = (Oid *)palloc(sizeof classObjectId[0]);
classObjectId = (Oid *) palloc(sizeof classObjectId[0]);
FuncIndexArgs(funcIndex, attributeNumberA,
@ -182,15 +191,17 @@ DefineIndex(char *heapRelationName,
indexRelationName,
&fInfo, NULL, accessMethodId,
numberOfAttributes, attributeNumberA,
classObjectId, parameterCount, parameterA, (Node*)cnfPred,
classObjectId, parameterCount, parameterA, (Node *) cnfPred,
lossy, unique);
}else {
}
else
{
attributeNumberA =
(AttrNumber *)palloc(numberOfAttributes *
(AttrNumber *) palloc(numberOfAttributes *
sizeof attributeNumberA[0]);
classObjectId =
(Oid *)palloc(numberOfAttributes * sizeof classObjectId[0]);
(Oid *) palloc(numberOfAttributes * sizeof classObjectId[0]);
NormIndexAttrs(attributeList, attributeNumberA,
classObjectId, relationId);
@ -198,7 +209,7 @@ DefineIndex(char *heapRelationName,
index_create(heapRelationName, indexRelationName, NULL,
attributeList,
accessMethodId, numberOfAttributes, attributeNumberA,
classObjectId, parameterCount, parameterA, (Node*)cnfPred,
classObjectId, parameterCount, parameterA, (Node *) cnfPred,
lossy, unique);
}
}
@ -212,11 +223,12 @@ DefineIndex(char *heapRelationName,
* XXX
*/
void
ExtendIndex(char *indexRelationName, Expr *predicate, List *rangetable)
ExtendIndex(char *indexRelationName, Expr * predicate, List * rangetable)
{
Oid *classObjectId;
Oid accessMethodId;
Oid indexId, relationId;
Oid indexId,
relationId;
Oid indproc;
int numberOfAttributes;
AttrNumber *attributeNumberA;
@ -235,8 +247,9 @@ ExtendIndex(char *indexRelationName, Expr *predicate, List *rangetable)
* compute index relation id and access method id
*/
tuple = SearchSysCacheTuple(RELNAME, PointerGetDatum(indexRelationName),
0,0,0);
if (!HeapTupleIsValid(tuple)) {
0, 0, 0);
if (!HeapTupleIsValid(tuple))
{
elog(WARN, "ExtendIndex: %s index not found",
indexRelationName);
}
@ -248,8 +261,9 @@ ExtendIndex(char *indexRelationName, Expr *predicate, List *rangetable)
*/
tuple = SearchSysCacheTuple(INDEXRELID,
ObjectIdGetDatum(indexId),
0,0,0);
if (!HeapTupleIsValid(tuple)) {
0, 0, 0);
if (!HeapTupleIsValid(tuple))
{
elog(WARN, "ExtendIndex: %s is not an index",
indexRelationName);
}
@ -257,16 +271,18 @@ ExtendIndex(char *indexRelationName, Expr *predicate, List *rangetable)
/*
* Extract info from the pg_index tuple
*/
index = (IndexTupleForm)GETSTRUCT(tuple);
index = (IndexTupleForm) GETSTRUCT(tuple);
Assert(index->indexrelid == indexId);
relationId = index->indrelid;
indproc = index->indproc;
for (i=0; i<INDEX_MAX_KEYS; i++)
if (index->indkey[i] == 0) break;
for (i = 0; i < INDEX_MAX_KEYS; i++)
if (index->indkey[i] == 0)
break;
numberOfAttributes = i;
if (VARSIZE(&index->indpred) != 0) {
if (VARSIZE(&index->indpred) != 0)
{
char *predString;
predString = fmgr(F_TEXTOUT, &index->indpred);
@ -278,49 +294,52 @@ ExtendIndex(char *indexRelationName, Expr *predicate, List *rangetable)
indexRelationName);
/*
* Convert the extension predicate from parsetree form to plan
* form, so it can be readily evaluated during index creation.
* Note: "predicate" comes in as a list containing (1) the predicate
* itself (a where_clause), and (2) a corresponding range table.
* Convert the extension predicate from parsetree form to plan form,
* so it can be readily evaluated during index creation. Note:
* "predicate" comes in as a list containing (1) the predicate itself
* (a where_clause), and (2) a corresponding range table.
*/
if (rangetable != NIL) {
cnfPred = cnfify((Expr*)copyObject(predicate), true);
if (rangetable != NIL)
{
cnfPred = cnfify((Expr *) copyObject(predicate), true);
fix_opids(cnfPred);
CheckPredicate(cnfPred, rangetable, relationId);
}
/* make predInfo list to pass to index_build */
predInfo = (PredInfo*)palloc(sizeof(PredInfo));
predInfo->pred = (Node*)cnfPred;
predInfo = (PredInfo *) palloc(sizeof(PredInfo));
predInfo->pred = (Node *) cnfPred;
predInfo->oldPred = oldPred;
attributeNumberA =
(AttrNumber *)palloc(numberOfAttributes*
(AttrNumber *) palloc(numberOfAttributes *
sizeof attributeNumberA[0]);
classObjectId =
(Oid *)palloc(numberOfAttributes * sizeof classObjectId[0]);
(Oid *) palloc(numberOfAttributes * sizeof classObjectId[0]);
for (i=0; i<numberOfAttributes; i++) {
for (i = 0; i < numberOfAttributes; i++)
{
attributeNumberA[i] = index->indkey[i];
classObjectId[i] = index->indclass[i];
}
if (indproc != InvalidOid) {
if (indproc != InvalidOid)
{
funcInfo = &fInfo;
/* FIgetnArgs(funcInfo) = numberOfAttributes; */
FIsetnArgs(funcInfo,numberOfAttributes);
FIsetnArgs(funcInfo, numberOfAttributes);
tuple = SearchSysCacheTuple(PROOID,
ObjectIdGetDatum(indproc),
0,0,0);
0, 0, 0);
if (!HeapTupleIsValid(tuple))
elog(WARN, "ExtendIndex: index procedure not found");
namecpy(&(funcInfo->funcName),
&(((Form_pg_proc) GETSTRUCT(tuple))->proname));
FIsetProcOid(funcInfo,tuple->t_oid);
FIsetProcOid(funcInfo, tuple->t_oid);
}
heapRelation = heap_open(relationId);
@ -345,47 +364,53 @@ ExtendIndex(char *indexRelationName, Expr *predicate, List *rangetable)
*/
static void
CheckPredicate(List *predList, List *rangeTable, Oid baseRelOid)
CheckPredicate(List * predList, List * rangeTable, Oid baseRelOid)
{
List *item;
foreach (item, predList) {
foreach(item, predList)
{
CheckPredExpr(lfirst(item), rangeTable, baseRelOid);
}
}
static void
CheckPredExpr(Node *predicate, List *rangeTable, Oid baseRelOid)
CheckPredExpr(Node * predicate, List * rangeTable, Oid baseRelOid)
{
List *clauses = NIL, *clause;
List *clauses = NIL,
*clause;
if (is_opclause(predicate)) {
CheckPredClause((Expr*)predicate, rangeTable, baseRelOid);
if (is_opclause(predicate))
{
CheckPredClause((Expr *) predicate, rangeTable, baseRelOid);
return;
} else if (or_clause(predicate))
clauses = ((Expr*)predicate)->args;
}
else if (or_clause(predicate))
clauses = ((Expr *) predicate)->args;
else if (and_clause(predicate))
clauses = ((Expr*)predicate)->args;
clauses = ((Expr *) predicate)->args;
else
elog(WARN, "Unsupported partial-index predicate expression type");
foreach (clause, clauses) {
foreach(clause, clauses)
{
CheckPredExpr(lfirst(clause), rangeTable, baseRelOid);
}
}
static void
CheckPredClause(Expr *predicate, List *rangeTable, Oid baseRelOid)
CheckPredClause(Expr * predicate, List * rangeTable, Oid baseRelOid)
{
Var *pred_var;
Const *pred_const;
pred_var = (Var *)get_leftop(predicate);
pred_const = (Const *)get_rightop(predicate);
pred_var = (Var *) get_leftop(predicate);
pred_const = (Const *) get_rightop(predicate);
if (!IsA(predicate->oper,Oper) ||
!IsA(pred_var,Var) ||
!IsA(pred_const,Const)) {
if (!IsA(predicate->oper, Oper) ||
!IsA(pred_var, Var) ||
!IsA(pred_const, Const))
{
elog(WARN, "Unsupported partial-index predicate clause type");
}
@ -396,10 +421,10 @@ CheckPredClause(Expr *predicate, List *rangeTable, Oid baseRelOid)
static void
FuncIndexArgs(IndexElem *funcIndex,
AttrNumber *attNumP,
Oid *argTypes,
Oid *opOidP,
FuncIndexArgs(IndexElem * funcIndex,
AttrNumber * attNumP,
Oid * argTypes,
Oid * opOidP,
Oid relId)
{
List *rest;
@ -408,7 +433,7 @@ FuncIndexArgs(IndexElem *funcIndex,
tuple = SearchSysCacheTuple(CLANAME,
PointerGetDatum(funcIndex->class),
0,0,0);
0, 0, 0);
if (!HeapTupleIsValid(tuple))
{
@ -422,30 +447,32 @@ FuncIndexArgs(IndexElem *funcIndex,
/*
* process the function arguments
*/
for (rest=funcIndex->args; rest != NIL; rest = lnext(rest)) {
for (rest = funcIndex->args; rest != NIL; rest = lnext(rest))
{
char *arg;
arg = strVal(lfirst(rest));
tuple = SearchSysCacheTuple(ATTNAME,
ObjectIdGetDatum(relId),
PointerGetDatum(arg),0,0);
PointerGetDatum(arg), 0, 0);
if (!HeapTupleIsValid(tuple)) {
if (!HeapTupleIsValid(tuple))
{
elog(WARN,
"DefineIndex: attribute \"%s\" not found",
arg);
}
att = (AttributeTupleForm)GETSTRUCT(tuple);
att = (AttributeTupleForm) GETSTRUCT(tuple);
*attNumP++ = att->attnum;
*argTypes++ = att->atttypid;
}
}
static void
NormIndexAttrs(List *attList, /* list of IndexElem's */
AttrNumber *attNumP,
Oid *opOidP,
NormIndexAttrs(List * attList, /* list of IndexElem's */
AttrNumber * attNumP,
Oid * opOidP,
Oid relId)
{
List *rest;
@ -455,7 +482,8 @@ NormIndexAttrs(List *attList, /* list of IndexElem's */
* process attributeList
*/
for (rest=attList; rest != NIL; rest = lnext(rest)) {
for (rest = attList; rest != NIL; rest = lnext(rest))
{
IndexElem *attribute;
AttributeTupleForm attform;
@ -467,20 +495,23 @@ NormIndexAttrs(List *attList, /* list of IndexElem's */
tuple = SearchSysCacheTuple(ATTNAME,
ObjectIdGetDatum(relId),
PointerGetDatum(attribute->name),
0,0);
if (!HeapTupleIsValid(tuple)) {
0, 0);
if (!HeapTupleIsValid(tuple))
{
elog(WARN,
"DefineIndex: attribute \"%s\" not found",
attribute->name);
}
attform = (AttributeTupleForm)GETSTRUCT(tuple);
attform = (AttributeTupleForm) GETSTRUCT(tuple);
*attNumP++ = attform->attnum;
if (attribute->class == NULL) {
if (attribute->class == NULL)
{
/* no operator class specified, so find the default */
attribute->class = GetDefaultOpClass(attform->atttypid);
if(attribute->class == NULL) {
if (attribute->class == NULL)
{
elog(WARN,
"Can't find a default operator class for type %d.",
attform->atttypid);
@ -489,9 +520,10 @@ NormIndexAttrs(List *attList, /* list of IndexElem's */
tuple = SearchSysCacheTuple(CLANAME,
PointerGetDatum(attribute->class),
0,0,0);
0, 0, 0);
if (!HeapTupleIsValid(tuple)) {
if (!HeapTupleIsValid(tuple))
{
elog(WARN, "DefineIndex: %s class not found",
attribute->class);
}
@ -507,11 +539,12 @@ GetDefaultOpClass(Oid atttypid)
tuple = SearchSysCacheTuple(CLADEFTYPE,
ObjectIdGetDatum(atttypid),
0, 0, 0);
if(!HeapTupleIsValid(tuple)) {
if (!HeapTupleIsValid(tuple))
{
return 0;
}
return nameout(&(((Form_pg_opclass)GETSTRUCT(tuple))->opcname));
return nameout(&(((Form_pg_opclass) GETSTRUCT(tuple))->opcname));
}
/*
@ -530,16 +563,18 @@ RemoveIndex(char *name)
tuple = SearchSysCacheTuple(RELNAME,
PointerGetDatum(name),
0,0,0);
0, 0, 0);
if (!HeapTupleIsValid(tuple)) {
if (!HeapTupleIsValid(tuple))
{
elog(WARN, "index \"%s\" nonexistent", name);
}
if (((Form_pg_class)GETSTRUCT(tuple))->relkind != RELKIND_INDEX) {
if (((Form_pg_class) GETSTRUCT(tuple))->relkind != RELKIND_INDEX)
{
elog(WARN, "relation \"%s\" is of type \"%c\"",
name,
((Form_pg_class)GETSTRUCT(tuple))->relkind);
((Form_pg_class) GETSTRUCT(tuple))->relkind);
}
index_destroy(tuple->t_oid);

View File

@ -9,7 +9,7 @@
*
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/commands/define.c,v 1.13 1997/08/12 22:52:23 momjian Exp $
* $Header: /cvsroot/pgsql/src/backend/commands/define.c,v 1.14 1997/09/07 04:40:46 momjian Exp $
*
* DESCRIPTION
* The "DefineFoo" routines take the parse tree and pick out the
@ -53,14 +53,15 @@
#include <tcop/dest.h>
#include <catalog/pg_user.h>
static char *defGetString(DefElem *def);
static int defGetTypeLength(DefElem *def);
static char *defGetString(DefElem * def);
static int defGetTypeLength(DefElem * def);
#define DEFAULT_TYPDELIM ','
static void
case_translate_language_name(const char *input, char *output) {
case_translate_language_name(const char *input, char *output)
{
/*-------------------------------------------------------------------------
Translate the input language name to lower case, except if it's C,
translate to upper case.
@ -72,24 +73,30 @@ case_translate_language_name(const char *input, char *output) {
output[i] = '\0';
if (strcmp(output, "c") == 0) output[0] = 'C';
if (strcmp(output, "c") == 0)
output[0] = 'C';
}
static void
compute_return_type(const Node *returnType,
char **prorettype_p, bool *returnsSet_p) {
compute_return_type(const Node * returnType,
char **prorettype_p, bool * returnsSet_p)
{
/*---------------------------------------------------------------------------
Examine the "returns" clause returnType of the CREATE FUNCTION statement
and return information about it as **prorettype_p and **returnsSet.
----------------------------------------------------------------------------*/
if (nodeTag(returnType) == T_TypeName) {
if (nodeTag(returnType) == T_TypeName)
{
/* a set of values */
TypeName *setType = (TypeName *)returnType;
TypeName *setType = (TypeName *) returnType;
*prorettype_p = setType->name;
*returnsSet_p = true;
}else {
}
else
{
/* singleton */
*prorettype_p = strVal(returnType);
*returnsSet_p = false;
@ -99,9 +106,10 @@ compute_return_type(const Node *returnType,
static void
compute_full_attributes(const List *parameters, int32 *byte_pct_p,
int32 *perbyte_cpu_p, int32 *percall_cpu_p,
int32 *outin_ratio_p, bool *canCache_p) {
compute_full_attributes(const List * parameters, int32 * byte_pct_p,
int32 * perbyte_cpu_p, int32 * percall_cpu_p,
int32 * outin_ratio_p, bool * canCache_p)
{
/*--------------------------------------------------------------------------
Interpret the parameters *parameters and return their contents as
*byte_pct_p, etc.
@ -116,40 +124,59 @@ compute_full_attributes(const List *parameters, int32 *byte_pct_p,
*percall_cpu_p = PERCALL_CPU;
*outin_ratio_p = OUTIN_RATIO;
foreach(pl, (List *)parameters) {
ParamString *param = (ParamString*)lfirst(pl);
foreach(pl, (List *) parameters)
{
ParamString *param = (ParamString *) lfirst(pl);
if (strcasecmp(param->name, "iscachable") == 0) {
if (strcasecmp(param->name, "iscachable") == 0)
{
*canCache_p = true;
} else if (strcasecmp(param->name, "trusted") == 0) {
}
else if (strcasecmp(param->name, "trusted") == 0)
{
/*
* we don't have untrusted functions any more. The 4.2
* implementation is lousy anyway so I took it out.
* -ay 10/94
* implementation is lousy anyway so I took it out. -ay 10/94
*/
elog(WARN, "untrusted function has been decommissioned.");
} else if (strcasecmp(param->name, "byte_pct") == 0) {
}
else if (strcasecmp(param->name, "byte_pct") == 0)
{
/*
** handle expensive function parameters
* * handle expensive function parameters
*/
*byte_pct_p = atoi(param->val);
} else if (strcasecmp(param->name, "perbyte_cpu") == 0) {
if (sscanf(param->val, "%d", perbyte_cpu_p) == 0) {
}
else if (strcasecmp(param->name, "perbyte_cpu") == 0)
{
if (sscanf(param->val, "%d", perbyte_cpu_p) == 0)
{
int count;
char *ptr;
for (count = 0, ptr = param->val; *ptr != '\0'; ptr++)
if (*ptr == '!') count++;
if (*ptr == '!')
count++;
*perbyte_cpu_p = (int) pow(10.0, (double) count);
}
} else if (strcasecmp(param->name, "percall_cpu") == 0) {
if (sscanf(param->val, "%d", percall_cpu_p) == 0) {
}
else if (strcasecmp(param->name, "percall_cpu") == 0)
{
if (sscanf(param->val, "%d", percall_cpu_p) == 0)
{
int count;
char *ptr;
for (count = 0, ptr = param->val; *ptr != '\0'; ptr++)
if (*ptr == '!') count++;
if (*ptr == '!')
count++;
*percall_cpu_p = (int) pow(10.0, (double) count);
}
} else if (strcasecmp(param->name, "outin_ratio") == 0) {
}
else if (strcasecmp(param->name, "outin_ratio") == 0)
{
*outin_ratio_p = atoi(param->val);
}
}
@ -159,14 +186,18 @@ compute_full_attributes(const List *parameters, int32 *byte_pct_p,
static void
interpret_AS_clause(const char languageName[], const char as[],
char **prosrc_str_p, char **probin_str_p) {
char **prosrc_str_p, char **probin_str_p)
{
if ( strcmp(languageName, "C") == 0 ||
strcmp(languageName, "internal") == 0 ) {
if (strcmp(languageName, "C") == 0 ||
strcmp(languageName, "internal") == 0)
{
*prosrc_str_p = "-";
*probin_str_p = (char *)as;
} else {
*prosrc_str_p = (char *)as;
*probin_str_p = (char *) as;
}
else
{
*prosrc_str_p = (char *) as;
*probin_str_p = "-";
}
}
@ -179,24 +210,35 @@ interpret_AS_clause(const char languageName[], const char as[],
*
*/
void
CreateFunction(ProcedureStmt *stmt, CommandDest dest)
CreateFunction(ProcedureStmt * stmt, CommandDest dest)
{
char *probin_str;
/* pathname of executable file that executes this function, if any */
char *prosrc_str;
/* SQL that executes this function, if any */
char *prorettype;
/* Type of return value (or member of set of values) from function */
char languageName[NAMEDATALEN];
/* name of language of function, with case adjusted:
"C", "internal", or "SQL"
/*
* name of language of function, with case adjusted: "C", "internal",
* or "SQL"
*/
/* The following are attributes of the function, as expressed in the
CREATE FUNCTION statement, where applicable.
/*
* The following are attributes of the function, as expressed in the
* CREATE FUNCTION statement, where applicable.
*/
int32 byte_pct, perbyte_cpu, percall_cpu, outin_ratio;
int32 byte_pct,
perbyte_cpu,
percall_cpu,
outin_ratio;
bool canCache;
bool returnsSet;
/* The function returns a set of values, as opposed to a singleton. */
@ -204,17 +246,22 @@ CreateFunction(ProcedureStmt *stmt, CommandDest dest)
compute_return_type(stmt->returnType, &prorettype, &returnsSet);
if ( strcmp(languageName, "C") == 0 ||
strcmp(languageName, "internal") == 0 ) {
if (strcmp(languageName, "C") == 0 ||
strcmp(languageName, "internal") == 0)
{
compute_full_attributes(stmt->withClause,
&byte_pct, &perbyte_cpu, &percall_cpu,
&outin_ratio, &canCache);
} else if (strcmp(languageName, "sql") == 0) {
}
else if (strcmp(languageName, "sql") == 0)
{
/* query optimizer groks sql, these are meaningless */
perbyte_cpu = percall_cpu = 0;
byte_pct = outin_ratio = 100;
canCache = false;
} else {
}
else
{
elog(WARN,
"Unrecognized language specified in a CREATE FUNCTION: "
"'%s'. Recognized languages are sql, C, and internal.",
@ -230,9 +277,12 @@ CreateFunction(ProcedureStmt *stmt, CommandDest dest)
"in the '%s' language. Others may use the 'sql' language.",
languageName);
/* Above does not return. */
else {
/* And now that we have all the parameters, and know we're permitted
to do so, go ahead and create the function.
else
{
/*
* And now that we have all the parameters, and know we're
* permitted to do so, go ahead and create the function.
*/
ProcedureCreate(stmt->funcname,
returnsSet,
@ -265,67 +315,99 @@ CreateFunction(ProcedureStmt *stmt, CommandDest dest)
*/
void
DefineOperator(char *oprName,
List *parameters)
List * parameters)
{
uint16 precedence=0; /* operator precedence */
bool canHash=false; /* operator hashes */
bool isLeftAssociative=true; /* operator is left associative */
char *functionName=NULL; /* function for operator */
char *typeName1=NULL; /* first type name */
char *typeName2=NULL; /* second type name */
char *commutatorName=NULL; /* optional commutator operator name */
char *negatorName=NULL; /* optional negator operator name */
char *restrictionName=NULL; /* optional restrict. sel. procedure */
char *joinName=NULL; /* optional join sel. procedure name */
char *sortName1=NULL; /* optional first sort operator */
char *sortName2=NULL; /* optional second sort operator */
uint16 precedence = 0; /* operator precedence */
bool canHash = false; /* operator hashes */
bool isLeftAssociative = true; /* operator is left
* associative */
char *functionName = NULL; /* function for operator */
char *typeName1 = NULL; /* first type name */
char *typeName2 = NULL; /* second type name */
char *commutatorName = NULL; /* optional commutator
* operator name */
char *negatorName = NULL; /* optional negator operator name */
char *restrictionName = NULL; /* optional restrict. sel.
* procedure */
char *joinName = NULL; /* optional join sel. procedure
* name */
char *sortName1 = NULL; /* optional first sort operator */
char *sortName2 = NULL; /* optional second sort operator */
List *pl;
/*
* loop over the definition list and extract the information we need.
*/
foreach (pl, parameters) {
DefElem *defel = (DefElem *)lfirst(pl);
foreach(pl, parameters)
{
DefElem *defel = (DefElem *) lfirst(pl);
if (!strcasecmp(defel->defname, "leftarg")) {
if (!strcasecmp(defel->defname, "leftarg"))
{
/* see gram.y, must be setof */
if (nodeTag(defel->arg)==T_TypeName)
if (nodeTag(defel->arg) == T_TypeName)
elog(WARN, "setof type not implemented for leftarg");
if (nodeTag(defel->arg)==T_String) {
if (nodeTag(defel->arg) == T_String)
{
typeName1 = defGetString(defel);
}else {
}
else
{
elog(WARN, "type for leftarg is malformed.");
}
} else if (!strcasecmp(defel->defname, "rightarg")) {
}
else if (!strcasecmp(defel->defname, "rightarg"))
{
/* see gram.y, must be setof */
if (nodeTag(defel->arg)==T_TypeName)
if (nodeTag(defel->arg) == T_TypeName)
elog(WARN, "setof type not implemented for rightarg");
if (nodeTag(defel->arg)==T_String) {
if (nodeTag(defel->arg) == T_String)
{
typeName2 = defGetString(defel);
}else {
}
else
{
elog(WARN, "type for rightarg is malformed.");
}
} else if (!strcasecmp(defel->defname, "procedure")) {
}
else if (!strcasecmp(defel->defname, "procedure"))
{
functionName = defGetString(defel);
} else if (!strcasecmp(defel->defname, "precedence")) {
}
else if (!strcasecmp(defel->defname, "precedence"))
{
/* NOT IMPLEMENTED (never worked in v4.2) */
elog(NOTICE, "CREATE OPERATOR: precedence not implemented");
} else if (!strcasecmp(defel->defname, "associativity")) {
}
else if (!strcasecmp(defel->defname, "associativity"))
{
/* NOT IMPLEMENTED (never worked in v4.2) */
elog(NOTICE, "CREATE OPERATOR: associativity not implemented");
} else if (!strcasecmp(defel->defname, "commutator")) {
}
else if (!strcasecmp(defel->defname, "commutator"))
{
commutatorName = defGetString(defel);
} else if (!strcasecmp(defel->defname, "negator")) {
}
else if (!strcasecmp(defel->defname, "negator"))
{
negatorName = defGetString(defel);
} else if (!strcasecmp(defel->defname, "restrict")) {
}
else if (!strcasecmp(defel->defname, "restrict"))
{
restrictionName = defGetString(defel);
} else if (!strcasecmp(defel->defname, "join")) {
}
else if (!strcasecmp(defel->defname, "join"))
{
joinName = defGetString(defel);
} else if (!strcasecmp(defel->defname, "hashes")) {
}
else if (!strcasecmp(defel->defname, "hashes"))
{
canHash = TRUE;
} else if (!strcasecmp(defel->defname, "sort1")) {
}
else if (!strcasecmp(defel->defname, "sort1"))
{
/* ----------------
* XXX ( ... [ , sort1 = oprname ] [ , sort2 = oprname ] ... )
* XXX is undocumented in the reference manual source as of
@ -333,9 +415,13 @@ DefineOperator(char *oprName,
* ----------------
*/
sortName1 = defGetString(defel);
} else if (!strcasecmp(defel->defname, "sort2")) {
}
else if (!strcasecmp(defel->defname, "sort2"))
{
sortName2 = defGetString(defel);
} else {
}
else
{
elog(NOTICE, "DefineOperator: attribute \"%s\" not recognized",
defel->defname);
}
@ -344,7 +430,8 @@ DefineOperator(char *oprName,
/*
* make sure we have our required definitions
*/
if (functionName==NULL) {
if (functionName == NULL)
{
elog(WARN, "Define: \"procedure\" unspecified");
}
@ -355,12 +442,14 @@ DefineOperator(char *oprName,
OperatorCreate(oprName, /* operator name */
typeName1, /* first type name */
typeName2, /* second type name */
functionName, /* function for operator */
functionName,/* function for operator */
precedence, /* operator precedence */
isLeftAssociative, /* operator is left associative */
commutatorName, /* optional commutator operator name */
commutatorName, /* optional commutator operator
* name */
negatorName, /* optional negator operator name */
restrictionName, /* optional restrict. sel. procedure */
restrictionName, /* optional restrict. sel.
* procedure */
joinName, /* optional join sel. procedure name */
canHash, /* operator hashes */
sortName1, /* optional first sort operator */
@ -373,7 +462,7 @@ DefineOperator(char *oprName,
* ------------------
*/
void
DefineAggregate(char *aggName, List *parameters)
DefineAggregate(char *aggName, List * parameters)
{
char *stepfunc1Name = NULL;
@ -386,39 +475,59 @@ DefineAggregate(char *aggName, List *parameters)
char *init2 = NULL;
List *pl;
foreach (pl, parameters) {
DefElem *defel = (DefElem *)lfirst(pl);
foreach(pl, parameters)
{
DefElem *defel = (DefElem *) lfirst(pl);
/*
* sfunc1
*/
if (!strcasecmp(defel->defname, "sfunc1")) {
if (!strcasecmp(defel->defname, "sfunc1"))
{
stepfunc1Name = defGetString(defel);
} else if (!strcasecmp(defel->defname, "basetype")) {
}
else if (!strcasecmp(defel->defname, "basetype"))
{
baseType = defGetString(defel);
} else if (!strcasecmp(defel->defname, "stype1")) {
}
else if (!strcasecmp(defel->defname, "stype1"))
{
stepfunc1Type = defGetString(defel);
/*
* sfunc2
*/
} else if (!strcasecmp(defel->defname, "sfunc2")) {
}
else if (!strcasecmp(defel->defname, "sfunc2"))
{
stepfunc2Name = defGetString(defel);
} else if (!strcasecmp(defel->defname, "stype2")) {
}
else if (!strcasecmp(defel->defname, "stype2"))
{
stepfunc2Type = defGetString(defel);
/*
* final
*/
} else if (!strcasecmp(defel->defname, "finalfunc")) {
}
else if (!strcasecmp(defel->defname, "finalfunc"))
{
finalfuncName = defGetString(defel);
/*
* initial conditions
*/
} else if (!strcasecmp(defel->defname, "initcond1")) {
}
else if (!strcasecmp(defel->defname, "initcond1"))
{
init1 = defGetString(defel);
} else if (!strcasecmp(defel->defname, "initcond2")) {
}
else if (!strcasecmp(defel->defname, "initcond2"))
{
init2 = defGetString(defel);
} else {
}
else
{
elog(NOTICE, "DefineAggregate: attribute \"%s\" not recognized",
defel->defname);
}
@ -427,14 +536,16 @@ DefineAggregate(char *aggName, List *parameters)
/*
* make sure we have our required definitions
*/
if (baseType==NULL)
if (baseType == NULL)
elog(WARN, "Define: \"basetype\" unspecified");
if (stepfunc1Name!=NULL) {
if (stepfunc1Type==NULL)
if (stepfunc1Name != NULL)
{
if (stepfunc1Type == NULL)
elog(WARN, "Define: \"stype1\" unspecified");
}
if (stepfunc2Name!=NULL) {
if (stepfunc2Type==NULL)
if (stepfunc2Name != NULL)
{
if (stepfunc2Type == NULL)
elog(WARN, "Define: \"stype2\" unspecified");
}
@ -460,10 +571,10 @@ DefineAggregate(char *aggName, List *parameters)
*
*/
void
DefineType(char *typeName, List *parameters)
DefineType(char *typeName, List * parameters)
{
int16 internalLength= 0; /* int2 */
int16 externalLength= 0; /* int2 */
int16 internalLength = 0; /* int2 */
int16 externalLength = 0; /* int2 */
char *elemName = NULL;
char *inputName = NULL;
char *outputName = NULL;
@ -480,46 +591,78 @@ DefineType(char *typeName, List *parameters)
* Type names can only be 15 characters long, so that the shadow type
* can be created using the 16th character as necessary.
*/
if (strlen(typeName) >= (NAMEDATALEN - 1)) {
if (strlen(typeName) >= (NAMEDATALEN - 1))
{
elog(WARN, "DefineType: type names must be %d characters or less",
NAMEDATALEN - 1);
}
foreach(pl, parameters) {
DefElem *defel = (DefElem*)lfirst(pl);
foreach(pl, parameters)
{
DefElem *defel = (DefElem *) lfirst(pl);
if (!strcasecmp(defel->defname, "internallength")) {
if (!strcasecmp(defel->defname, "internallength"))
{
internalLength = defGetTypeLength(defel);
}else if (!strcasecmp(defel->defname, "externallength")) {
}
else if (!strcasecmp(defel->defname, "externallength"))
{
externalLength = defGetTypeLength(defel);
}else if (!strcasecmp(defel->defname, "input")) {
}
else if (!strcasecmp(defel->defname, "input"))
{
inputName = defGetString(defel);
}else if (!strcasecmp(defel->defname, "output")) {
}
else if (!strcasecmp(defel->defname, "output"))
{
outputName = defGetString(defel);
}else if (!strcasecmp(defel->defname, "send")) {
}
else if (!strcasecmp(defel->defname, "send"))
{
sendName = defGetString(defel);
}else if (!strcasecmp(defel->defname, "delimiter")) {
}
else if (!strcasecmp(defel->defname, "delimiter"))
{
char *p = defGetString(defel);
delimiter = p[0];
}else if (!strcasecmp(defel->defname, "receive")) {
}
else if (!strcasecmp(defel->defname, "receive"))
{
receiveName = defGetString(defel);
}else if (!strcasecmp(defel->defname, "element")) {
}
else if (!strcasecmp(defel->defname, "element"))
{
elemName = defGetString(defel);
}else if (!strcasecmp(defel->defname, "default")) {
}
else if (!strcasecmp(defel->defname, "default"))
{
defaultValue = defGetString(defel);
}else if (!strcasecmp(defel->defname, "passedbyvalue")) {
}
else if (!strcasecmp(defel->defname, "passedbyvalue"))
{
byValue = true;
}else if (!strcasecmp(defel->defname, "alignment")) {
}
else if (!strcasecmp(defel->defname, "alignment"))
{
char *a = defGetString(defel);
if (!strcasecmp(a, "double")) {
if (!strcasecmp(a, "double"))
{
alignment = 'd';
} else if (!strcasecmp(a, "int")) {
}
else if (!strcasecmp(a, "int"))
{
alignment = 'i';
} else {
}
else
{
elog(WARN, "DefineType: \"%s\" alignment not recognized",
a);
}
}else {
}
else
{
elog(NOTICE, "DefineType: attribute \"%s\" not recognized",
defel->defname);
}
@ -528,9 +671,9 @@ DefineType(char *typeName, List *parameters)
/*
* make sure we have our required definitions
*/
if (inputName==NULL)
if (inputName == NULL)
elog(WARN, "Define: \"input\" unspecified");
if (outputName==NULL)
if (outputName == NULL)
elog(WARN, "Define: \"output\" unspecified");
/* ----------------
@ -564,7 +707,7 @@ DefineType(char *typeName, List *parameters)
-1, /* internal size */
-1, /* external size */
'b', /* type-type (base type) */
DEFAULT_TYPDELIM, /* array element delimiter */
DEFAULT_TYPDELIM,/* array element delimiter */
"array_in", /* input procedure */
"array_out", /* output procedure */
"array_out", /* send procedure */
@ -578,20 +721,20 @@ DefineType(char *typeName, List *parameters)
}
static char *
defGetString(DefElem *def)
defGetString(DefElem * def)
{
if (nodeTag(def->arg)!=T_String)
if (nodeTag(def->arg) != T_String)
elog(WARN, "Define: \"%s\" = what?", def->defname);
return (strVal(def->arg));
}
static int
defGetTypeLength(DefElem *def)
defGetTypeLength(DefElem * def)
{
if (nodeTag(def->arg)==T_Integer)
if (nodeTag(def->arg) == T_Integer)
return (intVal(def->arg));
else if (nodeTag(def->arg)==T_String &&
!strcasecmp(strVal(def->arg),"variable"))
else if (nodeTag(def->arg) == T_String &&
!strcasecmp(strVal(def->arg), "variable"))
return -1; /* variable length */
elog(WARN, "Define: \"%s\" = what?", def->defname);

View File

@ -7,7 +7,7 @@
*
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/commands/explain.c,v 1.10 1997/08/18 20:52:17 momjian Exp $
* $Header: /cvsroot/pgsql/src/backend/commands/explain.c,v 1.11 1997/09/07 04:40:49 momjian Exp $
*
*-------------------------------------------------------------------------
*/
@ -25,7 +25,8 @@
#include <optimizer/planner.h>
#include <access/xact.h>
typedef struct ExplainState {
typedef struct ExplainState
{
/* options */
bool printCost; /* print cost */
bool printNodes; /* do nodeToString() instead */
@ -33,7 +34,7 @@ typedef struct ExplainState {
List *rtable; /* range table */
} ExplainState;
static char *Explain_PlanToString(Plan *plan, ExplainState *es);
static char *Explain_PlanToString(Plan * plan, ExplainState * es);
/*
* ExplainQuery -
@ -41,15 +42,18 @@ static char *Explain_PlanToString(Plan *plan, ExplainState *es);
*
*/
void
ExplainQuery(Query *query, bool verbose, CommandDest dest)
ExplainQuery(Query * query, bool verbose, CommandDest dest)
{
char *s = NULL, *s2;
char *s = NULL,
*s2;
Plan *plan;
ExplainState *es;
int len;
if (IsAbortedTransactionBlockState()) {
if (IsAbortedTransactionBlockState())
{
char *tag = "*ABORT STATE*";
EndCommand(tag, dest);
elog(NOTICE, "(transaction aborted): %s",
@ -65,7 +69,7 @@ ExplainQuery(Query *query, bool verbose, CommandDest dest)
if (plan == NULL)
return;
es = (ExplainState*)malloc(sizeof(ExplainState));
es = (ExplainState *) malloc(sizeof(ExplainState));
memset(es, 0, sizeof(ExplainState));
es->printCost = true; /* default */
@ -78,11 +82,13 @@ ExplainQuery(Query *query, bool verbose, CommandDest dest)
if (es->printNodes)
s = nodeToString(plan);
if (es->printCost) {
if (es->printCost)
{
s2 = Explain_PlanToString(plan, es);
if (s == NULL)
s = s2;
else {
else
{
strcat(s, "\n\n");
strcat(s, s2);
}
@ -90,12 +96,13 @@ ExplainQuery(Query *query, bool verbose, CommandDest dest)
/* output the plan */
len = strlen(s);
elog(NOTICE, "QUERY PLAN:\n\n%.*s", ELOG_MAXLEN-64, s);
len -= ELOG_MAXLEN-64;
while (len > 0) {
s += ELOG_MAXLEN-64;
elog(NOTICE, "%.*s", ELOG_MAXLEN-64, s);
len -= ELOG_MAXLEN-64;
elog(NOTICE, "QUERY PLAN:\n\n%.*s", ELOG_MAXLEN - 64, s);
len -= ELOG_MAXLEN - 64;
while (len > 0)
{
s += ELOG_MAXLEN - 64;
elog(NOTICE, "%.*s", ELOG_MAXLEN - 64, s);
len -= ELOG_MAXLEN - 64;
}
free(es);
}
@ -109,18 +116,20 @@ ExplainQuery(Query *query, bool verbose, CommandDest dest)
* converts a Node into ascii string and append it to 'str'
*/
static void
explain_outNode(StringInfo str, Plan *plan, int indent, ExplainState *es)
explain_outNode(StringInfo str, Plan * plan, int indent, ExplainState * es)
{
char *pname;
char buf[1000];
int i;
if (plan==NULL) {
if (plan == NULL)
{
appendStringInfo(str, "\n");
return;
}
switch(nodeTag(plan)) {
switch (nodeTag(plan))
{
case T_Result:
pname = "Result";
break;
@ -168,15 +177,18 @@ explain_outNode(StringInfo str, Plan *plan, int indent, ExplainState *es)
break;
}
for(i=0; i < indent; i++)
for (i = 0; i < indent; i++)
appendStringInfo(str, " ");
appendStringInfo(str, pname);
switch(nodeTag(plan)) {
switch (nodeTag(plan))
{
case T_SeqScan:
case T_IndexScan:
if (((Scan*)plan)->scanrelid > 0) {
RangeTblEntry *rte = nth(((Scan*)plan)->scanrelid-1, es->rtable);
if (((Scan *) plan)->scanrelid > 0)
{
RangeTblEntry *rte = nth(((Scan *) plan)->scanrelid - 1, es->rtable);
sprintf(buf, " on %s", rte->refname);
appendStringInfo(str, buf);
}
@ -184,7 +196,8 @@ explain_outNode(StringInfo str, Plan *plan, int indent, ExplainState *es)
default:
break;
}
if (es->printCost) {
if (es->printCost)
{
sprintf(buf, " (cost=%.2f size=%d width=%d)",
plan->cost, plan->plan_size, plan->plan_width);
appendStringInfo(str, buf);
@ -192,32 +205,34 @@ explain_outNode(StringInfo str, Plan *plan, int indent, ExplainState *es)
appendStringInfo(str, "\n");
/* lefttree */
if (outerPlan(plan)) {
for(i=0; i < indent; i++)
if (outerPlan(plan))
{
for (i = 0; i < indent; i++)
appendStringInfo(str, " ");
appendStringInfo(str, " -> ");
explain_outNode(str, outerPlan(plan), indent+1, es);
explain_outNode(str, outerPlan(plan), indent + 1, es);
}
/* righttree */
if (innerPlan(plan)) {
for(i=0; i < indent; i++)
if (innerPlan(plan))
{
for (i = 0; i < indent; i++)
appendStringInfo(str, " ");
appendStringInfo(str, " -> ");
explain_outNode(str, innerPlan(plan), indent+1, es);
explain_outNode(str, innerPlan(plan), indent + 1, es);
}
return;
}
static char *
Explain_PlanToString(Plan *plan, ExplainState *es)
Explain_PlanToString(Plan * plan, ExplainState * es)
{
StringInfo str;
char *s;
if (plan==NULL)
if (plan == NULL)
return "";
Assert(plan!=NULL);
Assert(plan != NULL);
str = makeStringInfo();
explain_outNode(str, plan, 0, es);
s = str->data;

View File

@ -7,7 +7,7 @@
*
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/commands/Attic/purge.c,v 1.6 1997/08/12 22:52:25 momjian Exp $
* $Header: /cvsroot/pgsql/src/backend/commands/Attic/purge.c,v 1.7 1997/09/07 04:40:51 momjian Exp $
*
* Note:
* XXX There are many instances of int32 instead of ...Time. These
@ -45,10 +45,11 @@ RelationPurge(char *relationName,
Relation relation;
HeapScanDesc scan;
static ScanKeyData key[1] = {
{ 0, Anum_pg_class_relname, F_NAMEEQ }
{0, Anum_pg_class_relname, F_NAMEEQ}
};
Buffer buffer;
HeapTuple newTuple, oldTuple;
HeapTuple newTuple,
oldTuple;
AbsoluteTime currentTime;
char *values[Natts_pg_class];
char nulls[Natts_pg_class];
@ -56,23 +57,26 @@ RelationPurge(char *relationName,
Relation idescs[Num_pg_class_indices];
/*
* XXX for some reason getmyrelids (in inval.c) barfs when
* you heap_replace tuples from these classes. i thought
* setheapoverride would fix it but it didn't. for now,
* just disallow purge on these classes.
* XXX for some reason getmyrelids (in inval.c) barfs when you
* heap_replace tuples from these classes. i thought setheapoverride
* would fix it but it didn't. for now, just disallow purge on these
* classes.
*/
if (strcmp(RelationRelationName, relationName) == 0 ||
strcmp(AttributeRelationName, relationName) == 0 ||
strcmp(AccessMethodRelationName, relationName) == 0 ||
strcmp(AccessMethodOperatorRelationName, relationName) == 0) {
strcmp(AccessMethodOperatorRelationName, relationName) == 0)
{
elog(WARN, "%s: cannot purge catalog \"%s\"",
cmdname, relationName);
}
if (PointerIsValid(absoluteTimeString)) {
if (PointerIsValid(absoluteTimeString))
{
absoluteTime = (int32) nabstimein(absoluteTimeString);
absoluteTimeString[0] = '\0';
if (absoluteTime == INVALID_ABSTIME) {
if (absoluteTime == INVALID_ABSTIME)
{
elog(NOTICE, "%s: bad absolute time string \"%s\"",
cmdname, absoluteTimeString);
elog(WARN, "purge not executed");
@ -84,8 +88,10 @@ RelationPurge(char *relationName,
cmdname, absoluteTimeString, absoluteTime);
#endif /* defined(PURGEDEBUG) */
if (PointerIsValid(relativeTimeString)) {
if (isreltime(relativeTimeString) != 1) {
if (PointerIsValid(relativeTimeString))
{
if (isreltime(relativeTimeString) != 1)
{
elog(WARN, "%s: bad relative time string \"%s\"",
cmdname, relativeTimeString);
}
@ -106,46 +112,52 @@ RelationPurge(char *relationName,
scan = heap_beginscan(relation, 0, NowTimeQual, 1, key);
oldTuple = heap_getnext(scan, 0, &buffer);
if (!HeapTupleIsValid(oldTuple)) {
if (!HeapTupleIsValid(oldTuple))
{
heap_endscan(scan);
heap_close(relation);
elog(WARN, "%s: no such relation: %s", cmdname, relationName);
return(0);
return (0);
}
/*
* Dig around in the tuple.
*/
currentTime = GetCurrentTransactionStartTime();
if (!RelativeTimeIsValid(relativeTime)) {
if (!RelativeTimeIsValid(relativeTime))
{
dateTag = ABSOLUTE;
if (!AbsoluteTimeIsValid(absoluteTime))
absoluteTime = currentTime;
} else if (!AbsoluteTimeIsValid(absoluteTime))
}
else if (!AbsoluteTimeIsValid(absoluteTime))
dateTag = RELATIVE;
else
dateTag = ABSOLUTE | RELATIVE;
for (i = 0; i < Natts_pg_class; ++i) {
nulls[i] = heap_attisnull(oldTuple, i+1) ? 'n' : ' ';
for (i = 0; i < Natts_pg_class; ++i)
{
nulls[i] = heap_attisnull(oldTuple, i + 1) ? 'n' : ' ';
values[i] = NULL;
replace[i] = ' ';
}
if (dateTag & ABSOLUTE) {
values[Anum_pg_class_relexpires-1] =
if (dateTag & ABSOLUTE)
{
values[Anum_pg_class_relexpires - 1] =
(char *) UInt32GetDatum(absoluteTime);
replace[Anum_pg_class_relexpires-1] = 'r';
replace[Anum_pg_class_relexpires - 1] = 'r';
}
if (dateTag & RELATIVE) {
values[Anum_pg_class_relpreserved-1] =
if (dateTag & RELATIVE)
{
values[Anum_pg_class_relpreserved - 1] =
(char *) UInt32GetDatum(relativeTime);
replace[Anum_pg_class_relpreserved-1] = 'r';
replace[Anum_pg_class_relpreserved - 1] = 'r';
}
/*
* Change the RELATION relation tuple for the given relation.
*/
newTuple = heap_modifytuple(oldTuple, buffer, relation, (Datum*)values,
newTuple = heap_modifytuple(oldTuple, buffer, relation, (Datum *) values,
nulls, replace);
/* XXX How do you detect an insertion error?? */
@ -160,6 +172,5 @@ RelationPurge(char *relationName,
heap_endscan(scan);
heap_close(relation);
return(1);
return (1);
}

File diff suppressed because it is too large Load Diff

View File

@ -7,7 +7,7 @@
*
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/commands/Attic/remove.c,v 1.10 1997/08/18 20:52:17 momjian Exp $
* $Header: /cvsroot/pgsql/src/backend/commands/Attic/remove.c,v 1.11 1997/09/07 04:40:54 momjian Exp $
*
*-------------------------------------------------------------------------
*/
@ -28,9 +28,9 @@
#include <storage/bufmgr.h>
#include <fmgr.h>
#ifndef HAVE_MEMMOVE
# include <regex/utils.h>
#include <regex/utils.h>
#else
# include <string.h>
#include <string.h>
#endif
/*
@ -59,17 +59,21 @@ RemoveOperator(char *operatorName, /* operator name */
ScanKeyData operatorKey[3];
char *userName;
if (typeName1) {
if (typeName1)
{
typeId1 = TypeGet(typeName1, &defined);
if (!OidIsValid(typeId1)) {
if (!OidIsValid(typeId1))
{
elog(WARN, "RemoveOperator: type '%s' does not exist", typeName1);
return;
}
}
if (typeName2) {
if (typeName2)
{
typeId2 = TypeGet(typeName2, &defined);
if (!OidIsValid(typeId2)) {
if (!OidIsValid(typeId2))
{
elog(WARN, "RemoveOperator: type '%s' does not exist", typeName2);
return;
}
@ -93,7 +97,8 @@ RemoveOperator(char *operatorName, /* operator name */
relation = heap_openr(OperatorRelationName);
scan = heap_beginscan(relation, 0, NowTimeQual, 3, operatorKey);
tup = heap_getnext(scan, 0, &buffer);
if (HeapTupleIsValid(tup)) {
if (HeapTupleIsValid(tup))
{
#ifndef NO_SECURITY
userName = GetPgUserName();
if (!pg_ownercheck(userName,
@ -104,17 +109,24 @@ RemoveOperator(char *operatorName, /* operator name */
#endif
ItemPointerCopy(&tup->t_ctid, &itemPointerData);
heap_delete(relation, &itemPointerData);
} else {
if (OidIsValid(typeId1) && OidIsValid(typeId2)) {
}
else
{
if (OidIsValid(typeId1) && OidIsValid(typeId2))
{
elog(WARN, "RemoveOperator: binary operator '%s' taking '%s' and '%s' does not exist",
operatorName,
typeName1,
typeName2);
} else if (OidIsValid(typeId1)) {
}
else if (OidIsValid(typeId1))
{
elog(WARN, "RemoveOperator: right unary operator '%s' taking '%s' does not exist",
operatorName,
typeName1);
} else {
}
else
{
elog(WARN, "RemoveOperator: left unary operator '%s' taking '%s' does not exist",
operatorName,
typeName2);
@ -142,16 +154,18 @@ SingleOpOperatorRemove(Oid typeOid)
HeapTuple tup;
ItemPointerData itemPointerData;
Buffer buffer;
static attnums[3] = { 7, 8, 9 }; /* left, right, return */
static attnums[3] = {7, 8, 9}; /* left, right, return */
register i;
ScanKeyEntryInitialize(&key[0],
0, 0, ObjectIdEqualRegProcedure, (Datum)typeOid);
0, 0, ObjectIdEqualRegProcedure, (Datum) typeOid);
rdesc = heap_openr(OperatorRelationName);
for (i = 0; i < 3; ++i) {
for (i = 0; i < 3; ++i)
{
key[0].sk_attno = attnums[i];
sdesc = heap_beginscan(rdesc, 0, NowTimeQual, 1, key);
while (PointerIsValid(tup = heap_getnext(sdesc, 0, &buffer))) {
while (PointerIsValid(tup = heap_getnext(sdesc, 0, &buffer)))
{
ItemPointerCopy(&tup->t_ctid, &itemPointerData);
/* XXX LOCK not being passed */
heap_delete(rdesc, &itemPointerData);
@ -170,11 +184,13 @@ SingleOpOperatorRemove(Oid typeOid)
static void
AttributeAndRelationRemove(Oid typeOid)
{
struct oidlist {
struct oidlist
{
Oid reloid;
struct oidlist *next;
};
struct oidlist *oidptr, *optr;
struct oidlist *oidptr,
*optr;
Relation rdesc;
ScanKeyData key[1];
HeapScanDesc sdesc;
@ -183,24 +199,24 @@ AttributeAndRelationRemove(Oid typeOid)
Buffer buffer;
/*
* Get the oid's of the relations to be removed by scanning the
* entire attribute relation.
* We don't need to remove the attributes here,
* because amdestroy will remove all attributes of the relation.
* XXX should check for duplicate relations
* Get the oid's of the relations to be removed by scanning the entire
* attribute relation. We don't need to remove the attributes here,
* because amdestroy will remove all attributes of the relation. XXX
* should check for duplicate relations
*/
ScanKeyEntryInitialize(&key[0],
0, 3, ObjectIdEqualRegProcedure, (Datum)typeOid);
0, 3, ObjectIdEqualRegProcedure, (Datum) typeOid);
oidptr = (struct oidlist *) palloc(sizeof(*oidptr));
oidptr->next = NULL;
optr = oidptr;
rdesc = heap_openr(AttributeRelationName);
sdesc = heap_beginscan(rdesc, 0, NowTimeQual, 1, key);
while (PointerIsValid(tup = heap_getnext(sdesc, 0, &buffer))) {
while (PointerIsValid(tup = heap_getnext(sdesc, 0, &buffer)))
{
ItemPointerCopy(&tup->t_ctid, &itemPointerData);
optr->reloid = ((AttributeTupleForm)GETSTRUCT(tup))->attrelid;
optr->reloid = ((AttributeTupleForm) GETSTRUCT(tup))->attrelid;
optr->next = (struct oidlist *) palloc(sizeof(*oidptr));
optr = optr->next;
}
@ -211,23 +227,26 @@ AttributeAndRelationRemove(Oid typeOid)
ScanKeyEntryInitialize(&key[0], 0,
ObjectIdAttributeNumber,
ObjectIdEqualRegProcedure, (Datum)0);
ObjectIdEqualRegProcedure, (Datum) 0);
optr = oidptr;
rdesc = heap_openr(RelationRelationName);
while (PointerIsValid((char *) optr->next)) {
while (PointerIsValid((char *) optr->next))
{
key[0].sk_argument = (Datum) (optr++)->reloid;
sdesc = heap_beginscan(rdesc, 0, NowTimeQual, 1, key);
tup = heap_getnext(sdesc, 0, &buffer);
if (PointerIsValid(tup)) {
if (PointerIsValid(tup))
{
char *name;
name = (((Form_pg_class)GETSTRUCT(tup))->relname).data;
name = (((Form_pg_class) GETSTRUCT(tup))->relname).data;
heap_destroy(name);
}
}
heap_endscan(sdesc);
heap_close(rdesc);
}
#endif /* NOTYET */
/*
@ -244,7 +263,7 @@ RemoveType(char *typeName) /* type name to be removed */
Oid typeOid;
ItemPointerData itemPointerData;
static ScanKeyData typeKey[1] = {
{ 0, Anum_pg_type_typname, NameEqualRegProcedure }
{0, Anum_pg_type_typname, NameEqualRegProcedure}
};
char *shadow_type;
char *userName;
@ -266,7 +285,8 @@ RemoveType(char *typeName) /* type name to be removed */
scan = heap_beginscan(relation, 0, NowTimeQual, 1, typeKey);
tup = heap_getnext(scan, 0, (Buffer *) 0);
if (!HeapTupleIsValid(tup)) {
if (!HeapTupleIsValid(tup))
{
heap_endscan(scan);
heap_close(relation);
elog(WARN, "RemoveType: type '%s' does not exist",
@ -310,7 +330,7 @@ RemoveType(char *typeName) /* type name to be removed */
void
RemoveFunction(char *functionName, /* function name to be removed */
int nargs,
List *argNameList /* list of TypeNames */)
List * argNameList /* list of TypeNames */ )
{
Relation relation;
HeapScanDesc scan;
@ -321,26 +341,29 @@ RemoveFunction(char *functionName, /* function name to be removed */
Form_pg_proc the_proc = NULL;
ItemPointerData itemPointerData;
static ScanKeyData key[3] = {
{ 0, Anum_pg_proc_proname, NameEqualRegProcedure }
{0, Anum_pg_proc_proname, NameEqualRegProcedure}
};
char *userName;
char *typename;
int i;
memset(argList, 0, 8 * sizeof(Oid));
for (i=0; i<nargs; i++) {
for (i = 0; i < nargs; i++)
{
/* typename = ((TypeName*)(lfirst(argNameList)))->name; */
typename = strVal(lfirst(argNameList));
argNameList = lnext(argNameList);
if (strcmp(typename, "opaque") == 0)
argList[i] = 0;
else {
else
{
tup = SearchSysCacheTuple(TYPNAME, PointerGetDatum(typename),
0,0,0);
0, 0, 0);
if (!HeapTupleIsValid(tup)) {
elog(WARN, "RemoveFunction: type '%s' not found",typename);
if (!HeapTupleIsValid(tup))
{
elog(WARN, "RemoveFunction: type '%s' not found", typename);
}
argList[i] = tup->t_oid;
}
@ -348,13 +371,14 @@ RemoveFunction(char *functionName, /* function name to be removed */
tup = SearchSysCacheTuple(PRONAME, PointerGetDatum(functionName),
Int32GetDatum(nargs),
PointerGetDatum(argList),0);
PointerGetDatum(argList), 0);
if (!HeapTupleIsValid(tup))
func_error("RemoveFunction", functionName, nargs, argList);
#ifndef NO_SECURITY
userName = GetPgUserName();
if (!pg_func_ownercheck(userName, functionName, nargs, argList)) {
if (!pg_func_ownercheck(userName, functionName, nargs, argList))
{
elog(WARN, "RemoveFunction: function '%s': permission denied",
functionName);
}
@ -367,17 +391,19 @@ RemoveFunction(char *functionName, /* function name to be removed */
relation = heap_openr(ProcedureRelationName);
scan = heap_beginscan(relation, 0, NowTimeQual, 1, key);
do { /* hope this is ok because it's indexed */
if (bufferUsed) {
do
{ /* hope this is ok because it's indexed */
if (bufferUsed)
{
ReleaseBuffer(buffer);
bufferUsed = FALSE;
}
tup = heap_getnext(scan, 0, (Buffer *) &buffer);
tup = heap_getnext(scan, 0, (Buffer *) & buffer);
if (!HeapTupleIsValid(tup))
break;
bufferUsed = TRUE;
the_proc = (Form_pg_proc) GETSTRUCT(tup);
} while ( (namestrcmp(&(the_proc->proname), functionName) == 0) &&
} while ((namestrcmp(&(the_proc->proname), functionName) == 0) &&
(the_proc->pronargs != nargs ||
!oid8eq(&(the_proc->proargtypes[0]), &argList[0])));
@ -387,7 +413,7 @@ RemoveFunction(char *functionName, /* function name to be removed */
{
heap_endscan(scan);
heap_close(relation);
func_error("RemoveFunction", functionName,nargs, argList);
func_error("RemoveFunction", functionName, nargs, argList);
}
/* ok, function has been found */
@ -416,21 +442,25 @@ RemoveAggregate(char *aggName, char *aggType)
/*
* if a basetype is passed in, then attempt to find an aggregate for that
* specific type.
* if a basetype is passed in, then attempt to find an aggregate for
* that specific type.
*
* else if the basetype is blank, then attempt to find an aggregate with a
* basetype of zero. This is valid. It means that the aggregate is to apply
* to all basetypes. ie, a counter of some sort.
* else if the basetype is blank, then attempt to find an aggregate with
* a basetype of zero. This is valid. It means that the aggregate is
* to apply to all basetypes. ie, a counter of some sort.
*
*/
if (aggType) {
if (aggType)
{
basetypeID = TypeGet(aggType, &defined);
if (!OidIsValid(basetypeID)) {
if (!OidIsValid(basetypeID))
{
elog(WARN, "RemoveAggregate: type '%s' does not exist", aggType);
}
} else {
}
else
{
basetypeID = 0;
}
@ -438,11 +468,15 @@ RemoveAggregate(char *aggName, char *aggType)
#ifndef NO_SECURITY
*/
userName = GetPgUserName();
if (!pg_aggr_ownercheck(userName, aggName, basetypeID)) {
if (aggType) {
if (!pg_aggr_ownercheck(userName, aggName, basetypeID))
{
if (aggType)
{
elog(WARN, "RemoveAggregate: aggregate '%s' on type '%s': permission denied",
aggName, aggType);
} else {
}
else
{
elog(WARN, "RemoveAggregate: aggregate '%s': permission denied",
aggName);
}
@ -464,13 +498,17 @@ RemoveAggregate(char *aggName, char *aggType)
relation = heap_openr(AggregateRelationName);
scan = heap_beginscan(relation, 0, NowTimeQual, 2, aggregateKey);
tup = heap_getnext(scan, 0, (Buffer *) 0);
if (!HeapTupleIsValid(tup)) {
if (!HeapTupleIsValid(tup))
{
heap_endscan(scan);
heap_close(relation);
if (aggType) {
if (aggType)
{
elog(WARN, "RemoveAggregate: aggregate '%s' for '%s' does not exist",
aggName, aggType);
} else {
}
else
{
elog(WARN, "RemoveAggregate: aggregate '%s' for all types does not exist",
aggName);
}

View File

@ -7,7 +7,7 @@
*
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/commands/Attic/rename.c,v 1.7 1997/08/18 20:52:18 momjian Exp $
* $Header: /cvsroot/pgsql/src/backend/commands/Attic/rename.c,v 1.8 1997/09/07 04:40:55 momjian Exp $
*
*-------------------------------------------------------------------------
*/
@ -34,12 +34,12 @@
#include <optimizer/internal.h>
#include <optimizer/prep.h> /* for find_all_inheritors */
#ifndef NO_SECURITY
# include <utils/acl.h>
#include <utils/acl.h>
#endif /* !NO_SECURITY */
#ifndef HAVE_MEMMOVE
# include <regex/utils.h>
#include <regex/utils.h>
#else
# include <string.h>
#include <string.h>
#endif
/*
@ -66,8 +66,11 @@ renameatt(char *relname,
char *userName,
int recurse)
{
Relation relrdesc, attrdesc;
HeapTuple reltup, oldatttup, newatttup;
Relation relrdesc,
attrdesc;
HeapTuple reltup,
oldatttup,
newatttup;
ItemPointerData oldTID;
Relation idescs[Num_pg_attr_indices];
@ -89,19 +92,23 @@ renameatt(char *relname,
/*
* if the 'recurse' flag is set then we are supposed to rename this
* attribute in all classes that inherit from 'relname' (as well as
* in 'relname').
* attribute in all classes that inherit from 'relname' (as well as in
* 'relname').
*
* any permissions or problems with duplicate attributes will cause
* the whole transaction to abort, which is what we want -- all or
* any permissions or problems with duplicate attributes will cause the
* whole transaction to abort, which is what we want -- all or
* nothing.
*/
if (recurse) {
Oid myrelid, childrelid;
List *child, *children;
if (recurse)
{
Oid myrelid,
childrelid;
List *child,
*children;
relrdesc = heap_openr(relname);
if (!RelationIsValid(relrdesc)) {
if (!RelationIsValid(relrdesc))
{
elog(WARN, "renameatt: unknown relation: \"%s\"",
relname);
}
@ -114,17 +121,19 @@ renameatt(char *relname,
/*
* find_all_inheritors does the recursive search of the
* inheritance hierarchy, so all we have to do is process
* all of the relids in the list that it returns.
* inheritance hierarchy, so all we have to do is process all of
* the relids in the list that it returns.
*/
foreach (child, children) {
foreach(child, children)
{
char *childname;
childrelid = lfirsti(child);
if (childrelid == myrelid)
continue;
relrdesc = heap_open(childrelid);
if (!RelationIsValid(relrdesc)) {
if (!RelationIsValid(relrdesc))
{
elog(WARN, "renameatt: can't find catalog entry for inheriting class with oid %d",
childrelid);
}
@ -137,7 +146,8 @@ renameatt(char *relname,
relrdesc = heap_openr(RelationRelationName);
reltup = ClassNameIndexScan(relrdesc, relname);
if (!PointerIsValid(reltup)) {
if (!PointerIsValid(reltup))
{
heap_close(relrdesc);
elog(WARN, "renameatt: relation \"%s\" nonexistent",
relname);
@ -147,25 +157,28 @@ renameatt(char *relname,
attrdesc = heap_openr(AttributeRelationName);
oldatttup = AttributeNameIndexScan(attrdesc, reltup->t_oid, oldattname);
if (!PointerIsValid(oldatttup)) {
if (!PointerIsValid(oldatttup))
{
heap_close(attrdesc);
elog(WARN, "renameatt: attribute \"%s\" nonexistent",
oldattname);
}
if (((AttributeTupleForm ) GETSTRUCT(oldatttup))->attnum < 0) {
if (((AttributeTupleForm) GETSTRUCT(oldatttup))->attnum < 0)
{
elog(WARN, "renameatt: system attribute \"%s\" not renamed",
oldattname);
}
newatttup = AttributeNameIndexScan(attrdesc, reltup->t_oid, newattname);
if (PointerIsValid(newatttup)) {
if (PointerIsValid(newatttup))
{
pfree(oldatttup);
heap_close(attrdesc);
elog(WARN, "renameatt: attribute \"%s\" exists",
newattname);
}
namestrcpy(&(((AttributeTupleForm)(GETSTRUCT(oldatttup)))->attname),
namestrcpy(&(((AttributeTupleForm) (GETSTRUCT(oldatttup)))->attname),
newattname);
oldTID = oldatttup->t_ctid;
@ -201,17 +214,21 @@ void
renamerel(char oldrelname[], char newrelname[])
{
Relation relrdesc; /* for RELATION relation */
HeapTuple oldreltup, newreltup;
HeapTuple oldreltup,
newreltup;
ItemPointerData oldTID;
char oldpath[MAXPGPATH], newpath[MAXPGPATH];
char oldpath[MAXPGPATH],
newpath[MAXPGPATH];
Relation idescs[Num_pg_class_indices];
if (IsSystemRelationName(oldrelname)) {
if (IsSystemRelationName(oldrelname))
{
elog(WARN, "renamerel: system relation \"%s\" not renamed",
oldrelname);
return;
}
if (IsSystemRelationName(newrelname)) {
if (IsSystemRelationName(newrelname))
{
elog(WARN, "renamerel: Illegal class name: \"%s\" -- pg_ is reserved for system catalogs",
newrelname);
return;
@ -220,14 +237,16 @@ renamerel(char oldrelname[], char newrelname[])
relrdesc = heap_openr(RelationRelationName);
oldreltup = ClassNameIndexScan(relrdesc, oldrelname);
if (!PointerIsValid(oldreltup)) {
if (!PointerIsValid(oldreltup))
{
heap_close(relrdesc);
elog(WARN, "renamerel: relation \"%s\" does not exist",
oldrelname);
}
newreltup = ClassNameIndexScan(relrdesc, newrelname);
if (PointerIsValid(newreltup)) {
if (PointerIsValid(newreltup))
{
pfree(oldreltup);
heap_close(relrdesc);
elog(WARN, "renamerel: relation \"%s\" exists",

View File

@ -26,7 +26,8 @@
bool ItsSequenceCreation = false;
typedef struct FormData_pg_sequence {
typedef struct FormData_pg_sequence
{
NameData sequence_name;
int4 last_value;
int4 increment_by;
@ -39,11 +40,13 @@ typedef struct FormData_pg_sequence {
typedef FormData_pg_sequence *SequenceTupleForm;
typedef struct sequence_magic {
typedef struct sequence_magic
{
uint32 magic;
} sequence_magic;
typedef struct SeqTableData {
typedef struct SeqTableData
{
char *name;
Oid relid;
Relation rel;
@ -57,20 +60,20 @@ typedef SeqTableData *SeqTable;
static SeqTable seqtab = NULL;
static SeqTable init_sequence (char *caller, char *name);
static SequenceTupleForm read_info (char * caller, SeqTable elm, Buffer * buf);
static void init_params (CreateSeqStmt *seq, SequenceTupleForm new);
static int get_param (DefElem *def);
static SeqTable init_sequence(char *caller, char *name);
static SequenceTupleForm read_info(char *caller, SeqTable elm, Buffer * buf);
static void init_params(CreateSeqStmt * seq, SequenceTupleForm new);
static int get_param(DefElem * def);
/*
* DefineSequence --
* Creates a new sequence relation
*/
void
DefineSequence (CreateSeqStmt *seq)
DefineSequence(CreateSeqStmt * seq)
{
FormData_pg_sequence new;
CreateStmt *stmt = makeNode (CreateStmt);
CreateStmt *stmt = makeNode(CreateStmt);
ColumnDef *coldef;
TypeName *typnam;
Relation rel;
@ -84,7 +87,7 @@ DefineSequence (CreateSeqStmt *seq)
int i;
/* Check and set values */
init_params (seq, &new);
init_params(seq, &new);
/*
* Create relation (and fill null[] & value[])
@ -99,52 +102,52 @@ DefineSequence (CreateSeqStmt *seq)
coldef->typename = typnam;
coldef->defval = NULL;
coldef->is_not_null = false;
null[i-1] = ' ';
null[i - 1] = ' ';
switch (i)
{
case SEQ_COL_NAME:
typnam->name = "name";
coldef->colname = "sequence_name";
value[i-1] = PointerGetDatum (seq->seqname);
value[i - 1] = PointerGetDatum(seq->seqname);
break;
case SEQ_COL_LASTVAL:
typnam->name = "int4";
coldef->colname = "last_value";
value[i-1] = Int32GetDatum (new.last_value);
value[i - 1] = Int32GetDatum(new.last_value);
break;
case SEQ_COL_INCBY:
typnam->name = "int4";
coldef->colname = "increment_by";
value[i-1] = Int32GetDatum (new.increment_by);
value[i - 1] = Int32GetDatum(new.increment_by);
break;
case SEQ_COL_MAXVALUE:
typnam->name = "int4";
coldef->colname = "max_value";
value[i-1] = Int32GetDatum (new.max_value);
value[i - 1] = Int32GetDatum(new.max_value);
break;
case SEQ_COL_MINVALUE:
typnam->name = "int4";
coldef->colname = "min_value";
value[i-1] = Int32GetDatum (new.min_value);
value[i - 1] = Int32GetDatum(new.min_value);
break;
case SEQ_COL_CACHE:
typnam->name = "int4";
coldef->colname = "cache_value";
value[i-1] = Int32GetDatum (new.cache_value);
value[i - 1] = Int32GetDatum(new.cache_value);
break;
case SEQ_COL_CYCLE:
typnam->name = "char";
coldef->colname = "is_cycled";
value[i-1] = CharGetDatum (new.is_cycled);
value[i - 1] = CharGetDatum(new.is_cycled);
break;
case SEQ_COL_CALLED:
typnam->name = "char";
coldef->colname = "is_called";
value[i-1] = CharGetDatum ('f');
value[i - 1] = CharGetDatum('f');
break;
}
stmt->tableElts = lappend (stmt->tableElts, coldef);
stmt->tableElts = lappend(stmt->tableElts, coldef);
}
stmt->relname = seq->seqname;
@ -155,39 +158,42 @@ DefineSequence (CreateSeqStmt *seq)
ItsSequenceCreation = true; /* hack */
DefineRelation (stmt);
DefineRelation(stmt);
/* Xact abort calls CloseSequences, which turns ItsSequenceCreation off */
ItsSequenceCreation = false; /* hack */
/*
* Xact abort calls CloseSequences, which turns ItsSequenceCreation
* off
*/
ItsSequenceCreation = false;/* hack */
rel = heap_openr (seq->seqname);
Assert ( RelationIsValid (rel) );
rel = heap_openr(seq->seqname);
Assert(RelationIsValid(rel));
RelationSetLockForWrite (rel);
RelationSetLockForWrite(rel);
tupDesc = RelationGetTupleDescriptor(rel);
Assert ( RelationGetNumberOfBlocks (rel) == 0 );
buf = ReadBuffer (rel, P_NEW);
Assert(RelationGetNumberOfBlocks(rel) == 0);
buf = ReadBuffer(rel, P_NEW);
if ( !BufferIsValid (buf) )
elog (WARN, "DefineSequence: ReadBuffer failed");
if (!BufferIsValid(buf))
elog(WARN, "DefineSequence: ReadBuffer failed");
page = (PageHeader) BufferGetPage (buf);
page = (PageHeader) BufferGetPage(buf);
PageInit((Page)page, BufferGetPageSize(buf), sizeof(sequence_magic));
sm = (sequence_magic *) PageGetSpecialPointer (page);
PageInit((Page) page, BufferGetPageSize(buf), sizeof(sequence_magic));
sm = (sequence_magic *) PageGetSpecialPointer(page);
sm->magic = SEQ_MAGIC;
/* Now - form & insert sequence tuple */
tuple = heap_formtuple (tupDesc, value, null);
heap_insert (rel, tuple);
tuple = heap_formtuple(tupDesc, value, null);
heap_insert(rel, tuple);
if ( WriteBuffer (buf) == STATUS_ERROR )
elog (WARN, "DefineSequence: WriteBuffer failed");
if (WriteBuffer(buf) == STATUS_ERROR)
elog(WARN, "DefineSequence: WriteBuffer failed");
RelationUnsetLockForWrite (rel);
heap_close (rel);
RelationUnsetLockForWrite(rel);
heap_close(rel);
return;
@ -195,27 +201,33 @@ DefineSequence (CreateSeqStmt *seq)
int4
nextval (struct varlena * seqin)
nextval(struct varlena * seqin)
{
char *seqname = textout(seqin);
SeqTable elm;
Buffer buf;
SequenceTupleForm seq;
ItemPointerData iptr;
int4 incby, maxv, minv, cache;
int4 result, next, rescnt = 0;
int4 incby,
maxv,
minv,
cache;
int4 result,
next,
rescnt = 0;
/* open and WIntentLock sequence */
elm = init_sequence ("nextval", seqname);
pfree (seqname);
elm = init_sequence("nextval", seqname);
pfree(seqname);
if ( elm->last != elm->cached ) /* some numbers were cached */
if (elm->last != elm->cached) /* some numbers were cached */
{
elm->last += elm->increment;
return (elm->last);
}
seq = read_info ("nextval", elm, &buf); /* lock page and read tuple */
seq = read_info("nextval", elm, &buf); /* lock page and read
* tuple */
next = result = seq->last_value;
incby = seq->increment_by;
@ -223,39 +235,41 @@ nextval (struct varlena * seqin)
minv = seq->min_value;
cache = seq->cache_value;
if ( seq->is_called != 't' )
if (seq->is_called != 't')
rescnt++; /* last_value if not called */
while ( rescnt < cache ) /* try to fetch cache numbers */
while (rescnt < cache) /* try to fetch cache numbers */
{
/*
* Check MAXVALUE for ascending sequences
* and MINVALUE for descending sequences
* Check MAXVALUE for ascending sequences and MINVALUE for
* descending sequences
*/
if ( incby > 0 ) /* ascending sequence */
if (incby > 0) /* ascending sequence */
{
if ( ( maxv >= 0 && next > maxv - incby) ||
( maxv < 0 && next + incby > maxv ) )
if ((maxv >= 0 && next > maxv - incby) ||
(maxv < 0 && next + incby > maxv))
{
if ( rescnt > 0 )
if (rescnt > 0)
break; /* stop caching */
if ( seq->is_cycled != 't' )
elog (WARN, "%s.nextval: got MAXVALUE (%d)",
if (seq->is_cycled != 't')
elog(WARN, "%s.nextval: got MAXVALUE (%d)",
elm->name, maxv);
next = minv;
}
else
next += incby;
}
else /* descending sequence */
else
/* descending sequence */
{
if ( ( minv < 0 && next < minv - incby ) ||
( minv >= 0 && next + incby < minv ) )
if ((minv < 0 && next < minv - incby) ||
(minv >= 0 && next + incby < minv))
{
if ( rescnt > 0 )
if (rescnt > 0)
break; /* stop caching */
if ( seq->is_cycled != 't' )
elog (WARN, "%s.nextval: got MINVALUE (%d)",
if (seq->is_cycled != 't')
elog(WARN, "%s.nextval: got MINVALUE (%d)",
elm->name, minv);
next = maxv;
}
@ -263,7 +277,7 @@ nextval (struct varlena * seqin)
next += incby;
}
rescnt++; /* got result */
if ( rescnt == 1 ) /* if it's first one - */
if (rescnt == 1) /* if it's first one - */
result = next; /* it's what to return */
}
@ -275,11 +289,11 @@ nextval (struct varlena * seqin)
seq->last_value = next; /* last fetched number */
seq->is_called = 't';
if ( WriteBuffer (buf) == STATUS_ERROR )
elog (WARN, "%s.nextval: WriteBuffer failed", elm->name);
if (WriteBuffer(buf) == STATUS_ERROR)
elog(WARN, "%s.nextval: WriteBuffer failed", elm->name);
ItemPointerSet(&iptr, 0, FirstOffsetNumber);
RelationUnsetSingleWLockPage (elm->rel, &iptr);
RelationUnsetSingleWLockPage(elm->rel, &iptr);
return (result);
@ -287,19 +301,19 @@ nextval (struct varlena * seqin)
int4
currval (struct varlena * seqin)
currval(struct varlena * seqin)
{
char *seqname = textout(seqin);
SeqTable elm;
int4 result;
/* open and WIntentLock sequence */
elm = init_sequence ("currval", seqname);
pfree (seqname);
elm = init_sequence("currval", seqname);
pfree(seqname);
if ( elm->increment == 0 ) /* nextval/read_info were not called */
if (elm->increment == 0) /* nextval/read_info were not called */
{
elog (WARN, "%s.currval is not yet defined in this session", elm->name);
elog(WARN, "%s.currval is not yet defined in this session", elm->name);
}
result = elm->last;
@ -309,7 +323,7 @@ currval (struct varlena * seqin)
}
static SequenceTupleForm
read_info (char * caller, SeqTable elm, Buffer * buf)
read_info(char *caller, SeqTable elm, Buffer * buf)
{
ItemPointerData iptr;
PageHeader page;
@ -319,25 +333,25 @@ read_info (char * caller, SeqTable elm, Buffer * buf)
SequenceTupleForm seq;
ItemPointerSet(&iptr, 0, FirstOffsetNumber);
RelationSetSingleWLockPage (elm->rel, &iptr);
RelationSetSingleWLockPage(elm->rel, &iptr);
if ( RelationGetNumberOfBlocks (elm->rel) != 1 )
elog (WARN, "%s.%s: invalid number of blocks in sequence",
if (RelationGetNumberOfBlocks(elm->rel) != 1)
elog(WARN, "%s.%s: invalid number of blocks in sequence",
elm->name, caller);
*buf = ReadBuffer (elm->rel, 0);
if ( !BufferIsValid (*buf) )
elog (WARN, "%s.%s: ReadBuffer failed", elm->name, caller);
*buf = ReadBuffer(elm->rel, 0);
if (!BufferIsValid(*buf))
elog(WARN, "%s.%s: ReadBuffer failed", elm->name, caller);
page = (PageHeader) BufferGetPage (*buf);
sm = (sequence_magic *) PageGetSpecialPointer (page);
page = (PageHeader) BufferGetPage(*buf);
sm = (sequence_magic *) PageGetSpecialPointer(page);
if ( sm->magic != SEQ_MAGIC )
elog (WARN, "%s.%s: bad magic (%08X)", elm->name, caller, sm->magic);
if (sm->magic != SEQ_MAGIC)
elog(WARN, "%s.%s: bad magic (%08X)", elm->name, caller, sm->magic);
lp = PageGetItemId (page, FirstOffsetNumber);
Assert (ItemIdIsUsed (lp));
tuple = (HeapTuple) PageGetItem ((Page) page, lp);
lp = PageGetItemId(page, FirstOffsetNumber);
Assert(ItemIdIsUsed(lp));
tuple = (HeapTuple) PageGetItem((Page) page, lp);
seq = (SequenceTupleForm) GETSTRUCT(tuple);
@ -349,60 +363,62 @@ read_info (char * caller, SeqTable elm, Buffer * buf)
static SeqTable
init_sequence (char * caller, char * name)
init_sequence(char *caller, char *name)
{
SeqTable elm, priv = (SeqTable) NULL;
SeqTable elm,
priv = (SeqTable) NULL;
SeqTable temp;
for (elm = seqtab; elm != (SeqTable) NULL; )
for (elm = seqtab; elm != (SeqTable) NULL;)
{
if ( strcmp (elm->name, name) == 0 )
if (strcmp(elm->name, name) == 0)
break;
priv = elm;
elm = elm->next;
}
if ( elm == (SeqTable) NULL ) /* not found */
if (elm == (SeqTable) NULL) /* not found */
{
temp = (SeqTable) malloc (sizeof(SeqTableData));
temp->name = malloc (strlen(name) + 1);
strcpy (temp->name, name);
temp = (SeqTable) malloc(sizeof(SeqTableData));
temp->name = malloc(strlen(name) + 1);
strcpy(temp->name, name);
temp->rel = (Relation) NULL;
temp->cached = temp->last = temp->increment = 0;
temp->next = (SeqTable) NULL;
}
else /* found */
else
/* found */
{
if ( elm->rel != (Relation) NULL) /* already opened */
if (elm->rel != (Relation) NULL) /* already opened */
return (elm);
temp = elm;
}
temp->rel = heap_openr (name);
temp->rel = heap_openr(name);
if ( ! RelationIsValid (temp->rel) )
elog (WARN, "%s.%s: sequence does not exist", name, caller);
if (!RelationIsValid(temp->rel))
elog(WARN, "%s.%s: sequence does not exist", name, caller);
RelationSetWIntentLock (temp->rel);
RelationSetWIntentLock(temp->rel);
if ( temp->rel->rd_rel->relkind != RELKIND_SEQUENCE )
elog (WARN, "%s.%s: %s is not sequence !", name, caller, name);
if (temp->rel->rd_rel->relkind != RELKIND_SEQUENCE)
elog(WARN, "%s.%s: %s is not sequence !", name, caller, name);
if ( elm != (SeqTable) NULL ) /* we opened sequence from our */
if (elm != (SeqTable) NULL) /* we opened sequence from our */
{ /* SeqTable - check relid ! */
if ( RelationGetRelationId (elm->rel) != elm->relid )
if (RelationGetRelationId(elm->rel) != elm->relid)
{
elog (NOTICE, "%s.%s: sequence was re-created",
elog(NOTICE, "%s.%s: sequence was re-created",
name, caller, name);
elm->cached = elm->last = elm->increment = 0;
elm->relid = RelationGetRelationId (elm->rel);
elm->relid = RelationGetRelationId(elm->rel);
}
}
else
{
elm = temp;
elm->relid = RelationGetRelationId (elm->rel);
if ( seqtab == (SeqTable) NULL )
elm->relid = RelationGetRelationId(elm->rel);
if (seqtab == (SeqTable) NULL)
seqtab = elm;
else
priv->next = elm;
@ -418,21 +434,21 @@ init_sequence (char * caller, char * name)
* is calling by xact mgr at commit/abort.
*/
void
CloseSequences (void)
CloseSequences(void)
{
SeqTable elm;
Relation rel;
ItsSequenceCreation = false;
for (elm = seqtab; elm != (SeqTable) NULL; )
for (elm = seqtab; elm != (SeqTable) NULL;)
{
if ( elm->rel != (Relation) NULL ) /* opened in current xact */
if (elm->rel != (Relation) NULL) /* opened in current xact */
{
rel = elm->rel;
elm->rel = (Relation) NULL;
RelationUnsetWIntentLock (rel);
heap_close (rel);
RelationUnsetWIntentLock(rel);
heap_close(rel);
}
elm = elm->next;
}
@ -443,7 +459,7 @@ CloseSequences (void)
static void
init_params (CreateSeqStmt *seq, SequenceTupleForm new)
init_params(CreateSeqStmt * seq, SequenceTupleForm new)
{
DefElem *last_value = NULL;
DefElem *increment_by = NULL;
@ -453,89 +469,89 @@ init_params (CreateSeqStmt *seq, SequenceTupleForm new)
List *option;
new->is_cycled = 'f';
foreach (option, seq->options)
foreach(option, seq->options)
{
DefElem *defel = (DefElem *)lfirst(option);
DefElem *defel = (DefElem *) lfirst(option);
if ( !strcasecmp(defel->defname, "increment") )
if (!strcasecmp(defel->defname, "increment"))
increment_by = defel;
else if ( !strcasecmp(defel->defname, "start") )
else if (!strcasecmp(defel->defname, "start"))
last_value = defel;
else if ( !strcasecmp(defel->defname, "maxvalue") )
else if (!strcasecmp(defel->defname, "maxvalue"))
max_value = defel;
else if ( !strcasecmp(defel->defname, "minvalue") )
else if (!strcasecmp(defel->defname, "minvalue"))
min_value = defel;
else if ( !strcasecmp(defel->defname, "cache") )
else if (!strcasecmp(defel->defname, "cache"))
cache_value = defel;
else if ( !strcasecmp(defel->defname, "cycle") )
else if (!strcasecmp(defel->defname, "cycle"))
{
if ( defel->arg != (Node*) NULL )
elog (WARN, "DefineSequence: CYCLE ??");
if (defel->arg != (Node *) NULL)
elog(WARN, "DefineSequence: CYCLE ??");
new->is_cycled = 't';
}
else
elog (WARN, "DefineSequence: option \"%s\" not recognized",
elog(WARN, "DefineSequence: option \"%s\" not recognized",
defel->defname);
}
if ( increment_by == (DefElem*) NULL ) /* INCREMENT BY */
if (increment_by == (DefElem *) NULL) /* INCREMENT BY */
new->increment_by = 1;
else if ( ( new->increment_by = get_param (increment_by) ) == 0 )
elog (WARN, "DefineSequence: can't INCREMENT by 0");
else if ((new->increment_by = get_param(increment_by)) == 0)
elog(WARN, "DefineSequence: can't INCREMENT by 0");
if ( max_value == (DefElem*) NULL ) /* MAXVALUE */
if ( new->increment_by > 0 )
if (max_value == (DefElem *) NULL) /* MAXVALUE */
if (new->increment_by > 0)
new->max_value = SEQ_MAXVALUE; /* ascending seq */
else
new->max_value = -1; /* descending seq */
new->max_value = -1;/* descending seq */
else
new->max_value = get_param (max_value);
new->max_value = get_param(max_value);
if ( min_value == (DefElem*) NULL ) /* MINVALUE */
if ( new->increment_by > 0 )
if (min_value == (DefElem *) NULL) /* MINVALUE */
if (new->increment_by > 0)
new->min_value = 1; /* ascending seq */
else
new->min_value = SEQ_MINVALUE; /* descending seq */
else
new->min_value = get_param (min_value);
new->min_value = get_param(min_value);
if ( new->min_value >= new->max_value )
elog (WARN, "DefineSequence: MINVALUE (%d) can't be >= MAXVALUE (%d)",
if (new->min_value >= new->max_value)
elog(WARN, "DefineSequence: MINVALUE (%d) can't be >= MAXVALUE (%d)",
new->min_value, new->max_value);
if ( last_value == (DefElem*) NULL ) /* START WITH */
if ( new->increment_by > 0 )
if (last_value == (DefElem *) NULL) /* START WITH */
if (new->increment_by > 0)
new->last_value = new->min_value; /* ascending seq */
else
new->last_value = new->max_value; /* descending seq */
else
new->last_value = get_param (last_value);
new->last_value = get_param(last_value);
if ( new->last_value < new->min_value )
elog (WARN, "DefineSequence: START value (%d) can't be < MINVALUE (%d)",
if (new->last_value < new->min_value)
elog(WARN, "DefineSequence: START value (%d) can't be < MINVALUE (%d)",
new->last_value, new->min_value);
if ( new->last_value > new->max_value )
elog (WARN, "DefineSequence: START value (%d) can't be > MAXVALUE (%d)",
if (new->last_value > new->max_value)
elog(WARN, "DefineSequence: START value (%d) can't be > MAXVALUE (%d)",
new->last_value, new->max_value);
if ( cache_value == (DefElem*) NULL ) /* CACHE */
if (cache_value == (DefElem *) NULL) /* CACHE */
new->cache_value = 1;
else if ( ( new->cache_value = get_param (cache_value) ) <= 0 )
elog (WARN, "DefineSequence: CACHE (%d) can't be <= 0",
else if ((new->cache_value = get_param(cache_value)) <= 0)
elog(WARN, "DefineSequence: CACHE (%d) can't be <= 0",
new->cache_value);
}
static int
get_param (DefElem *def)
get_param(DefElem * def)
{
if ( def->arg == (Node*) NULL )
elog (WARN, "DefineSequence: \"%s\" value unspecified", def->defname);
if (def->arg == (Node *) NULL)
elog(WARN, "DefineSequence: \"%s\" value unspecified", def->defname);
if ( nodeTag (def->arg) == T_Integer )
return (intVal (def->arg));
if (nodeTag(def->arg) == T_Integer)
return (intVal(def->arg));
elog (WARN, "DefineSequence: \"%s\" is to be integer", def->defname);
elog(WARN, "DefineSequence: \"%s\" is to be integer", def->defname);
return (-1);
}

View File

@ -34,16 +34,16 @@
TriggerData *CurrentTriggerData = NULL;
void RelationBuildTriggers (Relation relation);
void FreeTriggerDesc (Relation relation);
void RelationBuildTriggers(Relation relation);
void FreeTriggerDesc(Relation relation);
static void DescribeTrigger (TriggerDesc *trigdesc, Trigger *trigger);
static void DescribeTrigger(TriggerDesc * trigdesc, Trigger * trigger);
extern void fmgr_info(Oid procedureId, func_ptr *function, int *nargs);
extern void fmgr_info(Oid procedureId, func_ptr * function, int *nargs);
extern GlobalMemory CacheCxt;
void
CreateTrigger (CreateTrigStmt *stmt)
CreateTrigger(CreateTrigStmt * stmt)
{
int16 tgtype;
int16 tgattr[8] = {0};
@ -63,153 +63,155 @@ CreateTrigger (CreateTrigStmt *stmt)
int found = 0;
int i;
if ( IsSystemRelationName (stmt->relname) )
if (IsSystemRelationName(stmt->relname))
elog(WARN, "CreateTrigger: can't create trigger for system relation %s", stmt->relname);
#ifndef NO_SECURITY
if ( !pg_ownercheck (GetPgUserName (), stmt->relname, RELNAME))
if (!pg_ownercheck(GetPgUserName(), stmt->relname, RELNAME))
elog(WARN, "%s: %s", stmt->relname, aclcheck_error_strings[ACLCHECK_NOT_OWNER]);
#endif
rel = heap_openr (stmt->relname);
if ( !RelationIsValid (rel) )
elog (WARN, "CreateTrigger: there is no relation %s", stmt->relname);
rel = heap_openr(stmt->relname);
if (!RelationIsValid(rel))
elog(WARN, "CreateTrigger: there is no relation %s", stmt->relname);
RelationSetLockForWrite (rel);
RelationSetLockForWrite(rel);
TRIGGER_CLEAR_TYPE (tgtype);
if ( stmt->before )
TRIGGER_SETT_BEFORE (tgtype);
if ( stmt->row )
TRIGGER_SETT_ROW (tgtype);
TRIGGER_CLEAR_TYPE(tgtype);
if (stmt->before)
TRIGGER_SETT_BEFORE(tgtype);
if (stmt->row)
TRIGGER_SETT_ROW(tgtype);
for (i = 0; i < 3 && stmt->actions[i]; i++)
{
switch ( stmt->actions[i] )
switch (stmt->actions[i])
{
case 'i':
if ( TRIGGER_FOR_INSERT (tgtype) )
elog (WARN, "CreateTrigger: double INSERT event specified");
TRIGGER_SETT_INSERT (tgtype);
if (TRIGGER_FOR_INSERT(tgtype))
elog(WARN, "CreateTrigger: double INSERT event specified");
TRIGGER_SETT_INSERT(tgtype);
break;
case 'd':
if ( TRIGGER_FOR_DELETE (tgtype) )
elog (WARN, "CreateTrigger: double DELETE event specified");
TRIGGER_SETT_DELETE (tgtype);
if (TRIGGER_FOR_DELETE(tgtype))
elog(WARN, "CreateTrigger: double DELETE event specified");
TRIGGER_SETT_DELETE(tgtype);
break;
case 'u':
if ( TRIGGER_FOR_UPDATE (tgtype) )
elog (WARN, "CreateTrigger: double UPDATE event specified");
TRIGGER_SETT_UPDATE (tgtype);
if (TRIGGER_FOR_UPDATE(tgtype))
elog(WARN, "CreateTrigger: double UPDATE event specified");
TRIGGER_SETT_UPDATE(tgtype);
break;
default:
elog (WARN, "CreateTrigger: unknown event specified");
elog(WARN, "CreateTrigger: unknown event specified");
break;
}
}
/* Scan pg_trigger */
tgrel = heap_openr (TriggerRelationName);
RelationSetLockForWrite (tgrel);
tgrel = heap_openr(TriggerRelationName);
RelationSetLockForWrite(tgrel);
ScanKeyEntryInitialize(&key, 0, Anum_pg_trigger_tgrelid,
ObjectIdEqualRegProcedure, rel->rd_id);
tgscan = heap_beginscan (tgrel, 0, NowTimeQual, 1, &key);
while (tuple = heap_getnext (tgscan, 0, (Buffer *)NULL), PointerIsValid(tuple))
tgscan = heap_beginscan(tgrel, 0, NowTimeQual, 1, &key);
while (tuple = heap_getnext(tgscan, 0, (Buffer *) NULL), PointerIsValid(tuple))
{
Form_pg_trigger pg_trigger = (Form_pg_trigger) GETSTRUCT (tuple);
if ( namestrcmp (&(pg_trigger->tgname), stmt->trigname) == 0 )
elog (WARN, "CreateTrigger: trigger %s already defined on relation %s",
Form_pg_trigger pg_trigger = (Form_pg_trigger) GETSTRUCT(tuple);
if (namestrcmp(&(pg_trigger->tgname), stmt->trigname) == 0)
elog(WARN, "CreateTrigger: trigger %s already defined on relation %s",
stmt->trigname, stmt->relname);
else
found++;
}
heap_endscan (tgscan);
heap_endscan(tgscan);
memset (fargtypes, 0, 8 * sizeof(Oid));
tuple = SearchSysCacheTuple (PRONAME,
PointerGetDatum (stmt->funcname),
0, PointerGetDatum (fargtypes), 0);
if ( !HeapTupleIsValid (tuple) ||
((Form_pg_proc)GETSTRUCT(tuple))->prorettype != 0 ||
((Form_pg_proc)GETSTRUCT(tuple))->pronargs != 0 )
elog (WARN, "CreateTrigger: function %s () does not exist", stmt->funcname);
memset(fargtypes, 0, 8 * sizeof(Oid));
tuple = SearchSysCacheTuple(PRONAME,
PointerGetDatum(stmt->funcname),
0, PointerGetDatum(fargtypes), 0);
if (!HeapTupleIsValid(tuple) ||
((Form_pg_proc) GETSTRUCT(tuple))->prorettype != 0 ||
((Form_pg_proc) GETSTRUCT(tuple))->pronargs != 0)
elog(WARN, "CreateTrigger: function %s () does not exist", stmt->funcname);
if ( ((Form_pg_proc)GETSTRUCT(tuple))->prolang != ClanguageId )
elog (WARN, "CreateTrigger: only C functions are supported");
if (((Form_pg_proc) GETSTRUCT(tuple))->prolang != ClanguageId)
elog(WARN, "CreateTrigger: only C functions are supported");
memset (nulls, ' ', Natts_pg_trigger * sizeof (char));
memset(nulls, ' ', Natts_pg_trigger * sizeof(char));
values[Anum_pg_trigger_tgrelid - 1] = ObjectIdGetDatum (rel->rd_id);
values[Anum_pg_trigger_tgname - 1] = NameGetDatum (namein (stmt->trigname));
values[Anum_pg_trigger_tgfoid - 1] = ObjectIdGetDatum (tuple->t_oid);
values[Anum_pg_trigger_tgtype - 1] = Int16GetDatum (tgtype);
if ( stmt->args )
values[Anum_pg_trigger_tgrelid - 1] = ObjectIdGetDatum(rel->rd_id);
values[Anum_pg_trigger_tgname - 1] = NameGetDatum(namein(stmt->trigname));
values[Anum_pg_trigger_tgfoid - 1] = ObjectIdGetDatum(tuple->t_oid);
values[Anum_pg_trigger_tgtype - 1] = Int16GetDatum(tgtype);
if (stmt->args)
{
List *le;
char *args;
int16 nargs = length (stmt->args);
int16 nargs = length(stmt->args);
int len = 0;
foreach (le, stmt->args)
foreach(le, stmt->args)
{
char *ar = (char *) lfirst (le);
len += strlen (ar) + 4;
char *ar = (char *) lfirst(le);
len += strlen(ar) + 4;
}
args = (char *) palloc (len + 1);
args = (char *) palloc(len + 1);
args[0] = 0;
foreach (le, stmt->args)
sprintf (args + strlen (args), "%s\\000", (char *)lfirst (le));
values[Anum_pg_trigger_tgnargs - 1] = Int16GetDatum (nargs);
values[Anum_pg_trigger_tgargs - 1] = PointerGetDatum (byteain (args));
foreach(le, stmt->args)
sprintf(args + strlen(args), "%s\\000", (char *) lfirst(le));
values[Anum_pg_trigger_tgnargs - 1] = Int16GetDatum(nargs);
values[Anum_pg_trigger_tgargs - 1] = PointerGetDatum(byteain(args));
}
else
{
values[Anum_pg_trigger_tgnargs - 1] = Int16GetDatum (0);
values[Anum_pg_trigger_tgargs - 1] = PointerGetDatum (byteain (""));
values[Anum_pg_trigger_tgnargs - 1] = Int16GetDatum(0);
values[Anum_pg_trigger_tgargs - 1] = PointerGetDatum(byteain(""));
}
values[Anum_pg_trigger_tgattr - 1] = PointerGetDatum (tgattr);
values[Anum_pg_trigger_tgattr - 1] = PointerGetDatum(tgattr);
tuple = heap_formtuple (tgrel->rd_att, values, nulls);
heap_insert (tgrel, tuple);
CatalogOpenIndices (Num_pg_trigger_indices, Name_pg_trigger_indices, idescs);
CatalogIndexInsert (idescs, Num_pg_trigger_indices, tgrel, tuple);
CatalogCloseIndices (Num_pg_trigger_indices, idescs);
pfree (tuple);
RelationUnsetLockForWrite (tgrel);
heap_close (tgrel);
tuple = heap_formtuple(tgrel->rd_att, values, nulls);
heap_insert(tgrel, tuple);
CatalogOpenIndices(Num_pg_trigger_indices, Name_pg_trigger_indices, idescs);
CatalogIndexInsert(idescs, Num_pg_trigger_indices, tgrel, tuple);
CatalogCloseIndices(Num_pg_trigger_indices, idescs);
pfree(tuple);
RelationUnsetLockForWrite(tgrel);
heap_close(tgrel);
pfree (DatumGetPointer(values[Anum_pg_trigger_tgname - 1]));
pfree (DatumGetPointer(values[Anum_pg_trigger_tgargs - 1]));
pfree(DatumGetPointer(values[Anum_pg_trigger_tgname - 1]));
pfree(DatumGetPointer(values[Anum_pg_trigger_tgargs - 1]));
/* update pg_class */
relrdesc = heap_openr (RelationRelationName);
tuple = ClassNameIndexScan (relrdesc, stmt->relname);
if ( !PointerIsValid (tuple) )
relrdesc = heap_openr(RelationRelationName);
tuple = ClassNameIndexScan(relrdesc, stmt->relname);
if (!PointerIsValid(tuple))
{
heap_close(relrdesc);
elog(WARN, "CreateTrigger: relation %s not found in pg_class", stmt->relname);
}
((Form_pg_class) GETSTRUCT(tuple))->reltriggers = found + 1;
RelationInvalidateHeapTuple (relrdesc, tuple);
RelationInvalidateHeapTuple(relrdesc, tuple);
oldTID = tuple->t_ctid;
heap_replace (relrdesc, &oldTID, tuple);
CatalogOpenIndices (Num_pg_class_indices, Name_pg_class_indices, ridescs);
CatalogIndexInsert (ridescs, Num_pg_class_indices, relrdesc, tuple);
CatalogCloseIndices (Num_pg_class_indices, ridescs);
heap_replace(relrdesc, &oldTID, tuple);
CatalogOpenIndices(Num_pg_class_indices, Name_pg_class_indices, ridescs);
CatalogIndexInsert(ridescs, Num_pg_class_indices, relrdesc, tuple);
CatalogCloseIndices(Num_pg_class_indices, ridescs);
pfree(tuple);
heap_close(relrdesc);
CommandCounterIncrement ();
oldcxt = MemoryContextSwitchTo ((MemoryContext)CacheCxt);
FreeTriggerDesc (rel);
CommandCounterIncrement();
oldcxt = MemoryContextSwitchTo((MemoryContext) CacheCxt);
FreeTriggerDesc(rel);
rel->rd_rel->reltriggers = found + 1;
RelationBuildTriggers (rel);
MemoryContextSwitchTo (oldcxt);
heap_close (rel);
RelationBuildTriggers(rel);
MemoryContextSwitchTo(oldcxt);
heap_close(rel);
return;
}
void
DropTrigger (DropTrigStmt *stmt)
DropTrigger(DropTrigStmt * stmt)
{
Relation rel;
Relation tgrel;
@ -224,99 +226,100 @@ DropTrigger (DropTrigStmt *stmt)
int tgfound = 0;
#ifndef NO_SECURITY
if ( !pg_ownercheck (GetPgUserName (), stmt->relname, RELNAME))
if (!pg_ownercheck(GetPgUserName(), stmt->relname, RELNAME))
elog(WARN, "%s: %s", stmt->relname, aclcheck_error_strings[ACLCHECK_NOT_OWNER]);
#endif
rel = heap_openr (stmt->relname);
if ( !RelationIsValid (rel) )
elog (WARN, "DropTrigger: there is no relation %s", stmt->relname);
rel = heap_openr(stmt->relname);
if (!RelationIsValid(rel))
elog(WARN, "DropTrigger: there is no relation %s", stmt->relname);
RelationSetLockForWrite (rel);
RelationSetLockForWrite(rel);
tgrel = heap_openr (TriggerRelationName);
RelationSetLockForWrite (tgrel);
tgrel = heap_openr(TriggerRelationName);
RelationSetLockForWrite(tgrel);
ScanKeyEntryInitialize(&key, 0, Anum_pg_trigger_tgrelid,
ObjectIdEqualRegProcedure, rel->rd_id);
tgscan = heap_beginscan (tgrel, 0, NowTimeQual, 1, &key);
while (tuple = heap_getnext (tgscan, 0, (Buffer *)NULL), PointerIsValid(tuple))
tgscan = heap_beginscan(tgrel, 0, NowTimeQual, 1, &key);
while (tuple = heap_getnext(tgscan, 0, (Buffer *) NULL), PointerIsValid(tuple))
{
Form_pg_trigger pg_trigger = (Form_pg_trigger) GETSTRUCT (tuple);
if ( namestrcmp (&(pg_trigger->tgname), stmt->trigname) == 0 )
Form_pg_trigger pg_trigger = (Form_pg_trigger) GETSTRUCT(tuple);
if (namestrcmp(&(pg_trigger->tgname), stmt->trigname) == 0)
{
heap_delete (tgrel, &tuple->t_ctid);
heap_delete(tgrel, &tuple->t_ctid);
tgfound++;
}
else
found++;
}
if ( tgfound == 0 )
elog (WARN, "DropTrigger: there is no trigger %s on relation %s",
if (tgfound == 0)
elog(WARN, "DropTrigger: there is no trigger %s on relation %s",
stmt->trigname, stmt->relname);
if ( tgfound > 1 )
elog (NOTICE, "DropTrigger: found (and deleted) %d trigger %s on relation %s",
if (tgfound > 1)
elog(NOTICE, "DropTrigger: found (and deleted) %d trigger %s on relation %s",
tgfound, stmt->trigname, stmt->relname);
heap_endscan (tgscan);
RelationUnsetLockForWrite (tgrel);
heap_close (tgrel);
heap_endscan(tgscan);
RelationUnsetLockForWrite(tgrel);
heap_close(tgrel);
/* update pg_class */
relrdesc = heap_openr (RelationRelationName);
tuple = ClassNameIndexScan (relrdesc, stmt->relname);
if ( !PointerIsValid (tuple) )
relrdesc = heap_openr(RelationRelationName);
tuple = ClassNameIndexScan(relrdesc, stmt->relname);
if (!PointerIsValid(tuple))
{
heap_close(relrdesc);
elog(WARN, "DropTrigger: relation %s not found in pg_class", stmt->relname);
}
((Form_pg_class) GETSTRUCT(tuple))->reltriggers = found;
RelationInvalidateHeapTuple (relrdesc, tuple);
RelationInvalidateHeapTuple(relrdesc, tuple);
oldTID = tuple->t_ctid;
heap_replace (relrdesc, &oldTID, tuple);
CatalogOpenIndices (Num_pg_class_indices, Name_pg_class_indices, ridescs);
CatalogIndexInsert (ridescs, Num_pg_class_indices, relrdesc, tuple);
CatalogCloseIndices (Num_pg_class_indices, ridescs);
heap_replace(relrdesc, &oldTID, tuple);
CatalogOpenIndices(Num_pg_class_indices, Name_pg_class_indices, ridescs);
CatalogIndexInsert(ridescs, Num_pg_class_indices, relrdesc, tuple);
CatalogCloseIndices(Num_pg_class_indices, ridescs);
pfree(tuple);
heap_close(relrdesc);
CommandCounterIncrement ();
oldcxt = MemoryContextSwitchTo ((MemoryContext)CacheCxt);
FreeTriggerDesc (rel);
CommandCounterIncrement();
oldcxt = MemoryContextSwitchTo((MemoryContext) CacheCxt);
FreeTriggerDesc(rel);
rel->rd_rel->reltriggers = found;
if ( found > 0 )
RelationBuildTriggers (rel);
MemoryContextSwitchTo (oldcxt);
heap_close (rel);
if (found > 0)
RelationBuildTriggers(rel);
MemoryContextSwitchTo(oldcxt);
heap_close(rel);
return;
}
void
RelationRemoveTriggers (Relation rel)
RelationRemoveTriggers(Relation rel)
{
Relation tgrel;
HeapScanDesc tgscan;
ScanKeyData key;
HeapTuple tup;
tgrel = heap_openr (TriggerRelationName);
RelationSetLockForWrite (tgrel);
tgrel = heap_openr(TriggerRelationName);
RelationSetLockForWrite(tgrel);
ScanKeyEntryInitialize(&key, 0, Anum_pg_trigger_tgrelid,
ObjectIdEqualRegProcedure, rel->rd_id);
tgscan = heap_beginscan (tgrel, 0, NowTimeQual, 1, &key);
tgscan = heap_beginscan(tgrel, 0, NowTimeQual, 1, &key);
while (tup = heap_getnext (tgscan, 0, (Buffer *)NULL), PointerIsValid(tup))
heap_delete (tgrel, &tup->t_ctid);
while (tup = heap_getnext(tgscan, 0, (Buffer *) NULL), PointerIsValid(tup))
heap_delete(tgrel, &tup->t_ctid);
heap_endscan (tgscan);
RelationUnsetLockForWrite (tgrel);
heap_close (tgrel);
heap_endscan(tgscan);
RelationUnsetLockForWrite(tgrel);
heap_close(tgrel);
}
void
RelationBuildTriggers (Relation relation)
RelationBuildTriggers(Relation relation)
{
TriggerDesc *trigdesc = (TriggerDesc *) palloc (sizeof (TriggerDesc));
TriggerDesc *trigdesc = (TriggerDesc *) palloc(sizeof(TriggerDesc));
int ntrigs = relation->rd_rel->reltriggers;
Trigger *triggers = NULL;
Trigger *build;
@ -333,20 +336,20 @@ RelationBuildTriggers (Relation relation)
bool isnull;
int found;
memset (trigdesc, 0, sizeof (TriggerDesc));
memset(trigdesc, 0, sizeof(TriggerDesc));
ScanKeyEntryInitialize(&skey,
(bits16)0x0,
(AttrNumber)1,
(RegProcedure)ObjectIdEqualRegProcedure,
(bits16) 0x0,
(AttrNumber) 1,
(RegProcedure) ObjectIdEqualRegProcedure,
ObjectIdGetDatum(relation->rd_id));
tgrel = heap_openr(TriggerRelationName);
RelationSetLockForRead (tgrel);
RelationSetLockForRead(tgrel);
irel = index_openr(TriggerRelidIndex);
sd = index_beginscan(irel, false, 1, &skey);
for (found = 0; ; )
for (found = 0;;)
{
indexRes = index_getnext(sd, ForwardScanDirection);
if (!indexRes)
@ -357,48 +360,48 @@ RelationBuildTriggers (Relation relation)
pfree(indexRes);
if (!HeapTupleIsValid(tuple))
continue;
if ( found == ntrigs )
elog (WARN, "RelationBuildTriggers: unexpected record found for rel %.*s",
if (found == ntrigs)
elog(WARN, "RelationBuildTriggers: unexpected record found for rel %.*s",
NAMEDATALEN, relation->rd_rel->relname.data);
pg_trigger = (Form_pg_trigger) GETSTRUCT (tuple);
pg_trigger = (Form_pg_trigger) GETSTRUCT(tuple);
if ( triggers == NULL )
triggers = (Trigger *) palloc (sizeof (Trigger));
if (triggers == NULL)
triggers = (Trigger *) palloc(sizeof(Trigger));
else
triggers = (Trigger *) repalloc (triggers, (found + 1) * sizeof (Trigger));
triggers = (Trigger *) repalloc(triggers, (found + 1) * sizeof(Trigger));
build = &(triggers[found]);
build->tgname = nameout (&(pg_trigger->tgname));
build->tgname = nameout(&(pg_trigger->tgname));
build->tgfoid = pg_trigger->tgfoid;
build->tgfunc = NULL;
build->tgtype = pg_trigger->tgtype;
build->tgnargs = pg_trigger->tgnargs;
memcpy (build->tgattr, &(pg_trigger->tgattr), 8 * sizeof (int16));
val = (struct varlena*) fastgetattr (tuple,
memcpy(build->tgattr, &(pg_trigger->tgattr), 8 * sizeof(int16));
val = (struct varlena *) fastgetattr(tuple,
Anum_pg_trigger_tgargs,
tgrel->rd_att, &isnull);
if ( isnull )
elog (WARN, "RelationBuildTriggers: tgargs IS NULL for rel %.*s",
if (isnull)
elog(WARN, "RelationBuildTriggers: tgargs IS NULL for rel %.*s",
NAMEDATALEN, relation->rd_rel->relname.data);
if ( build->tgnargs > 0 )
if (build->tgnargs > 0)
{
char *p;
int i;
val = (struct varlena*) fastgetattr (tuple,
val = (struct varlena *) fastgetattr(tuple,
Anum_pg_trigger_tgargs,
tgrel->rd_att, &isnull);
if ( isnull )
elog (WARN, "RelationBuildTriggers: tgargs IS NULL for rel %.*s",
if (isnull)
elog(WARN, "RelationBuildTriggers: tgargs IS NULL for rel %.*s",
NAMEDATALEN, relation->rd_rel->relname.data);
p = (char *) VARDATA (val);
build->tgargs = (char**) palloc (build->tgnargs * sizeof (char*));
p = (char *) VARDATA(val);
build->tgargs = (char **) palloc(build->tgnargs * sizeof(char *));
for (i = 0; i < build->tgnargs; i++)
{
build->tgargs[i] = (char*) palloc (strlen (p) + 1);
strcpy (build->tgargs[i], p);
p += strlen (p) + 1;
build->tgargs[i] = (char *) palloc(strlen(p) + 1);
strcpy(build->tgargs[i], p);
p += strlen(p) + 1;
}
}
else
@ -408,23 +411,23 @@ RelationBuildTriggers (Relation relation)
ReleaseBuffer(buffer);
}
if ( found < ntrigs )
elog (WARN, "RelationBuildTriggers: %d record not found for rel %.*s",
if (found < ntrigs)
elog(WARN, "RelationBuildTriggers: %d record not found for rel %.*s",
ntrigs - found,
NAMEDATALEN, relation->rd_rel->relname.data);
index_endscan (sd);
pfree (sd);
index_close (irel);
RelationUnsetLockForRead (tgrel);
heap_close (tgrel);
index_endscan(sd);
pfree(sd);
index_close(irel);
RelationUnsetLockForRead(tgrel);
heap_close(tgrel);
/* Build trigdesc */
trigdesc->triggers = triggers;
for (found = 0; found < ntrigs; found++)
{
build = &(triggers[found]);
DescribeTrigger (trigdesc, build);
DescribeTrigger(trigdesc, build);
}
relation->trigdesc = trigdesc;
@ -432,60 +435,62 @@ RelationBuildTriggers (Relation relation)
}
void
FreeTriggerDesc (Relation relation)
FreeTriggerDesc(Relation relation)
{
TriggerDesc *trigdesc = relation->trigdesc;
Trigger ***t;
Trigger *trigger;
int i;
if ( trigdesc == NULL )
if (trigdesc == NULL)
return;
t = trigdesc->tg_before_statement;
for (i = 0; i < 3; i++)
if ( t[i] != NULL )
pfree (t[i]);
if (t[i] != NULL)
pfree(t[i]);
t = trigdesc->tg_before_row;
for (i = 0; i < 3; i++)
if ( t[i] != NULL )
pfree (t[i]);
if (t[i] != NULL)
pfree(t[i]);
t = trigdesc->tg_after_row;
for (i = 0; i < 3; i++)
if ( t[i] != NULL )
pfree (t[i]);
if (t[i] != NULL)
pfree(t[i]);
t = trigdesc->tg_after_statement;
for (i = 0; i < 3; i++)
if ( t[i] != NULL )
pfree (t[i]);
if (t[i] != NULL)
pfree(t[i]);
trigger = trigdesc->triggers;
for (i = 0; i < relation->rd_rel->reltriggers; i++)
{
pfree (trigger->tgname);
if ( trigger->tgnargs > 0 )
pfree(trigger->tgname);
if (trigger->tgnargs > 0)
{
while ( --(trigger->tgnargs) >= 0 )
pfree (trigger->tgargs[trigger->tgnargs]);
pfree (trigger->tgargs);
while (--(trigger->tgnargs) >= 0)
pfree(trigger->tgargs[trigger->tgnargs]);
pfree(trigger->tgargs);
}
trigger++;
}
pfree (trigdesc->triggers);
pfree (trigdesc);
pfree(trigdesc->triggers);
pfree(trigdesc);
relation->trigdesc = NULL;
return;
}
static void
DescribeTrigger (TriggerDesc *trigdesc, Trigger *trigger)
DescribeTrigger(TriggerDesc * trigdesc, Trigger * trigger)
{
uint16 *n;
Trigger ***t, ***tp;
Trigger ***t,
***tp;
if ( TRIGGER_FOR_ROW (trigger->tgtype) ) /* Is ROW/STATEMENT trigger */
if (TRIGGER_FOR_ROW(trigger->tgtype)) /* Is ROW/STATEMENT
* trigger */
{
if ( TRIGGER_FOR_BEFORE (trigger->tgtype) )
if (TRIGGER_FOR_BEFORE(trigger->tgtype))
{
n = trigdesc->n_before_row;
t = trigdesc->tg_before_row;
@ -496,9 +501,10 @@ DescribeTrigger (TriggerDesc *trigdesc, Trigger *trigger)
t = trigdesc->tg_after_row;
}
}
else /* STATEMENT (NI) */
else
/* STATEMENT (NI) */
{
if ( TRIGGER_FOR_BEFORE (trigger->tgtype) )
if (TRIGGER_FOR_BEFORE(trigger->tgtype))
{
n = trigdesc->n_before_statement;
t = trigdesc->tg_before_statement;
@ -510,38 +516,38 @@ DescribeTrigger (TriggerDesc *trigdesc, Trigger *trigger)
}
}
if ( TRIGGER_FOR_INSERT (trigger->tgtype) )
if (TRIGGER_FOR_INSERT(trigger->tgtype))
{
tp = &(t[TRIGGER_EVENT_INSERT]);
if ( *tp == NULL )
*tp = (Trigger **) palloc (sizeof (Trigger *));
if (*tp == NULL)
*tp = (Trigger **) palloc(sizeof(Trigger *));
else
*tp = (Trigger **) repalloc (*tp, (n[TRIGGER_EVENT_INSERT] + 1) *
sizeof (Trigger *));
*tp = (Trigger **) repalloc(*tp, (n[TRIGGER_EVENT_INSERT] + 1) *
sizeof(Trigger *));
(*tp)[n[TRIGGER_EVENT_INSERT]] = trigger;
(n[TRIGGER_EVENT_INSERT])++;
}
if ( TRIGGER_FOR_DELETE (trigger->tgtype) )
if (TRIGGER_FOR_DELETE(trigger->tgtype))
{
tp = &(t[TRIGGER_EVENT_DELETE]);
if ( *tp == NULL )
*tp = (Trigger **) palloc (sizeof (Trigger *));
if (*tp == NULL)
*tp = (Trigger **) palloc(sizeof(Trigger *));
else
*tp = (Trigger **) repalloc (*tp, (n[TRIGGER_EVENT_DELETE] + 1) *
sizeof (Trigger *));
*tp = (Trigger **) repalloc(*tp, (n[TRIGGER_EVENT_DELETE] + 1) *
sizeof(Trigger *));
(*tp)[n[TRIGGER_EVENT_DELETE]] = trigger;
(n[TRIGGER_EVENT_DELETE])++;
}
if ( TRIGGER_FOR_UPDATE (trigger->tgtype) )
if (TRIGGER_FOR_UPDATE(trigger->tgtype))
{
tp = &(t[TRIGGER_EVENT_UPDATE]);
if ( *tp == NULL )
*tp = (Trigger **) palloc (sizeof (Trigger *));
if (*tp == NULL)
*tp = (Trigger **) palloc(sizeof(Trigger *));
else
*tp = (Trigger **) repalloc (*tp, (n[TRIGGER_EVENT_UPDATE] + 1) *
sizeof (Trigger *));
*tp = (Trigger **) repalloc(*tp, (n[TRIGGER_EVENT_UPDATE] + 1) *
sizeof(Trigger *));
(*tp)[n[TRIGGER_EVENT_UPDATE]] = trigger;
(n[TRIGGER_EVENT_UPDATE])++;
}
@ -549,7 +555,7 @@ DescribeTrigger (TriggerDesc *trigdesc, Trigger *trigger)
}
HeapTuple
ExecBRInsertTriggers (Relation rel, HeapTuple tuple)
ExecBRInsertTriggers(Relation rel, HeapTuple tuple)
{
int ntrigs = rel->trigdesc->n_before_row[TRIGGER_EVENT_INSERT];
Trigger **trigger = rel->trigdesc->tg_before_row[TRIGGER_EVENT_INSERT];
@ -557,55 +563,55 @@ ExecBRInsertTriggers (Relation rel, HeapTuple tuple)
int nargs;
int i;
CurrentTriggerData = (TriggerData *) palloc (sizeof (TriggerData));
CurrentTriggerData->tg_event = TRIGGER_EVENT_INSERT|TRIGGER_EVENT_ROW;
CurrentTriggerData = (TriggerData *) palloc(sizeof(TriggerData));
CurrentTriggerData->tg_event = TRIGGER_EVENT_INSERT | TRIGGER_EVENT_ROW;
CurrentTriggerData->tg_relation = rel;
CurrentTriggerData->tg_newtuple = NULL;
for (i = 0; i < ntrigs; i++)
{
CurrentTriggerData->tg_trigtuple = newtuple;
CurrentTriggerData->tg_trigger = trigger[i];
if ( trigger[i]->tgfunc == NULL )
fmgr_info (trigger[i]->tgfoid, &(trigger[i]->tgfunc), &nargs);
newtuple = (HeapTuple) ( (*(trigger[i]->tgfunc)) () );
if ( newtuple == NULL )
if (trigger[i]->tgfunc == NULL)
fmgr_info(trigger[i]->tgfoid, &(trigger[i]->tgfunc), &nargs);
newtuple = (HeapTuple) ((*(trigger[i]->tgfunc)) ());
if (newtuple == NULL)
break;
}
pfree (CurrentTriggerData);
pfree(CurrentTriggerData);
CurrentTriggerData = NULL;
return (newtuple);
}
void
ExecARInsertTriggers (Relation rel, HeapTuple tuple)
ExecARInsertTriggers(Relation rel, HeapTuple tuple)
{
return;
}
bool
ExecBRDeleteTriggers (Relation rel, ItemPointer tupleid)
ExecBRDeleteTriggers(Relation rel, ItemPointer tupleid)
{
return (true);
}
void
ExecARDeleteTriggers (Relation rel, ItemPointer tupleid)
ExecARDeleteTriggers(Relation rel, ItemPointer tupleid)
{
return;
}
HeapTuple
ExecBRUpdateTriggers (Relation rel, ItemPointer tupleid, HeapTuple tuple)
ExecBRUpdateTriggers(Relation rel, ItemPointer tupleid, HeapTuple tuple)
{
return (tuple);
}
void
ExecARUpdateTriggers (Relation rel, ItemPointer tupleid, HeapTuple tuple)
ExecARUpdateTriggers(Relation rel, ItemPointer tupleid, HeapTuple tuple)
{
return;

File diff suppressed because it is too large Load Diff

View File

@ -7,7 +7,7 @@
*
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/commands/view.c,v 1.8 1997/08/22 14:22:14 vadim Exp $
* $Header: /cvsroot/pgsql/src/backend/commands/view.c,v 1.9 1997/09/07 04:41:06 momjian Exp $
*
*-------------------------------------------------------------------------
*/
@ -42,24 +42,27 @@
*---------------------------------------------------------------------
*/
static void
DefineVirtualRelation(char *relname, List *tlist)
DefineVirtualRelation(char *relname, List * tlist)
{
CreateStmt createStmt;
List *attrList, *t;
List *attrList,
*t;
TargetEntry *entry;
Resdom *res;
char *resname;
char *restypename;
/*
* create a list with one entry per attribute of this relation.
* Each entry is a two element list. The first element is the
* name of the attribute (a string) and the second the name of the type
* (NOTE: a string, not a type id!).
* create a list with one entry per attribute of this relation. Each
* entry is a two element list. The first element is the name of the
* attribute (a string) and the second the name of the type (NOTE: a
* string, not a type id!).
*/
attrList = NIL;
if (tlist!=NIL) {
foreach (t, tlist ) {
if (tlist != NIL)
{
foreach(t, tlist)
{
ColumnDef *def = makeNode(ColumnDef);
TypeName *typename;
@ -79,17 +82,19 @@ DefineVirtualRelation(char *relname, List *tlist)
def->typename = typename;
def->is_not_null = false;
def->defval = (char*) NULL;
def->defval = (char *) NULL;
attrList = lappend(attrList, def);
}
} else {
elog ( WARN, "attempted to define virtual relation with no attrs");
}
else
{
elog(WARN, "attempted to define virtual relation with no attrs");
}
/*
* now create the parametesr for keys/inheritance etc.
* All of them are nil...
* now create the parametesr for keys/inheritance etc. All of them are
* nil...
*/
createStmt.relname = relname;
createStmt.tableElts = attrList;
@ -131,21 +136,22 @@ MakeRetrieveViewRuleName(char *viewName)
*/
char *buf;
buf = palloc(strlen(viewName) + 5);
sprintf(buf, "_RET%s",viewName);
sprintf(buf, "_RET%s", viewName);
return buf;
}
static RuleStmt *
FormViewRetrieveRule(char *viewName, Query *viewParse)
FormViewRetrieveRule(char *viewName, Query * viewParse)
{
RuleStmt *rule;
char *rname;
Attr *attr;
/*
* Create a RuleStmt that corresponds to the suitable
* rewrite rule args for DefineQueryRewrite();
* Create a RuleStmt that corresponds to the suitable rewrite rule
* args for DefineQueryRewrite();
*/
rule = makeNode(RuleStmt);
rname = MakeRetrieveViewRuleName(viewName);
@ -164,13 +170,15 @@ FormViewRetrieveRule(char *viewName, Query *viewParse)
}
static void
DefineViewRules(char *viewName, Query *viewParse)
DefineViewRules(char *viewName, Query * viewParse)
{
RuleStmt *retrieve_rule = NULL;
#ifdef NOTYET
RuleStmt *replace_rule = NULL;
RuleStmt *append_rule = NULL;
RuleStmt *delete_rule = NULL;
#endif
retrieve_rule =
@ -216,16 +224,17 @@ DefineViewRules(char *viewName, Query *viewParse)
*---------------------------------------------------------------
*/
static void
UpdateRangeTableOfViewParse(char *viewName, Query *viewParse)
UpdateRangeTableOfViewParse(char *viewName, Query * viewParse)
{
List *old_rt;
List *new_rt;
RangeTblEntry *rt_entry1, *rt_entry2;
RangeTblEntry *rt_entry1,
*rt_entry2;
/*
* first offset all var nodes by 2
*/
OffsetVarNodes((Node*)viewParse->targetList, 2);
OffsetVarNodes((Node *) viewParse->targetList, 2);
OffsetVarNodes(viewParse->qual, 2);
/*
@ -234,23 +243,21 @@ UpdateRangeTableOfViewParse(char *viewName, Query *viewParse)
old_rt = viewParse->rtable;
/*
* create the 2 new range table entries and form the new
* range table...
* CURRENT first, then NEW....
* create the 2 new range table entries and form the new range
* table... CURRENT first, then NEW....
*/
rt_entry1 =
addRangeTableEntry(NULL, (char*)viewName, "*CURRENT*",
addRangeTableEntry(NULL, (char *) viewName, "*CURRENT*",
FALSE, FALSE, NULL);
rt_entry2 =
addRangeTableEntry(NULL, (char*)viewName, "*NEW*",
addRangeTableEntry(NULL, (char *) viewName, "*NEW*",
FALSE, FALSE, NULL);
new_rt = lcons(rt_entry2, old_rt);
new_rt = lcons(rt_entry1, new_rt);
/*
* Now the tricky part....
* Update the range table in place... Be careful here, or
* hell breaks loooooooooooooOOOOOOOOOOOOOOOOOOSE!
* Now the tricky part.... Update the range table in place... Be
* careful here, or hell breaks loooooooooooooOOOOOOOOOOOOOOOOOOSE!
*/
viewParse->rtable = new_rt;
}
@ -268,33 +275,30 @@ UpdateRangeTableOfViewParse(char *viewName, Query *viewParse)
*-------------------------------------------------------------------
*/
void
DefineView(char *viewName, Query *viewParse)
DefineView(char *viewName, Query * viewParse)
{
List *viewTlist;
viewTlist = viewParse->targetList;
/*
* Create the "view" relation
* NOTE: if it already exists, the xaxt will be aborted.
* Create the "view" relation NOTE: if it already exists, the xaxt
* will be aborted.
*/
DefineVirtualRelation(viewName, viewTlist);
/*
* The relation we have just created is not visible
* to any other commands running with the same transaction &
* command id.
* So, increment the command id counter (but do NOT pfree any
* memory!!!!)
* The relation we have just created is not visible to any other
* commands running with the same transaction & command id. So,
* increment the command id counter (but do NOT pfree any memory!!!!)
*/
CommandCounterIncrement();
/*
* The range table of 'viewParse' does not contain entries
* for the "CURRENT" and "NEW" relations.
* So... add them!
* NOTE: we make the update in place! After this call 'viewParse'
* will never be what it used to be...
* The range table of 'viewParse' does not contain entries for the
* "CURRENT" and "NEW" relations. So... add them! NOTE: we make the
* update in place! After this call 'viewParse' will never be what it
* used to be...
*/
UpdateRangeTableOfViewParse(viewName, viewParse);
DefineViewRules(viewName, viewParse);
@ -309,11 +313,10 @@ DefineView(char *viewName, Query *viewParse)
void
RemoveView(char *viewName)
{
char* rname;
char *rname;
/*
* first remove all the "view" rules...
* Currently we only have one!
* first remove all the "view" rules... Currently we only have one!
*/
rname = MakeRetrieveViewRuleName(viewName);
RemoveRewriteRule(rname);

View File

@ -7,7 +7,7 @@
*
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/executor/execAmi.c,v 1.5 1997/08/19 21:30:51 momjian Exp $
* $Header: /cvsroot/pgsql/src/backend/executor/execAmi.c,v 1.6 1997/09/07 04:41:09 momjian Exp $
*
*-------------------------------------------------------------------------
*/
@ -43,7 +43,8 @@
#include "access/heapam.h"
#include "catalog/heap.h"
static Pointer ExecBeginScan(Relation relation, int nkeys, ScanKey skeys,
static Pointer
ExecBeginScan(Relation relation, int nkeys, ScanKey skeys,
bool isindex, ScanDirection dir, TimeQual time_range);
static Relation ExecOpenR(Oid relationOid, bool isindex);
@ -70,8 +71,8 @@ ExecOpenScanR(Oid relOid,
bool isindex,
ScanDirection dir,
TimeQual timeRange,
Relation *returnRelation, /* return */
Pointer *returnScanDesc) /* return */
Relation * returnRelation, /* return */
Pointer * returnScanDesc) /* return */
{
Relation relation;
Pointer scanDesc;
@ -107,6 +108,7 @@ static Relation
ExecOpenR(Oid relationOid, bool isindex)
{
Relation relation;
relation = (Relation) NULL;
/* ----------------
@ -114,9 +116,11 @@ ExecOpenR(Oid relationOid, bool isindex)
* on whether this is a heap relation or an index relation.
* ----------------
*/
if (isindex) {
if (isindex)
{
relation = index_open(relationOid);
} else
}
else
relation = heap_open(relationOid);
if (relation == NULL)
@ -157,12 +161,15 @@ ExecBeginScan(Relation relation,
* if you pass it true, then the scan is backward.
* ----------------
*/
if (isindex) {
if (isindex)
{
scanDesc = (Pointer) index_beginscan(relation,
false, /* see above comment */
nkeys,
skeys);
} else {
}
else
{
scanDesc = (Pointer) heap_beginscan(relation,
ScanDirectionIsBackward(dir),
time_range,
@ -188,7 +195,7 @@ ExecBeginScan(Relation relation,
* ----------------------------------------------------------------
*/
void
ExecCloseR(Plan *node)
ExecCloseR(Plan * node)
{
CommonScanState *state;
Relation relation;
@ -198,26 +205,27 @@ ExecCloseR(Plan *node)
* shut down the heap scan and close the heap relation
* ----------------
*/
switch (nodeTag(node)) {
switch (nodeTag(node))
{
case T_SeqScan:
state = ((SeqScan *)node)->scanstate;
state = ((SeqScan *) node)->scanstate;
break;
case T_IndexScan:
state = ((IndexScan *)node)->scan.scanstate;
state = ((IndexScan *) node)->scan.scanstate;
break;
case T_Material:
state = &(((Material *)node)->matstate->csstate);
state = &(((Material *) node)->matstate->csstate);
break;
case T_Sort:
state = &(((Sort *)node)->sortstate->csstate);
state = &(((Sort *) node)->sortstate->csstate);
break;
case T_Agg:
state = &(((Agg *)node)->aggstate->csstate);
state = &(((Agg *) node)->aggstate->csstate);
break;
default:
@ -239,8 +247,9 @@ ExecCloseR(Plan *node)
* of the index relations as well..
* ----------------
*/
if (nodeTag(node) == T_IndexScan) {
IndexScan *iscan= (IndexScan *)node;
if (nodeTag(node) == T_IndexScan)
{
IndexScan *iscan = (IndexScan *) node;
IndexScanState *indexstate;
int numIndices;
RelationPtr indexRelationDescs;
@ -252,7 +261,8 @@ ExecCloseR(Plan *node)
indexRelationDescs = indexstate->iss_RelationDescs;
indexScanDescs = indexstate->iss_ScanDescs;
for (i = 0; i<numIndices; i++) {
for (i = 0; i < numIndices; i++)
{
/* ----------------
* shut down each of the scans and
* close each of the index relations
@ -278,9 +288,10 @@ ExecCloseR(Plan *node)
* ----------------------------------------------------------------
*/
void
ExecReScan(Plan *node, ExprContext *exprCtxt, Plan *parent)
ExecReScan(Plan * node, ExprContext * exprCtxt, Plan * parent)
{
switch(nodeTag(node)) {
switch (nodeTag(node))
{
case T_SeqScan:
ExecSeqReScan((SeqScan *) node, exprCtxt, parent);
return;
@ -290,16 +301,18 @@ ExecReScan(Plan *node, ExprContext *exprCtxt, Plan *parent)
return;
case T_Material:
/* the first call to ExecReScan should have no effect because
/*
* the first call to ExecReScan should have no effect because
* everything is initialized properly already. the following
* calls will be handled by ExecSeqReScan() because the nodes
* below the Material node have already been materialized into
* a temp relation.
* below the Material node have already been materialized into a
* temp relation.
*/
return;
case T_Tee:
ExecTeeReScan((Tee*) node, exprCtxt, parent);
ExecTeeReScan((Tee *) node, exprCtxt, parent);
break;
default:
@ -338,9 +351,10 @@ ExecReScanR(Relation relDesc, /* LLL relDesc unused */
* ----------------------------------------------------------------
*/
void
ExecMarkPos(Plan *node)
ExecMarkPos(Plan * node)
{
switch(nodeTag(node)) {
switch (nodeTag(node))
{
case T_SeqScan:
ExecSeqMarkPos((SeqScan *) node);
break;
@ -367,9 +381,10 @@ ExecMarkPos(Plan *node)
* ----------------------------------------------------------------
*/
void
ExecRestrPos(Plan *node)
ExecRestrPos(Plan * node)
{
switch(nodeTag(node)) {
switch (nodeTag(node))
{
case T_SeqScan:
ExecSeqRestrPos((SeqScan *) node);
return;
@ -415,7 +430,8 @@ ExecCreatR(TupleDesc tupType,
relDesc = NULL;
if (relationOid == _TEMP_RELATION_ID_ ) {
if (relationOid == _TEMP_RELATION_ID_)
{
/* ----------------
* create a temporary relation
* (currently the planner always puts a _TEMP_RELATION_ID
@ -428,11 +444,17 @@ ExecCreatR(TupleDesc tupType,
sprintf(tempname, "temp_%d.%d", getpid(), tmpcnt++);
EU1_printf("ExecCreatR: attempting to create %s\n", tempname);
*/
/* heap_creatr creates a name if the argument to heap_creatr is '\0 ' */
/*
* heap_creatr creates a name if the argument to heap_creatr is
* '\0 '
*/
relDesc = heap_creatr("",
DEFAULT_SMGR,
tupType);
} else {
}
else
{
/* ----------------
* use a relation from the range table
* ----------------
@ -448,4 +470,3 @@ ExecCreatR(TupleDesc tupType,
return relDesc;
}

View File

@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/executor/Attic/execFlatten.c,v 1.2 1997/08/19 21:30:56 momjian Exp $
* $Header: /cvsroot/pgsql/src/backend/executor/Attic/execFlatten.c,v 1.3 1997/09/07 04:41:12 momjian Exp $
*
*-------------------------------------------------------------------------
*/
@ -33,33 +33,36 @@
#include "executor/execFlatten.h"
#ifdef SETS_FIXED
static bool FjoinBumpOuterNodes(TargetEntry *tlist, ExprContext *econtext,
static bool
FjoinBumpOuterNodes(TargetEntry * tlist, ExprContext * econtext,
DatumPtr results, char *nulls);
#endif
Datum
ExecEvalIter(Iter *iterNode,
ExprContext *econtext,
bool *resultIsNull,
bool *iterIsDone)
ExecEvalIter(Iter * iterNode,
ExprContext * econtext,
bool * resultIsNull,
bool * iterIsDone)
{
Node *expression;
expression = iterNode->iterexpr;
/*
* Really Iter nodes are only needed for C functions, postquel function
* by their nature return 1 result at a time. For now we are only worrying
* about postquel functions, c functions will come later.
* Really Iter nodes are only needed for C functions, postquel
* function by their nature return 1 result at a time. For now we are
* only worrying about postquel functions, c functions will come
* later.
*/
return ExecEvalExpr(expression, econtext, resultIsNull, iterIsDone);
}
void
ExecEvalFjoin(TargetEntry *tlist,
ExprContext *econtext,
bool *isNullVect,
bool *fj_isDone)
ExecEvalFjoin(TargetEntry * tlist,
ExprContext * econtext,
bool * isNullVect,
bool * fj_isDone)
{
#ifdef SETS_FIXED
@ -71,13 +74,16 @@ ExecEvalFjoin(TargetEntry *tlist,
DatumPtr resVect = fjNode->fj_results;
BoolPtr alwaysDone = fjNode->fj_alwaysDone;
if (fj_isDone) *fj_isDone = false;
if (fj_isDone)
*fj_isDone = false;
/*
* For the next tuple produced by the plan, we need to re-initialize
* the Fjoin node.
*/
if (!fjNode->fj_initialized)
{
/*
* Initialize all of the Outer nodes
*/
@ -86,7 +92,7 @@ ExecEvalFjoin(TargetEntry *tlist,
{
TargetEntry *tle = lfirst(tlistP);
resVect[curNode] = ExecEvalIter((Iter*)tle->expr,
resVect[curNode] = ExecEvalIter((Iter *) tle->expr,
econtext,
&isNullVect[curNode],
&isDone);
@ -101,7 +107,7 @@ ExecEvalFjoin(TargetEntry *tlist,
/*
* Initialize the inner node
*/
resVect[0] = ExecEvalIter((Iter*)fjNode->fj_innerNode->expr,
resVect[0] = ExecEvalIter((Iter *) fjNode->fj_innerNode->expr,
econtext,
&isNullVect[0],
&isDone);
@ -123,17 +129,18 @@ ExecEvalFjoin(TargetEntry *tlist,
}
else
{
/*
* If we're already initialized, all we need to do is get the
* next inner result and pair it up with the existing outer node
* result vector. Watch out for the degenerate case, where the
* inner node never returns results.
* If we're already initialized, all we need to do is get the next
* inner result and pair it up with the existing outer node result
* vector. Watch out for the degenerate case, where the inner
* node never returns results.
*/
/*
* Fill in nulls for every function that is always done.
*/
for (curNode=fjNode->fj_nNodes-1; curNode >= 0; curNode--)
for (curNode = fjNode->fj_nNodes - 1; curNode >= 0; curNode--)
isNullVect[curNode] = alwaysDone[curNode];
if (alwaysDone[0] == true)
@ -145,7 +152,7 @@ ExecEvalFjoin(TargetEntry *tlist,
return;
}
else
resVect[0] = ExecEvalIter((Iter*)fjNode->fj_innerNode->expr,
resVect[0] = ExecEvalIter((Iter *) fjNode->fj_innerNode->expr,
econtext,
&isNullVect[0],
&isDone);
@ -163,7 +170,7 @@ ExecEvalFjoin(TargetEntry *tlist,
if (*fj_isDone)
return;
resVect[0] = ExecEvalIter((Iter*)fjNode->fj_innerNode->expr,
resVect[0] = ExecEvalIter((Iter *) fjNode->fj_innerNode->expr,
econtext,
&isNullVect[0],
&isDone);
@ -175,8 +182,8 @@ ExecEvalFjoin(TargetEntry *tlist,
#ifdef SETS_FIXED
static bool
FjoinBumpOuterNodes(TargetEntry *tlist,
ExprContext *econtext,
FjoinBumpOuterNodes(TargetEntry * tlist,
ExprContext * econtext,
DatumPtr results,
char *nulls)
{
@ -199,7 +206,7 @@ FjoinBumpOuterNodes(TargetEntry *tlist,
if (alwaysDone[curNode] == true)
nulls[curNode] = 'n';
else
results[curNode] = ExecEvalIter((Iter)tle->expr,
results[curNode] = ExecEvalIter((Iter) tle->expr,
econtext,
&nulls[curNode],
&funcIsDone);
@ -208,9 +215,9 @@ FjoinBumpOuterNodes(TargetEntry *tlist,
}
/*
* If every function is done, then we are done flattening.
* Mark the Fjoin node unitialized, it is time to get the
* next tuple from the plan and redo all of the flattening.
* If every function is done, then we are done flattening. Mark the
* Fjoin node unitialized, it is time to get the next tuple from the
* plan and redo all of the flattening.
*/
if (funcIsDone)
{
@ -223,12 +230,12 @@ FjoinBumpOuterNodes(TargetEntry *tlist,
* before it. As usual watch out for functions that are always done.
*/
trailNode = 1;
while (trailNode != curNode-1)
while (trailNode != curNode - 1)
{
TargetEntry *tle = lfirst(trailers);
if (alwaysDone[trailNode] != true)
results[trailNode] = ExecEvalIter((Iter)tle->expr,
results[trailNode] = ExecEvalIter((Iter) tle->expr,
econtext,
&nulls[trailNode],
&funcIsDone);
@ -237,4 +244,5 @@ FjoinBumpOuterNodes(TargetEntry *tlist,
}
return false;
}
#endif

View File

@ -7,7 +7,7 @@
*
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/executor/execJunk.c,v 1.5 1997/08/26 23:31:37 momjian Exp $
* $Header: /cvsroot/pgsql/src/backend/executor/execJunk.c,v 1.6 1997/09/07 04:41:14 momjian Exp $
*
*-------------------------------------------------------------------------
*/
@ -61,15 +61,18 @@
*-------------------------------------------------------------------------
*/
JunkFilter *
ExecInitJunkFilter(List *targetList)
ExecInitJunkFilter(List * targetList)
{
JunkFilter *junkfilter;
List *cleanTargetList;
int len, cleanLength;
TupleDesc tupType, cleanTupType;
int len,
cleanLength;
TupleDesc tupType,
cleanTupType;
List *t;
TargetEntry *tle;
Resdom *resdom, *cleanResdom;
Resdom *resdom,
*cleanResdom;
int resjunk;
AttrNumber cleanResno;
AttrNumber *cleanMap;
@ -86,19 +89,25 @@ ExecInitJunkFilter(List *targetList)
cleanTargetList = NIL;
cleanResno = 1;
foreach (t, targetList) {
foreach(t, targetList)
{
TargetEntry *rtarget = lfirst(t);
if (rtarget->resdom != NULL) {
if (rtarget->resdom != NULL)
{
resdom = rtarget->resdom;
expr = rtarget->expr;
resjunk = resdom->resjunk;
if (resjunk == 0) {
if (resjunk == 0)
{
/*
* make a copy of the resdom node, changing its resno.
*/
cleanResdom = (Resdom *) copyObject(resdom);
cleanResdom->resno = cleanResno;
cleanResno ++;
cleanResno++;
/*
* create a new target list entry
*/
@ -108,15 +117,16 @@ ExecInitJunkFilter(List *targetList)
cleanTargetList = lappend(cleanTargetList, tle);
}
}
else {
else
{
#ifdef SETS_FIXED
List *fjListP;
Fjoin *cleanFjoin;
List *cleanFjList;
List *fjList = lfirst(t);
Fjoin *fjNode = (Fjoin *)tl_node(fjList);
Fjoin *fjNode = (Fjoin *) tl_node(fjList);
cleanFjoin = (Fjoin)copyObject((Node) fjNode);
cleanFjoin = (Fjoin) copyObject((Node) fjNode);
cleanFjList = lcons(cleanFjoin, NIL);
resdom = (Resdom) lfirst(get_fj_innerNode(fjNode));
@ -127,14 +137,16 @@ ExecInitJunkFilter(List *targetList)
tle = (List) MakeTLE(cleanResdom, (Expr) expr);
set_fj_innerNode(cleanFjoin, tle);
foreach(fjListP, lnext(fjList)) {
foreach(fjListP, lnext(fjList))
{
TargetEntry *tle = lfirst(fjListP);
resdom = tle->resdom;
expr = tle->expr;
cleanResdom = (Resdom*) copyObject((Node) resdom);
cleanResdom = (Resdom *) copyObject((Node) resdom);
cleanResno++;
cleanResdom->Resno = cleanResno;
/*
* create a new target list entry
*/
@ -170,45 +182,55 @@ ExecInitJunkFilter(List *targetList)
* attribute of the "original" tuple.
* ---------------------
*/
if (cleanLength > 0) {
if (cleanLength > 0)
{
size = cleanLength * sizeof(AttrNumber);
cleanMap = (AttrNumber*) palloc(size);
cleanMap = (AttrNumber *) palloc(size);
cleanResno = 1;
foreach (t, targetList) {
foreach(t, targetList)
{
TargetEntry *tle = lfirst(t);
if (tle->resdom != NULL) {
if (tle->resdom != NULL)
{
resdom = tle->resdom;
expr = tle->expr;
resjunk = resdom->resjunk;
if (resjunk == 0) {
cleanMap[cleanResno-1] = resdom->resno;
cleanResno ++;
if (resjunk == 0)
{
cleanMap[cleanResno - 1] = resdom->resno;
cleanResno++;
}
} else {
}
else
{
#ifdef SETS_FIXED
List fjListP;
List fjList = lfirst(t);
Fjoin fjNode = (Fjoin)lfirst(fjList);
Fjoin fjNode = (Fjoin) lfirst(fjList);
/* what the hell is this????? */
resdom = (Resdom) lfirst(get_fj_innerNode(fjNode));
#endif
cleanMap[cleanResno-1] = tle->resdom->resno;
cleanMap[cleanResno - 1] = tle->resdom->resno;
cleanResno++;
#ifdef SETS_FIXED
foreach(fjListP, lnext(fjList)) {
foreach(fjListP, lnext(fjList))
{
TargetEntry *tle = lfirst(fjListP);
resdom = tle->resdom;
cleanMap[cleanResno-1] = resdom->resno;
cleanMap[cleanResno - 1] = resdom->resno;
cleanResno++;
}
#endif
}
}
} else {
}
else
{
cleanMap = NULL;
}
@ -226,7 +248,7 @@ ExecInitJunkFilter(List *targetList)
junkfilter->jf_cleanTupType = cleanTupType;
junkfilter->jf_cleanMap = cleanMap;
return(junkfilter);
return (junkfilter);
}
@ -242,11 +264,11 @@ ExecInitJunkFilter(List *targetList)
*-------------------------------------------------------------------------
*/
bool
ExecGetJunkAttribute(JunkFilter *junkfilter,
TupleTableSlot *slot,
ExecGetJunkAttribute(JunkFilter * junkfilter,
TupleTableSlot * slot,
char *attrName,
Datum *value,
bool *isNull)
Datum * value,
bool * isNull)
{
List *targetList;
List *t;
@ -265,21 +287,25 @@ ExecGetJunkAttribute(JunkFilter *junkfilter,
resno = InvalidAttrNumber;
targetList = junkfilter->jf_targetList;
foreach (t, targetList) {
foreach(t, targetList)
{
TargetEntry *tle = lfirst(t);
resdom = tle->resdom;
resname = resdom->resname;
resjunk = resdom->resjunk;
if (resjunk != 0 && (strcmp(resname, attrName) == 0)) {
if (resjunk != 0 && (strcmp(resname, attrName) == 0))
{
/* We found it ! */
resno = resdom->resno;
break;
}
}
if (resno == InvalidAttrNumber) {
if (resno == InvalidAttrNumber)
{
/* Ooops! We couldn't find this attribute... */
return(false);
return (false);
}
/* ---------------------
@ -302,7 +328,7 @@ ExecGetJunkAttribute(JunkFilter *junkfilter,
*-------------------------------------------------------------------------
*/
HeapTuple
ExecRemoveJunk(JunkFilter *junkfilter, TupleTableSlot *slot)
ExecRemoveJunk(JunkFilter * junkfilter, TupleTableSlot * slot)
{
HeapTuple tuple;
HeapTuple cleanTuple;
@ -345,13 +371,16 @@ ExecRemoveJunk(JunkFilter *junkfilter, TupleTableSlot *slot)
* for large tuples we just use palloc.
* ---------------------
*/
if (cleanLength > 64) {
if (cleanLength > 64)
{
size = cleanLength * sizeof(Datum);
values = (Datum *) palloc(size);
size = cleanLength * sizeof(char);
nulls = (char *) palloc(size);
} else {
}
else
{
values = values_array;
nulls = nulls_array;
}
@ -360,7 +389,8 @@ ExecRemoveJunk(JunkFilter *junkfilter, TupleTableSlot *slot)
* Exctract one by one all the values of the "clean" tuple.
* ---------------------
*/
for (i=0; i<cleanLength; i++) {
for (i = 0; i < cleanLength; i++)
{
Datum d = (Datum)
heap_getattr(tuple, InvalidBuffer, cleanMap[i], tupType, &isNull);
@ -385,11 +415,11 @@ ExecRemoveJunk(JunkFilter *junkfilter, TupleTableSlot *slot)
* and return the new tuple.
* ---------------------
*/
if (cleanLength > 64) {
if (cleanLength > 64)
{
pfree(values);
pfree(nulls);
}
return(cleanTuple);
return (cleanTuple);
}

View File

@ -26,7 +26,7 @@
*
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/executor/execMain.c,v 1.22 1997/09/04 13:22:36 vadim Exp $
* $Header: /cvsroot/pgsql/src/backend/executor/execMain.c,v 1.23 1997/09/07 04:41:18 momjian Exp $
*
*-------------------------------------------------------------------------
*/
@ -56,28 +56,35 @@
/* decls for local routines only used within this module */
static void ExecCheckPerms(CmdType operation, int resultRelation, List *rangeTable,
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,
Query *parseTree, CmdType operation,
static void
ExecCheckPerms(CmdType operation, int resultRelation, List * rangeTable,
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,
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,
EState *estate);
static void ExecDelete(TupleTableSlot *slot, ItemPointer tupleid,
EState *estate);
static void ExecReplace(TupleTableSlot *slot, ItemPointer tupleid,
EState *estate, Query *parseTree);
void (*printfunc) ());
static void ExecRetrieve(TupleTableSlot * slot, void (*printfunc) (),
EState * estate);
static void
ExecAppend(TupleTableSlot * slot, ItemPointer tupleid,
EState * estate);
static void
ExecDelete(TupleTableSlot * slot, ItemPointer tupleid,
EState * estate);
static void
ExecReplace(TupleTableSlot * slot, ItemPointer tupleid,
EState * estate, Query * parseTree);
/* end of local decls */
#ifdef QUERY_LIMIT
static int queryLimit = ALL_TUPLES;
#undef ALL_TUPLES
#define ALL_TUPLES queryLimit
@ -87,6 +94,7 @@ ExecutorLimit(int limit)
{
return queryLimit = limit;
}
#endif
#endif
@ -102,25 +110,25 @@ ExecutorLimit(int limit)
* ----------------------------------------------------------------
*/
TupleDesc
ExecutorStart(QueryDesc *queryDesc, EState *estate)
ExecutorStart(QueryDesc * queryDesc, EState * estate)
{
TupleDesc result;
/* sanity checks */
Assert(queryDesc!=NULL);
Assert(queryDesc != NULL);
result = InitPlan(queryDesc->operation,
queryDesc->parsetree,
queryDesc->plantree,
estate);
/* reset buffer refcount. the current refcounts
* are saved and will be restored when ExecutorEnd is called
/*
* reset buffer refcount. the current refcounts are saved and will be
* restored when ExecutorEnd is called
*
* this makes sure that when ExecutorRun's are
* called recursively as for postquel functions,
* the buffers pinned by one ExecutorRun will not be
* unpinned by another ExecutorRun.
* this makes sure that when ExecutorRun's are called recursively as for
* postquel functions, the buffers pinned by one ExecutorRun will not
* be unpinned by another ExecutorRun.
*/
BufferRefCountReset(estate->es_refcount);
@ -146,21 +154,21 @@ ExecutorStart(QueryDesc *queryDesc, EState *estate)
*
* ----------------------------------------------------------------
*/
TupleTableSlot*
ExecutorRun(QueryDesc *queryDesc, EState *estate, int feature, int count)
TupleTableSlot *
ExecutorRun(QueryDesc * queryDesc, EState * estate, int feature, int count)
{
CmdType operation;
Query *parseTree;
Plan *plan;
TupleTableSlot *result;
CommandDest dest;
void (*destination)();
void (*destination) ();
/* ----------------
* sanity checks
* ----------------
*/
Assert(queryDesc!=NULL);
Assert(queryDesc != NULL);
/* ----------------
* extract information from the query descriptor
@ -171,31 +179,37 @@ ExecutorRun(QueryDesc *queryDesc, EState *estate, int feature, int count)
parseTree = queryDesc->parsetree;
plan = queryDesc->plantree;
dest = queryDesc->dest;
destination = (void (*)()) DestToFunction(dest);
destination = (void (*) ()) DestToFunction(dest);
estate->es_processed = 0;
estate->es_lastoid = InvalidOid;
#if 0
/*
* It doesn't work in common case (i.g. if function has a aggregate).
* Now we store parameter values before ExecutorStart. - vadim 01/22/97
* Now we store parameter values before ExecutorStart. - vadim
* 01/22/97
*/
#ifdef INDEXSCAN_PATCH
/*
* If the plan is an index scan and some of the scan key are
* function arguments rescan the indices after the parameter
* values have been stored in the execution state. DZ - 27-8-1996
* If the plan is an index scan and some of the scan key are function
* arguments rescan the indices after the parameter values have been
* stored in the execution state. DZ - 27-8-1996
*/
if ((nodeTag(plan) == T_IndexScan) &&
(((IndexScan *)plan)->indxstate->iss_RuntimeKeyInfo != NULL)) {
(((IndexScan *) plan)->indxstate->iss_RuntimeKeyInfo != NULL))
{
ExprContext *econtext;
econtext = ((IndexScan *)plan)->scan.scanstate->cstate.cs_ExprContext;
ExecIndexReScan((IndexScan *)plan, econtext, plan);
econtext = ((IndexScan *) plan)->scan.scanstate->cstate.cs_ExprContext;
ExecIndexReScan((IndexScan *) plan, econtext, plan);
}
#endif
#endif
switch(feature) {
switch (feature)
{
case EXEC_RUN:
result = ExecutePlan(estate,
@ -265,10 +279,10 @@ ExecutorRun(QueryDesc *queryDesc, EState *estate, int feature, int count)
* ----------------------------------------------------------------
*/
void
ExecutorEnd(QueryDesc *queryDesc, EState *estate)
ExecutorEnd(QueryDesc * queryDesc, EState * estate)
{
/* sanity checks */
Assert(queryDesc!=NULL);
Assert(queryDesc != NULL);
EndPlan(queryDesc->plantree, estate);
@ -286,15 +300,17 @@ ExecutorEnd(QueryDesc *queryDesc, EState *estate)
static void
ExecCheckPerms(CmdType operation,
int resultRelation,
List *rangeTable,
Query *parseTree)
List * rangeTable,
Query * parseTree)
{
int i = 1;
Oid relid;
HeapTuple htp;
List *lp;
List *qvars, *tvars;
int32 ok = 1, aclcheck_result = -1;
List *qvars,
*tvars;
int32 ok = 1,
aclcheck_result = -1;
char *opstr;
NameData rname;
char *userName;
@ -303,31 +319,35 @@ ExecCheckPerms(CmdType operation,
userName = GetPgUserName();
foreach (lp, rangeTable) {
foreach(lp, rangeTable)
{
RangeTblEntry *rte = lfirst(lp);
relid = rte->relid;
htp = SearchSysCacheTuple(RELOID,
ObjectIdGetDatum(relid),
0,0,0);
0, 0, 0);
if (!HeapTupleIsValid(htp))
elog(WARN, "ExecCheckPerms: bogus RT relid: %d",
relid);
strNcpy(rname.data,
((Form_pg_class) GETSTRUCT(htp))->relname.data,
NAMEDATALEN-1);
if (i == resultRelation) { /* this is the result relation */
NAMEDATALEN - 1);
if (i == resultRelation)
{ /* this is the result relation */
qvars = pull_varnos(parseTree->qual);
tvars = pull_varnos((Node*)parseTree->targetList);
tvars = pull_varnos((Node *) parseTree->targetList);
if (intMember(resultRelation, qvars) ||
intMember(resultRelation, tvars)) {
intMember(resultRelation, tvars))
{
/* result relation is scanned */
ok = ((aclcheck_result = CHECK(ACL_RD)) == ACLCHECK_OK);
opstr = "read";
if (!ok)
break;
}
switch (operation) {
switch (operation)
{
case CMD_INSERT:
ok = ((aclcheck_result = CHECK(ACL_AP)) == ACLCHECK_OK) ||
((aclcheck_result = CHECK(ACL_WR)) == ACLCHECK_OK);
@ -343,7 +363,9 @@ ExecCheckPerms(CmdType operation,
elog(WARN, "ExecCheckPerms: bogus operation %d",
operation);
}
} else {
}
else
{
/* XXX NOTIFY?? */
ok = ((aclcheck_result = CHECK(ACL_RD)) == ACLCHECK_OK);
opstr = "read";
@ -352,7 +374,8 @@ ExecCheckPerms(CmdType operation,
break;
++i;
}
if (!ok) {
if (!ok)
{
elog(WARN, "%s: %s", rname.data, aclcheck_error_strings[aclcheck_result]);
}
}
@ -366,7 +389,7 @@ ExecCheckPerms(CmdType operation,
* ----------------------------------------------------------------
*/
static TupleDesc
InitPlan(CmdType operation, Query *parseTree, Plan *plan, EState *estate)
InitPlan(CmdType operation, Query * parseTree, Plan * plan, EState * estate)
{
List *rangeTable;
int resultRelation;
@ -403,7 +426,8 @@ InitPlan(CmdType operation, Query *parseTree, Plan *plan, EState *estate)
* ----------------
*/
if (resultRelation != 0 && operation != CMD_SELECT) {
if (resultRelation != 0 && operation != CMD_SELECT)
{
/* ----------------
* if we have a result relation, open it and
@ -421,15 +445,17 @@ InitPlan(CmdType operation, Query *parseTree, Plan *plan, EState *estate)
resultRelationOid = rtentry->relid;
resultRelationDesc = heap_open(resultRelationOid);
if ( resultRelationDesc->rd_rel->relkind == RELKIND_SEQUENCE )
elog (WARN, "You can't change sequence relation %s",
if (resultRelationDesc->rd_rel->relkind == RELKIND_SEQUENCE)
elog(WARN, "You can't change sequence relation %s",
resultRelationDesc->rd_rel->relname.data);
/* Write-lock the result relation right away: if the relation
is used in a subsequent scan, we won't have to elevate the
read-lock set by heap_beginscan to a write-lock (needed by
heap_insert, heap_delete and heap_replace).
This will hopefully prevent some deadlocks. - 01/24/94 */
/*
* Write-lock the result relation right away: if the relation is
* used in a subsequent scan, we won't have to elevate the
* read-lock set by heap_beginscan to a write-lock (needed by
* heap_insert, heap_delete and heap_replace). This will hopefully
* prevent some deadlocks. - 01/24/94
*/
RelationSetLockForWrite(resultRelationDesc);
resultRelationInfo = makeNode(RelationInfo);
@ -447,7 +473,9 @@ InitPlan(CmdType operation, Query *parseTree, Plan *plan, EState *estate)
ExecOpenIndices(resultRelationOid, resultRelationInfo);
estate->es_result_relation_info = resultRelationInfo;
} else {
}
else
{
/* ----------------
* if no result relation, then set state appropriately
* ----------------
@ -465,7 +493,7 @@ InitPlan(CmdType operation, Query *parseTree, Plan *plan, EState *estate)
*/
{
int nSlots = ExecCountSlotsNode(plan);
TupleTable tupleTable = ExecCreateTupleTable(nSlots+10); /* why add ten? - jolly */
TupleTable tupleTable = ExecCreateTupleTable(nSlots + 10); /* why add ten? - jolly */
estate->es_tupleTable = tupleTable;
}
@ -499,11 +527,14 @@ InitPlan(CmdType operation, Query *parseTree, Plan *plan, EState *estate)
* ----------------
*/
if (operation == CMD_UPDATE || operation == CMD_DELETE ||
operation == CMD_INSERT) {
operation == CMD_INSERT)
{
JunkFilter *j = (JunkFilter *) ExecInitJunkFilter(targetList);
JunkFilter *j = (JunkFilter*) ExecInitJunkFilter(targetList);
estate->es_junkFilter = j;
} else
}
else
estate->es_junkFilter = NULL;
/* ----------------
@ -512,17 +543,21 @@ InitPlan(CmdType operation, Query *parseTree, Plan *plan, EState *estate)
*/
intoRelationDesc = (Relation) NULL;
if (operation == CMD_SELECT) {
if (operation == CMD_SELECT)
{
char *intoName;
char archiveMode;
Oid intoRelationId;
TupleDesc tupdesc;
if (!parseTree->isPortal) {
if (!parseTree->isPortal)
{
/*
* a select into table
*/
if (parseTree->into != NULL) {
if (parseTree->into != NULL)
{
/* ----------------
* create the "into" relation
*
@ -537,7 +572,7 @@ InitPlan(CmdType operation, Query *parseTree, Plan *plan, EState *estate)
/*
* have to copy tupType to get rid of constraints
*/
tupdesc = CreateTupleDescCopy (tupType);
tupdesc = CreateTupleDescCopy(tupType);
/* fixup to prevent zero-length columns in create */
setVarAttrLenForCreateTable(tupdesc, targetList, rangeTable);
@ -550,7 +585,7 @@ InitPlan(CmdType operation, Query *parseTree, Plan *plan, EState *estate)
#ifdef NOT_USED /* it's copy ... */
resetVarAttrLenForCreateTable(tupdesc);
#endif
FreeTupleDesc (tupdesc);
FreeTupleDesc(tupdesc);
/* ----------------
* XXX rather than having to call setheapoverride(true)
@ -589,7 +624,7 @@ InitPlan(CmdType operation, Query *parseTree, Plan *plan, EState *estate)
* ----------------------------------------------------------------
*/
static void
EndPlan(Plan *plan, EState *estate)
EndPlan(Plan * plan, EState * estate)
{
RelationInfo *resultRelationInfo;
Relation intoRelationDesc;
@ -613,7 +648,8 @@ EndPlan(Plan *plan, EState *estate)
*/
{
TupleTable tupleTable = (TupleTable) estate->es_tupleTable;
ExecDestroyTupleTable(tupleTable,true); /* was missing last arg */
ExecDestroyTupleTable(tupleTable, true); /* was missing last arg */
estate->es_tupleTable = NULL;
}
@ -621,7 +657,8 @@ EndPlan(Plan *plan, EState *estate)
* close the result relations if necessary
* ----------------
*/
if (resultRelationInfo != NULL) {
if (resultRelationInfo != NULL)
{
Relation resultRelationDesc;
resultRelationDesc = resultRelationInfo->ri_RelationDesc;
@ -638,7 +675,8 @@ EndPlan(Plan *plan, EState *estate)
* close the "into" relation if necessary
* ----------------
*/
if (intoRelationDesc != NULL) {
if (intoRelationDesc != NULL)
{
heap_close(intoRelationDesc);
}
}
@ -660,13 +698,13 @@ EndPlan(Plan *plan, EState *estate)
user can see it*/
static TupleTableSlot *
ExecutePlan(EState *estate,
Plan *plan,
Query *parseTree,
ExecutePlan(EState * estate,
Plan * plan,
Query * parseTree,
CmdType operation,
int numberTuples,
ScanDirection direction,
void (*printfunc)())
void (*printfunc) ())
{
JunkFilter *junkfilter;
@ -696,14 +734,16 @@ ExecutePlan(EState *estate,
* ----------------
*/
for(;;) {
if (operation != CMD_NOTIFY) {
for (;;)
{
if (operation != CMD_NOTIFY)
{
/* ----------------
* Execute the plan and obtain a tuple
* ----------------
*/
/* at the top level, the parent of a plan (2nd arg) is itself */
slot = ExecProcNode(plan,plan);
slot = ExecProcNode(plan, plan);
/* ----------------
* if the tuple is null, then we assume
@ -711,7 +751,8 @@ ExecutePlan(EState *estate,
* we just return null...
* ----------------
*/
if (TupIsNull(slot)) {
if (TupIsNull(slot))
{
result = NULL;
break;
}
@ -727,8 +768,10 @@ ExecutePlan(EState *estate,
* Also, extract all the junk ifnormation we need.
* ----------------
*/
if ((junkfilter = estate->es_junkFilter) != (JunkFilter*)NULL) {
if ((junkfilter = estate->es_junkFilter) != (JunkFilter *) NULL)
{
Datum datum;
/* NameData attrName; */
HeapTuple newTuple;
bool isNull;
@ -737,19 +780,21 @@ ExecutePlan(EState *estate,
* extract the 'ctid' junk attribute.
* ---------------
*/
if (operation == CMD_UPDATE || operation == CMD_DELETE) {
if (! ExecGetJunkAttribute(junkfilter,
if (operation == CMD_UPDATE || operation == CMD_DELETE)
{
if (!ExecGetJunkAttribute(junkfilter,
slot,
"ctid",
&datum,
&isNull))
elog(WARN,"ExecutePlan: NO (junk) `ctid' was found!");
elog(WARN, "ExecutePlan: NO (junk) `ctid' was found!");
if (isNull)
elog(WARN,"ExecutePlan: (junk) `ctid' is NULL!");
elog(WARN, "ExecutePlan: (junk) `ctid' is NULL!");
tupleid = (ItemPointer) DatumGetPointer(datum);
tuple_ctid = *tupleid; /* make sure we don't free the ctid!! */
tuple_ctid = *tupleid; /* make sure we don't free the
* ctid!! */
tupleid = &tuple_ctid;
}
@ -762,7 +807,8 @@ ExecutePlan(EState *estate,
slot = ExecStoreTuple(newTuple, /* tuple to store */
slot, /* destination slot */
InvalidBuffer,/* this tuple has no buffer */
InvalidBuffer, /* this tuple has no
* buffer */
true); /* tuple should be pfreed */
} /* if (junkfilter... */
@ -774,7 +820,8 @@ ExecutePlan(EState *estate,
* ----------------
*/
switch(operation) {
switch (operation)
{
case CMD_SELECT:
ExecRetrieve(slot, /* slot containing tuple */
printfunc, /* print function */
@ -797,18 +844,21 @@ ExecutePlan(EState *estate,
result = NULL;
break;
/* Total hack. I'm ignoring any accessor functions for
Relation, RelationTupleForm, NameData.
Assuming that NameData.data has offset 0.
/*
* Total hack. I'm ignoring any accessor functions for
* Relation, RelationTupleForm, NameData. Assuming that
* NameData.data has offset 0.
*/
case CMD_NOTIFY: {
case CMD_NOTIFY:
{
RelationInfo *rInfo = estate->es_result_relation_info;
Relation rDesc = rInfo->ri_RelationDesc;
Async_Notify(rDesc->rd_rel->relname.data);
result = NULL;
current_tuple_count = 0;
numberTuples = 1;
elog(DEBUG, "ExecNotify %s",&rDesc->rd_rel->relname);
elog(DEBUG, "ExecNotify %s", &rDesc->rd_rel->relname);
}
break;
@ -847,9 +897,9 @@ ExecutePlan(EState *estate,
* ----------------------------------------------------------------
*/
static void
ExecRetrieve(TupleTableSlot *slot,
void (*printfunc)(),
EState *estate)
ExecRetrieve(TupleTableSlot * slot,
void (*printfunc) (),
EState * estate)
{
HeapTuple tuple;
TupleDesc attrtype;
@ -865,9 +915,9 @@ ExecRetrieve(TupleTableSlot *slot,
* insert the tuple into the "into relation"
* ----------------
*/
if ( estate->es_into_relation_descriptor != NULL )
if (estate->es_into_relation_descriptor != NULL)
{
heap_insert (estate->es_into_relation_descriptor, tuple);
heap_insert(estate->es_into_relation_descriptor, tuple);
IncrAppended();
}
@ -875,7 +925,7 @@ ExecRetrieve(TupleTableSlot *slot,
* send the tuple to the front end (or the screen)
* ----------------
*/
(*printfunc)(tuple, attrtype);
(*printfunc) (tuple, attrtype);
IncrRetrieved();
(estate->es_processed)++;
}
@ -890,9 +940,9 @@ ExecRetrieve(TupleTableSlot *slot,
*/
static void
ExecAppend(TupleTableSlot *slot,
ExecAppend(TupleTableSlot * slot,
ItemPointer tupleid,
EState *estate)
EState * estate)
{
HeapTuple tuple;
RelationInfo *resultRelationInfo;
@ -920,20 +970,20 @@ ExecAppend(TupleTableSlot *slot,
*/
/* BEFORE ROW INSERT Triggers */
if ( resultRelationDesc->trigdesc &&
resultRelationDesc->trigdesc->n_before_row[TRIGGER_EVENT_INSERT] > 0 )
if (resultRelationDesc->trigdesc &&
resultRelationDesc->trigdesc->n_before_row[TRIGGER_EVENT_INSERT] > 0)
{
HeapTuple newtuple;
newtuple = ExecBRInsertTriggers (resultRelationDesc, tuple);
newtuple = ExecBRInsertTriggers(resultRelationDesc, tuple);
if ( newtuple == NULL ) /* "do nothing" */
if (newtuple == NULL) /* "do nothing" */
return;
if ( newtuple != tuple ) /* modified by Trigger(s) */
if (newtuple != tuple) /* modified by Trigger(s) */
{
Assert ( slot->ttc_shouldFree );
pfree (tuple);
Assert(slot->ttc_shouldFree);
pfree(tuple);
slot->val = tuple = newtuple;
}
}
@ -943,16 +993,16 @@ ExecAppend(TupleTableSlot *slot,
* ----------------
*/
if ( resultRelationDesc->rd_att->constr )
if (resultRelationDesc->rd_att->constr)
{
HeapTuple newtuple;
newtuple = ExecConstraints ("ExecAppend", resultRelationDesc, tuple);
newtuple = ExecConstraints("ExecAppend", resultRelationDesc, tuple);
if ( newtuple != tuple ) /* modified by DEFAULT */
if (newtuple != tuple) /* modified by DEFAULT */
{
Assert ( slot->ttc_shouldFree );
pfree (tuple);
Assert(slot->ttc_shouldFree);
pfree(tuple);
slot->val = tuple = newtuple;
}
}
@ -974,16 +1024,17 @@ ExecAppend(TupleTableSlot *slot,
* ----------------
*/
numIndices = resultRelationInfo->ri_NumIndices;
if (numIndices > 0) {
if (numIndices > 0)
{
ExecInsertIndexTuples(slot, &(tuple->t_ctid), estate, false);
}
(estate->es_processed)++;
estate->es_lastoid = newId;
/* AFTER ROW INSERT Triggers */
if ( resultRelationDesc->trigdesc &&
resultRelationDesc->trigdesc->n_after_row[TRIGGER_EVENT_INSERT] > 0 )
ExecARInsertTriggers (resultRelationDesc, tuple);
if (resultRelationDesc->trigdesc &&
resultRelationDesc->trigdesc->n_after_row[TRIGGER_EVENT_INSERT] > 0)
ExecARInsertTriggers(resultRelationDesc, tuple);
}
/* ----------------------------------------------------------------
@ -994,9 +1045,9 @@ ExecAppend(TupleTableSlot *slot,
* ----------------------------------------------------------------
*/
static void
ExecDelete(TupleTableSlot *slot,
ExecDelete(TupleTableSlot * slot,
ItemPointer tupleid,
EState *estate)
EState * estate)
{
RelationInfo *resultRelationInfo;
Relation resultRelationDesc;
@ -1009,14 +1060,14 @@ ExecDelete(TupleTableSlot *slot,
resultRelationDesc = resultRelationInfo->ri_RelationDesc;
/* BEFORE ROW DELETE Triggers */
if ( resultRelationDesc->trigdesc &&
resultRelationDesc->trigdesc->n_before_row[TRIGGER_EVENT_DELETE] > 0 )
if (resultRelationDesc->trigdesc &&
resultRelationDesc->trigdesc->n_before_row[TRIGGER_EVENT_DELETE] > 0)
{
bool dodelete;
dodelete = ExecBRDeleteTriggers (resultRelationDesc, tupleid);
dodelete = ExecBRDeleteTriggers(resultRelationDesc, tupleid);
if ( !dodelete ) /* "do nothing" */
if (!dodelete) /* "do nothing" */
return;
}
@ -1024,8 +1075,8 @@ ExecDelete(TupleTableSlot *slot,
* delete the tuple
* ----------------
*/
if ( heap_delete(resultRelationDesc, /* relation desc */
tupleid) ) /* item pointer to tuple */
if (heap_delete(resultRelationDesc, /* relation desc */
tupleid)) /* item pointer to tuple */
return;
IncrDeleted();
@ -1044,9 +1095,9 @@ ExecDelete(TupleTableSlot *slot,
*/
/* AFTER ROW DELETE Triggers */
if ( resultRelationDesc->trigdesc &&
resultRelationDesc->trigdesc->n_after_row[TRIGGER_EVENT_DELETE] > 0 )
ExecARDeleteTriggers (resultRelationDesc, tupleid);
if (resultRelationDesc->trigdesc &&
resultRelationDesc->trigdesc->n_after_row[TRIGGER_EVENT_DELETE] > 0)
ExecARDeleteTriggers(resultRelationDesc, tupleid);
}
@ -1062,10 +1113,10 @@ ExecDelete(TupleTableSlot *slot,
* ----------------------------------------------------------------
*/
static void
ExecReplace(TupleTableSlot *slot,
ExecReplace(TupleTableSlot * slot,
ItemPointer tupleid,
EState *estate,
Query *parseTree)
EState * estate,
Query * parseTree)
{
HeapTuple tuple;
RelationInfo *resultRelationInfo;
@ -1076,7 +1127,8 @@ ExecReplace(TupleTableSlot *slot,
* abort the operation if not running transactions
* ----------------
*/
if (IsBootstrapProcessingMode()) {
if (IsBootstrapProcessingMode())
{
elog(DEBUG, "ExecReplace: replace can't run without transactions");
return;
}
@ -1103,20 +1155,20 @@ ExecReplace(TupleTableSlot *slot,
*/
/* BEFORE ROW UPDATE Triggers */
if ( resultRelationDesc->trigdesc &&
resultRelationDesc->trigdesc->n_before_row[TRIGGER_EVENT_UPDATE] > 0 )
if (resultRelationDesc->trigdesc &&
resultRelationDesc->trigdesc->n_before_row[TRIGGER_EVENT_UPDATE] > 0)
{
HeapTuple newtuple;
newtuple = ExecBRUpdateTriggers (resultRelationDesc, tupleid, tuple);
newtuple = ExecBRUpdateTriggers(resultRelationDesc, tupleid, tuple);
if ( newtuple == NULL ) /* "do nothing" */
if (newtuple == NULL) /* "do nothing" */
return;
if ( newtuple != tuple ) /* modified by Trigger(s) */
if (newtuple != tuple) /* modified by Trigger(s) */
{
Assert ( slot->ttc_shouldFree );
pfree (tuple);
Assert(slot->ttc_shouldFree);
pfree(tuple);
slot->val = tuple = newtuple;
}
}
@ -1126,16 +1178,16 @@ ExecReplace(TupleTableSlot *slot,
* ----------------
*/
if ( resultRelationDesc->rd_att->constr )
if (resultRelationDesc->rd_att->constr)
{
HeapTuple newtuple;
newtuple = ExecConstraints ("ExecReplace", resultRelationDesc, tuple);
newtuple = ExecConstraints("ExecReplace", resultRelationDesc, tuple);
if ( newtuple != tuple ) /* modified by DEFAULT */
if (newtuple != tuple) /* modified by DEFAULT */
{
Assert ( slot->ttc_shouldFree );
pfree (tuple);
Assert(slot->ttc_shouldFree);
pfree(tuple);
slot->val = tuple = newtuple;
}
}
@ -1150,7 +1202,8 @@ ExecReplace(TupleTableSlot *slot,
*/
if (heap_replace(resultRelationDesc, /* relation desc */
tupleid, /* item ptr of tuple to replace */
tuple)) { /* replacement heap tuple */
tuple))
{ /* replacement heap tuple */
return;
}
@ -1180,22 +1233,23 @@ ExecReplace(TupleTableSlot *slot,
*/
numIndices = resultRelationInfo->ri_NumIndices;
if (numIndices > 0) {
if (numIndices > 0)
{
ExecInsertIndexTuples(slot, &(tuple->t_ctid), estate, true);
}
/* AFTER ROW UPDATE Triggers */
if ( resultRelationDesc->trigdesc &&
resultRelationDesc->trigdesc->n_after_row[TRIGGER_EVENT_UPDATE] > 0 )
ExecARUpdateTriggers (resultRelationDesc, tupleid, tuple);
if (resultRelationDesc->trigdesc &&
resultRelationDesc->trigdesc->n_after_row[TRIGGER_EVENT_UPDATE] > 0)
ExecARUpdateTriggers(resultRelationDesc, tupleid, tuple);
}
static HeapTuple
ExecAttrDefault (Relation rel, HeapTuple tuple)
ExecAttrDefault(Relation rel, HeapTuple tuple)
{
int ndef = rel->rd_att->constr->num_defval;
AttrDefault *attrdef = rel->rd_att->constr->defval;
ExprContext *econtext = makeNode (ExprContext);
ExprContext *econtext = makeNode(ExprContext);
HeapTuple newtuple;
Node *expr;
bool isnull;
@ -1215,23 +1269,23 @@ ExecAttrDefault (Relation rel, HeapTuple tuple)
econtext->ecxt_range_table = NULL; /* range table */
for (i = 0; i < ndef; i++)
{
if ( !heap_attisnull (tuple, attrdef[i].adnum) )
if (!heap_attisnull(tuple, attrdef[i].adnum))
continue;
expr = (Node*) stringToNode (attrdef[i].adbin);
expr = (Node *) stringToNode(attrdef[i].adbin);
val = ExecEvalExpr (expr, econtext, &isnull, &isdone);
val = ExecEvalExpr(expr, econtext, &isnull, &isdone);
pfree (expr);
pfree(expr);
if ( isnull )
if (isnull)
continue;
if ( repl == NULL )
if (repl == NULL)
{
repl = (char*) palloc (rel->rd_att->natts * sizeof (char));
replNull = (char*) palloc (rel->rd_att->natts * sizeof (char));
replValue = (Datum*) palloc (rel->rd_att->natts * sizeof (Datum));
memset (repl, ' ', rel->rd_att->natts * sizeof (char));
repl = (char *) palloc(rel->rd_att->natts * sizeof(char));
replNull = (char *) palloc(rel->rd_att->natts * sizeof(char));
replValue = (Datum *) palloc(rel->rd_att->natts * sizeof(Datum));
memset(repl, ' ', rel->rd_att->natts * sizeof(char));
}
repl[attrdef[i].adnum - 1] = 'r';
@ -1240,29 +1294,29 @@ ExecAttrDefault (Relation rel, HeapTuple tuple)
}
pfree (econtext);
pfree(econtext);
if ( repl == NULL )
if (repl == NULL)
return (tuple);
newtuple = heap_modifytuple (tuple, InvalidBuffer, rel, replValue, replNull, repl);
newtuple = heap_modifytuple(tuple, InvalidBuffer, rel, replValue, replNull, repl);
pfree (repl);
pfree (replNull);
pfree (replValue);
pfree(repl);
pfree(replNull);
pfree(replValue);
return (newtuple);
}
static char *
ExecRelCheck (Relation rel, HeapTuple tuple)
ExecRelCheck(Relation rel, HeapTuple tuple)
{
int ncheck = rel->rd_att->constr->num_check;
ConstrCheck *check = rel->rd_att->constr->check;
ExprContext *econtext = makeNode (ExprContext);
TupleTableSlot *slot = makeNode (TupleTableSlot);
RangeTblEntry *rte = makeNode (RangeTblEntry);
ExprContext *econtext = makeNode(ExprContext);
TupleTableSlot *slot = makeNode(TupleTableSlot);
RangeTblEntry *rte = makeNode(RangeTblEntry);
List *rtlist;
List *qual;
bool res;
@ -1274,7 +1328,7 @@ ExecRelCheck (Relation rel, HeapTuple tuple)
slot->ttc_tupleDescriptor = rel->rd_att;
slot->ttc_buffer = InvalidBuffer;
slot->ttc_whichplan = -1;
rte->relname = nameout (&(rel->rd_rel->relname));
rte->relname = nameout(&(rel->rd_rel->relname));
rte->timeRange = NULL;
rte->refname = rte->relname;
rte->relid = rel->rd_id;
@ -1282,7 +1336,7 @@ ExecRelCheck (Relation rel, HeapTuple tuple)
rte->archive = false;
rte->inFromCl = true;
rte->timeQual = NULL;
rtlist = lcons (rte, NIL);
rtlist = lcons(rte, NIL);
econtext->ecxt_scantuple = slot; /* scan tuple slot */
econtext->ecxt_innertuple = NULL; /* inner tuple slot */
econtext->ecxt_outertuple = NULL; /* outer tuple slot */
@ -1293,54 +1347,54 @@ ExecRelCheck (Relation rel, HeapTuple tuple)
for (i = 0; i < ncheck; i++)
{
qual = (List*) stringToNode (check[i].ccbin);
qual = (List *) stringToNode(check[i].ccbin);
res = ExecQual (qual, econtext);
res = ExecQual(qual, econtext);
pfree (qual);
pfree(qual);
if ( !res )
if (!res)
return (check[i].ccname);
}
pfree (slot);
pfree (rte->relname);
pfree (rte);
pfree (rtlist);
pfree (econtext);
pfree(slot);
pfree(rte->relname);
pfree(rte);
pfree(rtlist);
pfree(econtext);
return ((char *) NULL);
}
HeapTuple
ExecConstraints (char *caller, Relation rel, HeapTuple tuple)
ExecConstraints(char *caller, Relation rel, HeapTuple tuple)
{
HeapTuple newtuple = tuple;
Assert ( rel->rd_att->constr );
Assert(rel->rd_att->constr);
if ( rel->rd_att->constr->num_defval > 0 )
newtuple = tuple = ExecAttrDefault (rel, tuple);
if (rel->rd_att->constr->num_defval > 0)
newtuple = tuple = ExecAttrDefault(rel, tuple);
if ( rel->rd_att->constr->has_not_null )
if (rel->rd_att->constr->has_not_null)
{
int attrChk;
for (attrChk = 1; attrChk <= rel->rd_att->natts; attrChk++)
{
if (rel->rd_att->attrs[attrChk-1]->attnotnull && heap_attisnull (tuple,attrChk))
elog(WARN,"%s: Fail to add null value in not null attribute %s",
caller, rel->rd_att->attrs[attrChk-1]->attname.data);
if (rel->rd_att->attrs[attrChk - 1]->attnotnull && heap_attisnull(tuple, attrChk))
elog(WARN, "%s: Fail to add null value in not null attribute %s",
caller, rel->rd_att->attrs[attrChk - 1]->attname.data);
}
}
if ( rel->rd_att->constr->num_check > 0 )
if (rel->rd_att->constr->num_check > 0)
{
char *failed;
if ( ( failed = ExecRelCheck (rel, tuple) ) != NULL )
elog(WARN,"%s: rejected due to CHECK constraint %s", caller, failed);
if ((failed = ExecRelCheck(rel, tuple)) != NULL)
elog(WARN, "%s: rejected due to CHECK constraint %s", caller, failed);
}
return (newtuple);

View File

@ -11,7 +11,7 @@
*
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/executor/execProcnode.c,v 1.2 1996/10/31 10:11:27 scrappy Exp $
* $Header: /cvsroot/pgsql/src/backend/executor/execProcnode.c,v 1.3 1997/09/07 04:41:19 momjian Exp $
*
*-------------------------------------------------------------------------
*/
@ -103,7 +103,7 @@
* ------------------------------------------------------------------------
*/
bool
ExecInitNode(Plan *node, EState *estate, Plan *parent)
ExecInitNode(Plan * node, EState * estate, Plan * parent)
{
bool result;
@ -115,17 +115,18 @@ ExecInitNode(Plan *node, EState *estate, Plan *parent)
if (node == NULL)
return FALSE;
switch(nodeTag(node)) {
switch (nodeTag(node))
{
/* ----------------
* control nodes
* ----------------
*/
case T_Result:
result = ExecInitResult((Result *)node, estate, parent);
result = ExecInitResult((Result *) node, estate, parent);
break;
case T_Append:
result = ExecInitAppend((Append *)node, estate, parent);
result = ExecInitAppend((Append *) node, estate, parent);
break;
/* ----------------
@ -133,11 +134,11 @@ ExecInitNode(Plan *node, EState *estate, Plan *parent)
* ----------------
*/
case T_SeqScan:
result = ExecInitSeqScan((SeqScan *)node, estate, parent);
result = ExecInitSeqScan((SeqScan *) node, estate, parent);
break;
case T_IndexScan:
result = ExecInitIndexScan((IndexScan *)node, estate, parent);
result = ExecInitIndexScan((IndexScan *) node, estate, parent);
break;
/* ----------------
@ -145,11 +146,11 @@ ExecInitNode(Plan *node, EState *estate, Plan *parent)
* ----------------
*/
case T_NestLoop:
result = ExecInitNestLoop((NestLoop *)node, estate, parent);
result = ExecInitNestLoop((NestLoop *) node, estate, parent);
break;
case T_MergeJoin:
result = ExecInitMergeJoin((MergeJoin *)node, estate, parent);
result = ExecInitMergeJoin((MergeJoin *) node, estate, parent);
break;
/* ----------------
@ -157,35 +158,35 @@ ExecInitNode(Plan *node, EState *estate, Plan *parent)
* ----------------
*/
case T_Material:
result = ExecInitMaterial((Material *)node, estate, parent);
result = ExecInitMaterial((Material *) node, estate, parent);
break;
case T_Sort:
result = ExecInitSort((Sort *)node, estate, parent);
result = ExecInitSort((Sort *) node, estate, parent);
break;
case T_Unique:
result = ExecInitUnique((Unique *)node, estate, parent);
result = ExecInitUnique((Unique *) node, estate, parent);
break;
case T_Group:
result = ExecInitGroup((Group *)node, estate, parent);
result = ExecInitGroup((Group *) node, estate, parent);
break;
case T_Agg:
result = ExecInitAgg((Agg *)node, estate, parent);
result = ExecInitAgg((Agg *) node, estate, parent);
break;
case T_Hash:
result = ExecInitHash((Hash *)node, estate, parent);
result = ExecInitHash((Hash *) node, estate, parent);
break;
case T_HashJoin:
result = ExecInitHashJoin((HashJoin *)node, estate, parent);
result = ExecInitHashJoin((HashJoin *) node, estate, parent);
break;
case T_Tee:
result = ExecInitTee((Tee*)node, estate, parent);
result = ExecInitTee((Tee *) node, estate, parent);
break;
default:
@ -206,7 +207,7 @@ ExecInitNode(Plan *node, EState *estate, Plan *parent)
* ----------------------------------------------------------------
*/
TupleTableSlot *
ExecProcNode(Plan *node, Plan *parent)
ExecProcNode(Plan * node, Plan * parent)
{
TupleTableSlot *result;
@ -217,17 +218,18 @@ ExecProcNode(Plan *node, Plan *parent)
if (node == NULL)
return NULL;
switch(nodeTag(node)) {
switch (nodeTag(node))
{
/* ----------------
* control nodes
* ----------------
*/
case T_Result:
result = ExecResult((Result *)node);
result = ExecResult((Result *) node);
break;
case T_Append:
result = ExecProcAppend((Append *)node);
result = ExecProcAppend((Append *) node);
break;
/* ----------------
@ -235,11 +237,11 @@ ExecProcNode(Plan *node, Plan *parent)
* ----------------
*/
case T_SeqScan:
result = ExecSeqScan((SeqScan *)node);
result = ExecSeqScan((SeqScan *) node);
break;
case T_IndexScan:
result = ExecIndexScan((IndexScan *)node);
result = ExecIndexScan((IndexScan *) node);
break;
/* ----------------
@ -247,11 +249,11 @@ ExecProcNode(Plan *node, Plan *parent)
* ----------------
*/
case T_NestLoop:
result = ExecNestLoop((NestLoop *)node, parent);
result = ExecNestLoop((NestLoop *) node, parent);
break;
case T_MergeJoin:
result = ExecMergeJoin((MergeJoin *)node);
result = ExecMergeJoin((MergeJoin *) node);
break;
/* ----------------
@ -259,35 +261,35 @@ ExecProcNode(Plan *node, Plan *parent)
* ----------------
*/
case T_Material:
result = ExecMaterial((Material *)node);
result = ExecMaterial((Material *) node);
break;
case T_Sort:
result = ExecSort((Sort *)node);
result = ExecSort((Sort *) node);
break;
case T_Unique:
result = ExecUnique((Unique *)node);
result = ExecUnique((Unique *) node);
break;
case T_Group:
result = ExecGroup((Group *)node);
result = ExecGroup((Group *) node);
break;
case T_Agg:
result = ExecAgg((Agg *)node);
result = ExecAgg((Agg *) node);
break;
case T_Hash:
result = ExecHash((Hash *)node);
result = ExecHash((Hash *) node);
break;
case T_HashJoin:
result = ExecHashJoin((HashJoin *)node);
result = ExecHashJoin((HashJoin *) node);
break;
case T_Tee:
result = ExecTee((Tee*)node, parent);
result = ExecTee((Tee *) node, parent);
break;
default:
@ -300,69 +302,70 @@ ExecProcNode(Plan *node, Plan *parent)
}
int
ExecCountSlotsNode(Plan *node)
ExecCountSlotsNode(Plan * node)
{
if (node == (Plan *)NULL)
if (node == (Plan *) NULL)
return 0;
switch(nodeTag(node)) {
switch (nodeTag(node))
{
/* ----------------
* control nodes
* ----------------
*/
case T_Result:
return ExecCountSlotsResult((Result *)node);
return ExecCountSlotsResult((Result *) node);
case T_Append:
return ExecCountSlotsAppend((Append *)node);
return ExecCountSlotsAppend((Append *) node);
/* ----------------
* scan nodes
* ----------------
*/
case T_SeqScan:
return ExecCountSlotsSeqScan((SeqScan *)node);
return ExecCountSlotsSeqScan((SeqScan *) node);
case T_IndexScan:
return ExecCountSlotsIndexScan((IndexScan *)node);
return ExecCountSlotsIndexScan((IndexScan *) node);
/* ----------------
* join nodes
* ----------------
*/
case T_NestLoop:
return ExecCountSlotsNestLoop((NestLoop *)node);
return ExecCountSlotsNestLoop((NestLoop *) node);
case T_MergeJoin:
return ExecCountSlotsMergeJoin((MergeJoin *)node);
return ExecCountSlotsMergeJoin((MergeJoin *) node);
/* ----------------
* materialization nodes
* ----------------
*/
case T_Material:
return ExecCountSlotsMaterial((Material *)node);
return ExecCountSlotsMaterial((Material *) node);
case T_Sort:
return ExecCountSlotsSort((Sort *)node);
return ExecCountSlotsSort((Sort *) node);
case T_Unique:
return ExecCountSlotsUnique((Unique *)node);
return ExecCountSlotsUnique((Unique *) node);
case T_Group:
return ExecCountSlotsGroup((Group *)node);
return ExecCountSlotsGroup((Group *) node);
case T_Agg:
return ExecCountSlotsAgg((Agg *)node);
return ExecCountSlotsAgg((Agg *) node);
case T_Hash:
return ExecCountSlotsHash((Hash *)node);
return ExecCountSlotsHash((Hash *) node);
case T_HashJoin:
return ExecCountSlotsHashJoin((HashJoin *)node);
return ExecCountSlotsHashJoin((HashJoin *) node);
case T_Tee:
return ExecCountSlotsTee((Tee*)node);
return ExecCountSlotsTee((Tee *) node);
default:
elog(WARN, "ExecCountSlotsNode: node not yet supported: %d",
@ -384,7 +387,7 @@ ExecCountSlotsNode(Plan *node)
* ----------------------------------------------------------------
*/
void
ExecEndNode(Plan *node, Plan *parent)
ExecEndNode(Plan * node, Plan * parent)
{
/* ----------------
* do nothing when we get to the end
@ -394,17 +397,18 @@ ExecEndNode(Plan *node, Plan *parent)
if (node == NULL)
return;
switch(nodeTag(node)) {
switch (nodeTag(node))
{
/* ----------------
* control nodes
* ----------------
*/
case T_Result:
ExecEndResult((Result *)node);
ExecEndResult((Result *) node);
break;
case T_Append:
ExecEndAppend((Append *)node);
ExecEndAppend((Append *) node);
break;
/* ----------------
@ -412,11 +416,11 @@ ExecEndNode(Plan *node, Plan *parent)
* ----------------
*/
case T_SeqScan:
ExecEndSeqScan((SeqScan *)node);
ExecEndSeqScan((SeqScan *) node);
break;
case T_IndexScan:
ExecEndIndexScan((IndexScan *)node);
ExecEndIndexScan((IndexScan *) node);
break;
/* ----------------
@ -424,11 +428,11 @@ ExecEndNode(Plan *node, Plan *parent)
* ----------------
*/
case T_NestLoop:
ExecEndNestLoop((NestLoop *)node);
ExecEndNestLoop((NestLoop *) node);
break;
case T_MergeJoin:
ExecEndMergeJoin((MergeJoin *)node);
ExecEndMergeJoin((MergeJoin *) node);
break;
/* ----------------
@ -436,23 +440,23 @@ ExecEndNode(Plan *node, Plan *parent)
* ----------------
*/
case T_Material:
ExecEndMaterial((Material *)node);
ExecEndMaterial((Material *) node);
break;
case T_Sort:
ExecEndSort((Sort *)node);
ExecEndSort((Sort *) node);
break;
case T_Unique:
ExecEndUnique((Unique *)node);
ExecEndUnique((Unique *) node);
break;
case T_Group:
ExecEndGroup((Group *)node);
ExecEndGroup((Group *) node);
break;
case T_Agg:
ExecEndAgg((Agg *)node);
ExecEndAgg((Agg *) node);
break;
/* ----------------
@ -468,7 +472,7 @@ ExecEndNode(Plan *node, Plan *parent)
break;
case T_Tee:
ExecEndTee((Tee*) node, parent);
ExecEndTee((Tee *) node, parent);
break;
default:

File diff suppressed because it is too large Load Diff

View File

@ -11,7 +11,7 @@
*
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/executor/execScan.c,v 1.3 1997/07/28 00:53:51 momjian Exp $
* $Header: /cvsroot/pgsql/src/backend/executor/execScan.c,v 1.4 1997/09/07 04:41:23 momjian Exp $
*
*-------------------------------------------------------------------------
*/
@ -43,8 +43,9 @@
* ----------------------------------------------------------------
*/
TupleTableSlot *
ExecScan(Scan *node,
TupleTableSlot* (*accessMtd)()) /* function returning a tuple */
ExecScan(Scan * node,
TupleTableSlot * (*accessMtd) ()) /* function returning a
* tuple */
{
CommonScanState *scanstate;
EState *estate;
@ -84,18 +85,21 @@ ExecScan(Scan *node,
econtext->ecxt_relation = scanstate->css_currentRelation;
econtext->ecxt_relid = node->scanrelid;
if (scanstate->cstate.cs_TupFromTlist) {
if (scanstate->cstate.cs_TupFromTlist)
{
projInfo = scanstate->cstate.cs_ProjInfo;
resultSlot = ExecProject(projInfo, &isDone);
if (!isDone)
return resultSlot;
}
/*
* get a tuple from the access method
* loop until we obtain a tuple which passes the qualification.
* get a tuple from the access method loop until we obtain a tuple
* which passes the qualification.
*/
for(;;) {
slot = (TupleTableSlot *) (*accessMtd)(node);
for (;;)
{
slot = (TupleTableSlot *) (*accessMtd) (node);
/* ----------------
* if the slot returned by the accessMtd contains
@ -103,7 +107,8 @@ ExecScan(Scan *node,
* so we just return the empty slot.
* ----------------
*/
if (TupIsNull(slot)) return slot;
if (TupIsNull(slot))
return slot;
/* ----------------
* place the current tuple into the expr context
@ -118,8 +123,10 @@ ExecScan(Scan *node,
* ----------------
*/
/* add a check for non-nil qual here to avoid a
function call to ExecQual() when the qual is nil */
/*
* add a check for non-nil qual here to avoid a function call to
* ExecQual() when the qual is nil
*/
if (!qual || ExecQual(qual, econtext) == true)
break;
}
@ -136,4 +143,3 @@ ExecScan(Scan *node,
return resultSlot;
}

View File

@ -14,7 +14,7 @@
*
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/executor/execTuples.c,v 1.6 1997/08/19 21:31:05 momjian Exp $
* $Header: /cvsroot/pgsql/src/backend/executor/execTuples.c,v 1.7 1997/09/07 04:41:24 momjian Exp $
*
*-------------------------------------------------------------------------
*/
@ -131,7 +131,7 @@
#include "parser/catalog_utils.h"
#include "catalog/pg_type.h"
static TupleTableSlot *NodeGetResultTupleSlot(Plan *node);
static TupleTableSlot *NodeGetResultTupleSlot(Plan * node);
/* ----------------------------------------------------------------
@ -150,10 +150,11 @@ static TupleTableSlot *NodeGetResultTupleSlot(Plan *node);
* --------------------------------
*/
TupleTable /* return: address of table */
ExecCreateTupleTable(int initialSize) /* initial number of slots in table */
ExecCreateTupleTable(int initialSize) /* initial number of slots
* in table */
{
TupleTable newtable; /* newly allocated table */
TupleTableSlot* array; /* newly allocated slot array */
TupleTableSlot *array; /* newly allocated slot array */
/* ----------------
* sanity checks
@ -167,7 +168,7 @@ ExecCreateTupleTable(int initialSize) /* initial number of slots in table */
*/
newtable = (TupleTable) palloc(sizeof(TupleTableData));
array = (TupleTableSlot*) palloc(initialSize * sizeof(TupleTableSlot));
array = (TupleTableSlot *) palloc(initialSize * sizeof(TupleTableSlot));
/* ----------------
* clean out the slots we just allocated
@ -196,7 +197,8 @@ ExecCreateTupleTable(int initialSize) /* initial number of slots in table */
*/
void
ExecDestroyTupleTable(TupleTable table, /* tuple table */
bool shouldFree) /* true if we should free slot contents */
bool shouldFree) /* true if we should free slot
* contents */
{
int next; /* next avaliable slot */
TupleTableSlot *array; /* start of table array */
@ -225,16 +227,19 @@ ExecDestroyTupleTable(TupleTable table, /* tuple table */
* ----------------
*/
if (shouldFree)
for (i = 0; i < next; i++) {
for (i = 0; i < next; i++)
{
TupleTableSlot slot;
HeapTuple tuple;
slot = array[i];
tuple = slot.val;
if (tuple != NULL) {
slot.val = (HeapTuple)NULL;
if (slot.ttc_shouldFree) {
if (tuple != NULL)
{
slot.val = (HeapTuple) NULL;
if (slot.ttc_shouldFree)
{
/* ----------------
* since a tuple may contain a pointer to
* lock information allocated along with the
@ -271,7 +276,8 @@ ExecDestroyTupleTable(TupleTable table, /* tuple table */
* slots (some just pass tuples around).
* --------------------------------
*/
TupleTableSlot* /* return: the slot allocated in the tuple table */
TupleTableSlot * /* return: the slot allocated in the tuple
* table */
ExecAllocTableSlot(TupleTable table)
{
int slotnum; /* new slot number */
@ -298,13 +304,14 @@ ExecAllocTableSlot(TupleTable table)
* happen now. Give a WARN if it does. -mer 4 Aug 1992
* ----------------
*/
if (table->next >= table->size) {
if (table->next >= table->size)
{
/*
* int newsize = NewTableSize(table->size);
*
* pfree(table->array);
* table->array = (Pointer) palloc(newsize * TableSlotSize);
* bzero(table->array, newsize * TableSlotSize);
* pfree(table->array); table->array = (Pointer) palloc(newsize *
* TableSlotSize); bzero(table->array, newsize * TableSlotSize);
* table->size = newsize;
*/
elog(NOTICE, "Plan requires more slots than are available");
@ -340,9 +347,9 @@ ExecAllocTableSlot(TupleTable table)
* by amgetattr, which are actually pointers onto disk pages.
* --------------------------------
*/
TupleTableSlot* /* return: slot passed */
TupleTableSlot * /* return: slot passed */
ExecStoreTuple(HeapTuple tuple, /* tuple to store */
TupleTableSlot* slot, /* slot in which to store tuple */
TupleTableSlot * slot, /* slot in which to store tuple */
Buffer buffer, /* buffer associated with tuple */
bool shouldFree) /* true if we call pfree() when we gc. */
{
@ -373,8 +380,8 @@ ExecStoreTuple(HeapTuple tuple, /* tuple to store */
* This function is used to clear out a slot in the tuple table.
* --------------------------------
*/
TupleTableSlot* /* return: slot passed */
ExecClearTuple(TupleTableSlot* slot) /* slot in which to store tuple */
TupleTableSlot * /* return: slot passed */
ExecClearTuple(TupleTableSlot * slot) /* slot in which to store tuple */
{
HeapTuple oldtuple; /* prior contents of slot */
@ -394,7 +401,8 @@ ExecClearTuple(TupleTableSlot* slot) /* slot in which to store tuple */
* free the old contents of the specified slot if necessary.
* ----------------
*/
if (slot->ttc_shouldFree && oldtuple != NULL) {
if (slot->ttc_shouldFree && oldtuple != NULL)
{
/* ----------------
* since a tuple may contain a pointer to
* lock information allocated along with the
@ -410,7 +418,7 @@ ExecClearTuple(TupleTableSlot* slot) /* slot in which to store tuple */
* - also set buffer to InvalidBuffer -cim 3/14/91
* ----------------
*/
slot->val = (HeapTuple)NULL;
slot->val = (HeapTuple) NULL;
if (BufferIsValid(slot->ttc_buffer))
ReleaseBuffer(slot->ttc_buffer);
@ -433,10 +441,11 @@ ExecClearTuple(TupleTableSlot* slot) /* slot in which to store tuple */
*/
#ifdef NOT_USED
bool /* return: slot policy */
ExecSlotPolicy(TupleTableSlot* slot) /* slot to inspect */
ExecSlotPolicy(TupleTableSlot * slot) /* slot to inspect */
{
return slot->ttc_shouldFree;
}
#endif
/* --------------------------------
@ -449,10 +458,12 @@ ExecSlotPolicy(TupleTableSlot* slot) /* slot to inspect */
* --------------------------------
*/
bool /* return: old slot policy */
ExecSetSlotPolicy(TupleTableSlot* slot, /* slot to change */
bool shouldFree) /* true if we call pfree() when we gc. */
ExecSetSlotPolicy(TupleTableSlot * slot, /* slot to change */
bool shouldFree) /* true if we call pfree() when we
* gc. */
{
bool old_shouldFree = slot->ttc_shouldFree;
slot->ttc_shouldFree = shouldFree;
return old_shouldFree;
@ -476,7 +487,7 @@ ExecSetSlotPolicy(TupleTableSlot* slot, /* slot to change */
* --------------------------------
*/
TupleDesc /* return: old slot tuple descriptor */
ExecSetSlotDescriptor(TupleTableSlot *slot, /* slot to change */
ExecSetSlotDescriptor(TupleTableSlot * slot, /* slot to change */
TupleDesc tupdesc) /* tuple descriptor */
{
TupleDesc old_tupdesc = slot->ttc_tupleDescriptor;
@ -492,7 +503,7 @@ ExecSetSlotDescriptor(TupleTableSlot *slot, /* slot to change */
* --------------------------------
*/
void
ExecSetSlotDescriptorIsNew(TupleTableSlot *slot,/* slot to change */
ExecSetSlotDescriptorIsNew(TupleTableSlot * slot, /* slot to change */
bool isNew) /* "isNew" setting */
{
slot->ttc_descIsNew = isNew;
@ -507,15 +518,17 @@ ExecSetSlotDescriptorIsNew(TupleTableSlot *slot,/* slot to change */
*/
#ifdef NOT_USED
TupleDesc /* return: old slot tuple descriptor */
ExecSetNewSlotDescriptor(TupleTableSlot *slot, /* slot to change */
ExecSetNewSlotDescriptor(TupleTableSlot * slot, /* slot to change */
TupleDesc tupdesc) /* tuple descriptor */
{
TupleDesc old_tupdesc = slot->ttc_tupleDescriptor;
slot->ttc_tupleDescriptor = tupdesc;
slot->ttc_descIsNew = true;
return old_tupdesc;
}
#endif
/* --------------------------------
@ -541,14 +554,16 @@ ExecSetNewSlotDescriptor(TupleTableSlot *slot, /* slot to change */
*/
#ifdef NOT_USED
Buffer /* return: old slot buffer */
ExecSetSlotBuffer(TupleTableSlot *slot, /* slot to change */
ExecSetSlotBuffer(TupleTableSlot * slot, /* slot to change */
Buffer b) /* tuple descriptor */
{
Buffer oldb = slot->ttc_buffer;
slot->ttc_buffer = b;
return oldb;
}
#endif
/* --------------------------------
@ -560,10 +575,11 @@ ExecSetSlotBuffer(TupleTableSlot *slot, /* slot to change */
* --------------------------------
*/
void
ExecIncrSlotBufferRefcnt(TupleTableSlot *slot) /* slot to bump refcnt */
ExecIncrSlotBufferRefcnt(TupleTableSlot * slot) /* slot to bump refcnt */
{
/* Buffer b = SlotBuffer((TupleTableSlot*) slot); */
Buffer b = slot->ttc_buffer;
if (BufferIsValid(b))
IncrBufferRefCount(b);
}
@ -581,7 +597,7 @@ ExecIncrSlotBufferRefcnt(TupleTableSlot *slot) /* slot to bump refcnt */
* ----------------
*/
bool /* return: true if tuple in slot is NULL */
TupIsNull(TupleTableSlot* slot) /* slot to check */
TupIsNull(TupleTableSlot * slot) /* slot to check */
{
HeapTuple tuple; /* contents of slot (returned) */
@ -613,12 +629,13 @@ TupIsNull(TupleTableSlot* slot) /* slot to check */
*/
#ifdef NOT_USED
bool /* return: descriptor "is new" */
ExecSlotDescriptorIsNew(TupleTableSlot *slot) /* slot to inspect */
ExecSlotDescriptorIsNew(TupleTableSlot * slot) /* slot to inspect */
{
/* bool isNew = SlotTupleDescriptorIsNew((TupleTableSlot*) slot);
return isNew; */
return slot->ttc_descIsNew;
}
#endif
/* ----------------------------------------------------------------
@ -650,7 +667,7 @@ ExecSlotDescriptorIsNew(TupleTableSlot *slot) /* slot to inspect */
* ----------------
*/
void
ExecInitResultTupleSlot(EState *estate, CommonState *commonstate)
ExecInitResultTupleSlot(EState * estate, CommonState * commonstate)
{
INIT_SLOT_DEFS;
INIT_SLOT_ALLOC;
@ -662,11 +679,11 @@ ExecInitResultTupleSlot(EState *estate, CommonState *commonstate)
* ----------------
*/
void
ExecInitScanTupleSlot(EState *estate, CommonScanState *commonscanstate)
ExecInitScanTupleSlot(EState * estate, CommonScanState * commonscanstate)
{
INIT_SLOT_DEFS;
INIT_SLOT_ALLOC;
commonscanstate->css_ScanTupleSlot = (TupleTableSlot *)slot;
commonscanstate->css_ScanTupleSlot = (TupleTableSlot *) slot;
}
/* ----------------
@ -674,7 +691,7 @@ ExecInitScanTupleSlot(EState *estate, CommonScanState *commonscanstate)
* ----------------
*/
void
ExecInitMarkedTupleSlot(EState *estate, MergeJoinState *mergestate)
ExecInitMarkedTupleSlot(EState * estate, MergeJoinState * mergestate)
{
INIT_SLOT_DEFS;
INIT_SLOT_ALLOC;
@ -686,7 +703,7 @@ ExecInitMarkedTupleSlot(EState *estate, MergeJoinState *mergestate)
* ----------------
*/
void
ExecInitOuterTupleSlot(EState *estate, HashJoinState *hashstate)
ExecInitOuterTupleSlot(EState * estate, HashJoinState * hashstate)
{
INIT_SLOT_DEFS;
INIT_SLOT_ALLOC;
@ -699,45 +716,50 @@ ExecInitOuterTupleSlot(EState *estate, HashJoinState *hashstate)
*/
#ifdef NOT_USED
void
ExecInitHashTupleSlot(EState *estate, HashJoinState *hashstate)
ExecInitHashTupleSlot(EState * estate, HashJoinState * hashstate)
{
INIT_SLOT_DEFS;
INIT_SLOT_ALLOC;
hashstate->hj_HashTupleSlot = slot;
}
#endif
static TupleTableSlot *
NodeGetResultTupleSlot(Plan *node)
NodeGetResultTupleSlot(Plan * node)
{
TupleTableSlot *slot;
switch(nodeTag(node)) {
switch (nodeTag(node))
{
case T_Result:
{
ResultState *resstate = ((Result *)node)->resstate;
ResultState *resstate = ((Result *) node)->resstate;
slot = resstate->cstate.cs_ResultTupleSlot;
}
break;
case T_SeqScan:
{
CommonScanState *scanstate = ((SeqScan *)node)->scanstate;
CommonScanState *scanstate = ((SeqScan *) node)->scanstate;
slot = scanstate->cstate.cs_ResultTupleSlot;
}
break;
case T_NestLoop:
{
NestLoopState *nlstate = ((NestLoop *)node)->nlstate;
NestLoopState *nlstate = ((NestLoop *) node)->nlstate;
slot = nlstate->jstate.cs_ResultTupleSlot;
}
break;
case T_Append:
{
Append *n = (Append *)node;
Append *n = (Append *) node;
AppendState *unionstate;
List *unionplans;
int whichplan;
@ -747,77 +769,87 @@ NodeGetResultTupleSlot(Plan *node)
unionplans = n->unionplans;
whichplan = unionstate->as_whichplan;
subplan = (Plan*) nth(whichplan, unionplans);
subplan = (Plan *) nth(whichplan, unionplans);
slot = NodeGetResultTupleSlot(subplan);
break;
}
case T_IndexScan:
{
CommonScanState *scanstate = ((IndexScan *)node)->scan.scanstate;
CommonScanState *scanstate = ((IndexScan *) node)->scan.scanstate;
slot = scanstate->cstate.cs_ResultTupleSlot;
}
break;
case T_Material:
{
MaterialState *matstate = ((Material *)node)->matstate;
MaterialState *matstate = ((Material *) node)->matstate;
slot = matstate->csstate.css_ScanTupleSlot;
}
break;
case T_Sort:
{
SortState *sortstate = ((Sort *)node)->sortstate;
SortState *sortstate = ((Sort *) node)->sortstate;
slot = sortstate->csstate.css_ScanTupleSlot;
}
break;
case T_Agg:
{
AggState *aggstate = ((Agg *)node)->aggstate;
AggState *aggstate = ((Agg *) node)->aggstate;
slot = aggstate->csstate.cstate.cs_ResultTupleSlot;
}
break;
case T_Group:
{
GroupState *grpstate = ((Group *)node)->grpstate;
GroupState *grpstate = ((Group *) node)->grpstate;
slot = grpstate->csstate.cstate.cs_ResultTupleSlot;
}
break;
case T_Hash:
{
HashState *hashstate = ((Hash *)node)->hashstate;
HashState *hashstate = ((Hash *) node)->hashstate;
slot = hashstate->cstate.cs_ResultTupleSlot;
}
break;
case T_Unique:
{
UniqueState *uniquestate = ((Unique *)node)->uniquestate;
UniqueState *uniquestate = ((Unique *) node)->uniquestate;
slot = uniquestate->cs_ResultTupleSlot;
}
break;
case T_MergeJoin:
{
MergeJoinState *mergestate = ((MergeJoin *)node)->mergestate;
MergeJoinState *mergestate = ((MergeJoin *) node)->mergestate;
slot = mergestate->jstate.cs_ResultTupleSlot;
}
break;
case T_HashJoin:
{
HashJoinState *hashjoinstate = ((HashJoin *)node)->hashjoinstate;
HashJoinState *hashjoinstate = ((HashJoin *) node)->hashjoinstate;
slot = hashjoinstate->jstate.cs_ResultTupleSlot;
}
break;
case T_Tee:
{
TeeState *teestate = ((Tee*)node)->teestate;
TeeState *teestate = ((Tee *) node)->teestate;
slot = teestate->cstate.cs_ResultTupleSlot;
}
break;
@ -862,7 +894,7 @@ NodeGetResultTupleSlot(Plan *node)
*/
TupleDesc
ExecGetTupType(Plan *node)
ExecGetTupType(Plan * node)
{
TupleTableSlot *slot;
TupleDesc tupType;
@ -914,7 +946,7 @@ ExecCopyTupType(TupleDesc td, int natts)
* ----------------------------------------------------------------
*/
TupleDesc
ExecTypeFromTL(List *targetList)
ExecTypeFromTL(List * targetList)
{
List *tlcdr;
TupleDesc typeInfo;
@ -943,9 +975,12 @@ ExecTypeFromTL(List *targetList)
* ----------------
*/
tlcdr = targetList;
while (tlcdr != NIL) {
while (tlcdr != NIL)
{
TargetEntry *tle = lfirst(tlcdr);
if (tle->resdom != NULL) {
if (tle->resdom != NULL)
{
resdom = tle->resdom;
restype = resdom->restype;
@ -953,7 +988,7 @@ ExecTypeFromTL(List *targetList)
resdom->resno,
resdom->resname,
/* fix for SELECT NULL ... */
get_id_typname(restype?restype:UNKNOWNOID),
get_id_typname(restype ? restype : UNKNOWNOID),
0,
false);
@ -968,13 +1003,15 @@ ExecTypeFromTL(List *targetList)
get_typalign(restype));
*/
}
else {
else
{
Resdom *fjRes;
List *fjTlistP;
List *fjList = lfirst(tlcdr);
#ifdef SETS_FIXED
TargetEntry *tle;
Fjoin *fjNode = ((TargetEntry *)lfirst(fjList))->fjoin;
Fjoin *fjNode = ((TargetEntry *) lfirst(fjList))->fjoin;
tle = fjNode->fj_innerNode; /* ??? */
#endif
@ -998,7 +1035,8 @@ ExecTypeFromTL(List *targetList)
get_typalign(restype));
*/
foreach(fjTlistP, lnext(fjList)) {
foreach(fjTlistP, lnext(fjList))
{
TargetEntry *fjTle = lfirst(fjTlistP);
fjRes = fjTle->resdom;
@ -1028,5 +1066,3 @@ ExecTypeFromTL(List *targetList)
return typeInfo;
}

View File

@ -7,7 +7,7 @@
*
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/executor/execUtils.c,v 1.14 1997/08/22 03:12:19 vadim Exp $
* $Header: /cvsroot/pgsql/src/backend/executor/execUtils.c,v 1.15 1997/09/07 04:41:26 momjian Exp $
*
*-------------------------------------------------------------------------
*/
@ -58,8 +58,9 @@
#include "catalog/pg_type.h"
#include "parser/parsetree.h"
static void ExecGetIndexKeyInfo(IndexTupleForm indexTuple, int *numAttsOutP,
AttrNumber **attsOutP, FuncIndexInfoPtr fInfoP);
static void
ExecGetIndexKeyInfo(IndexTupleForm indexTuple, int *numAttsOutP,
AttrNumber ** attsOutP, FuncIndexInfoPtr fInfoP);
/* ----------------------------------------------------------------
* global counters for number of tuples processed, retrieved,
@ -72,9 +73,9 @@ int NTupleReplaced;
int NTupleAppended;
int NTupleDeleted;
int NIndexTupleInserted;
extern int NIndexTupleProcessed; /* have to be defined in the access
method level so that the cinterface.a
will link ok. */
extern int NIndexTupleProcessed; /* have to be defined in the
* access method level so that the
* cinterface.a will link ok. */
/* ----------------------------------------------------------------
* statistic functions
@ -96,6 +97,7 @@ ResetTupleCount(void)
NTupleReplaced = 0;
NIndexTupleProcessed = 0;
}
#endif
/* ----------------------------------------------------------------
@ -104,12 +106,13 @@ ResetTupleCount(void)
*/
#ifdef NOT_USED
void
DisplayTupleCount(FILE *statfp)
DisplayTupleCount(FILE * statfp)
{
if (NTupleProcessed > 0)
fprintf(statfp, "!\t%d tuple%s processed, ", NTupleProcessed,
(NTupleProcessed == 1) ? "" : "s");
else {
else
{
fprintf(statfp, "!\tno tuples processed.\n");
return;
}
@ -133,6 +136,7 @@ DisplayTupleCount(FILE *statfp)
(NTupleReplaced == 1) ? "" : "s");
fprintf(statfp, "\n");
}
#endif
/* ----------------------------------------------------------------
@ -153,7 +157,7 @@ DisplayTupleCount(FILE *statfp)
* ----------------
*/
void
ExecAssignNodeBaseInfo(EState *estate, CommonState *cstate, Plan *parent)
ExecAssignNodeBaseInfo(EState * estate, CommonState * cstate, Plan * parent)
{
int baseId;
@ -172,7 +176,7 @@ ExecAssignNodeBaseInfo(EState *estate, CommonState *cstate, Plan *parent)
* ----------------
*/
void
ExecAssignExprContext(EState *estate, CommonState *commonstate)
ExecAssignExprContext(EState * estate, CommonState * commonstate)
{
ExprContext *econtext;
ParamListInfo paraminfo;
@ -203,7 +207,7 @@ ExecAssignExprContext(EState *estate, CommonState *commonstate)
* ----------------
*/
void
ExecAssignResultType(CommonState *commonstate,
ExecAssignResultType(CommonState * commonstate,
TupleDesc tupDesc)
{
TupleTableSlot *slot;
@ -217,7 +221,7 @@ ExecAssignResultType(CommonState *commonstate,
* ----------------
*/
void
ExecAssignResultTypeFromOuterPlan(Plan *node, CommonState *commonstate)
ExecAssignResultTypeFromOuterPlan(Plan * node, CommonState * commonstate)
{
Plan *outerPlan;
TupleDesc tupDesc;
@ -233,7 +237,7 @@ ExecAssignResultTypeFromOuterPlan(Plan *node, CommonState *commonstate)
* ----------------
*/
void
ExecAssignResultTypeFromTL(Plan *node, CommonState *commonstate)
ExecAssignResultTypeFromTL(Plan * node, CommonState * commonstate)
{
List *targetList;
int i;
@ -250,18 +254,23 @@ ExecAssignResultTypeFromTL(Plan *node, CommonState *commonstate)
fjtl = NIL;
tl = targetList;
i = 0;
while (tl != NIL || fjtl != NIL) {
if (fjtl != NIL) {
while (tl != NIL || fjtl != NIL)
{
if (fjtl != NIL)
{
tle = lfirst(fjtl);
fjtl = lnext(fjtl);
}
else {
else
{
tle = lfirst(tl);
tl = lnext(tl);
}
#ifdef SETS_FIXED
if (!tl_is_resdom(tle)) {
Fjoin *fj = (Fjoin *)lfirst(tle);
if (!tl_is_resdom(tle))
{
Fjoin *fj = (Fjoin *) lfirst(tle);
/* it is a FJoin */
fjtl = lnext(tle);
tle = fj->fj_innerNode;
@ -269,13 +278,14 @@ ExecAssignResultTypeFromTL(Plan *node, CommonState *commonstate)
#endif
i++;
}
if (len > 0) {
if (len > 0)
{
ExecAssignResultType(commonstate,
origTupDesc);
}
else
ExecAssignResultType(commonstate,
(TupleDesc)NULL);
(TupleDesc) NULL);
}
/* ----------------
@ -283,7 +293,7 @@ ExecAssignResultTypeFromTL(Plan *node, CommonState *commonstate)
* ----------------
*/
TupleDesc
ExecGetResultType(CommonState *commonstate)
ExecGetResultType(CommonState * commonstate)
{
TupleTableSlot *slot = commonstate->cs_ResultTupleSlot;
@ -296,7 +306,7 @@ ExecGetResultType(CommonState *commonstate)
*/
#ifdef NOT_USED
void
ExecFreeResultType(CommonState *commonstate)
ExecFreeResultType(CommonState * commonstate)
{
TupleTableSlot *slot;
TupleDesc tupType;
@ -307,6 +317,7 @@ ExecFreeResultType(CommonState *commonstate)
/* ExecFreeTypeInfo(tupType); */
pfree(tupType);
}
#endif
/* ----------------
@ -315,7 +326,7 @@ ExecFreeResultType(CommonState *commonstate)
* ----------------
*/
void
ExecAssignProjectionInfo(Plan *node, CommonState *commonstate)
ExecAssignProjectionInfo(Plan * node, CommonState * commonstate)
{
ProjectionInfo *projInfo;
List *targetList;
@ -341,7 +352,7 @@ ExecAssignProjectionInfo(Plan *node, CommonState *commonstate)
* ----------------
*/
void
ExecFreeProjectionInfo(CommonState *commonstate)
ExecFreeProjectionInfo(CommonState * commonstate)
{
ProjectionInfo *projInfo;
@ -380,9 +391,10 @@ ExecFreeProjectionInfo(CommonState *commonstate)
* ----------------
*/
TupleDesc
ExecGetScanType(CommonScanState *csstate)
ExecGetScanType(CommonScanState * csstate)
{
TupleTableSlot *slot = csstate->css_ScanTupleSlot;
return slot->ttc_tupleDescriptor;
}
@ -392,7 +404,7 @@ ExecGetScanType(CommonScanState *csstate)
*/
#ifdef NOT_USED
void
ExecFreeScanType(CommonScanState *csstate)
ExecFreeScanType(CommonScanState * csstate)
{
TupleTableSlot *slot;
TupleDesc tupType;
@ -403,6 +415,7 @@ ExecFreeScanType(CommonScanState *csstate)
/* ExecFreeTypeInfo(tupType); */
pfree(tupType);
}
#endif
/* ----------------
@ -410,7 +423,7 @@ ExecFreeScanType(CommonScanState *csstate)
* ----------------
*/
void
ExecAssignScanType(CommonScanState *csstate,
ExecAssignScanType(CommonScanState * csstate,
TupleDesc tupDesc)
{
TupleTableSlot *slot;
@ -424,7 +437,7 @@ ExecAssignScanType(CommonScanState *csstate,
* ----------------
*/
void
ExecAssignScanTypeFromOuterPlan(Plan *node, CommonScanState *csstate)
ExecAssignScanTypeFromOuterPlan(Plan * node, CommonScanState * csstate)
{
Plan *outerPlan;
TupleDesc tupDesc;
@ -501,9 +514,9 @@ ExecSetTypeInfo(int index,
att->attrelid = 0; /* dummy value */
if (attName != (char *) NULL)
strNcpy(att->attname.data, attName, NAMEDATALEN-1);
strNcpy(att->attname.data, attName, NAMEDATALEN - 1);
else
memset(att->attname.data,0,NAMEDATALEN);
memset(att->attname.data, 0, NAMEDATALEN);
att->atttypid = typeID;
att->attdefrel = 0; /* dummy value */
@ -556,12 +569,12 @@ ExecFreeTypeInfo(TupleDesc typeInfo)
* ----------------------------------------------------------------
*/
TupleDesc
QueryDescGetTypeInfo(QueryDesc *queryDesc)
QueryDescGetTypeInfo(QueryDesc * queryDesc)
{
Plan *plan;
TupleDesc tupleType;
List *targetList;
AttrInfo *attinfo = (AttrInfo *)palloc(sizeof(AttrInfo));
AttrInfo *attinfo = (AttrInfo *) palloc(sizeof(AttrInfo));
plan = queryDesc->plantree;
tupleType = (TupleDesc) ExecGetTupType(plan);
@ -575,6 +588,7 @@ QueryDescGetTypeInfo(QueryDesc *queryDesc)
attinfo->attrs = tupleType->attrs;
return attinfo;
}
#endif
/* ----------------------------------------------------------------
@ -594,7 +608,7 @@ QueryDescGetTypeInfo(QueryDesc *queryDesc)
static void
ExecGetIndexKeyInfo(IndexTupleForm indexTuple,
int *numAttsOutP,
AttrNumber **attsOutP,
AttrNumber ** attsOutP,
FuncIndexInfoPtr fInfoP)
{
int i;
@ -605,7 +619,8 @@ ExecGetIndexKeyInfo(IndexTupleForm indexTuple,
* check parameters
* ----------------
*/
if (numAttsOutP == NULL && attsOutP == NULL) {
if (numAttsOutP == NULL && attsOutP == NULL)
{
elog(DEBUG, "ExecGetIndexKeyInfo: %s",
"invalid parameters: numAttsOutP and attsOutP must be non-NULL");
}
@ -621,7 +636,7 @@ ExecGetIndexKeyInfo(IndexTupleForm indexTuple,
* ----------------
*/
numKeys = 0;
for (i=0; i<8 && indexTuple->indkey[i] != 0; i++)
for (i = 0; i < 8 && indexTuple->indkey[i] != 0; i++)
numKeys++;
/* ----------------
@ -633,14 +648,16 @@ ExecGetIndexKeyInfo(IndexTupleForm indexTuple,
* single return value).
* ----------------
*/
if (FIgetProcOid(fInfoP) != InvalidOid) {
if (FIgetProcOid(fInfoP) != InvalidOid)
{
FIsetnArgs(fInfoP, numKeys);
(*numAttsOutP) = 1;
}
else
(*numAttsOutP) = numKeys;
if (numKeys < 1) {
if (numKeys < 1)
{
elog(DEBUG, "ExecGetIndexKeyInfo: %s",
"all index key attribute numbers are zero!");
(*attsOutP) = NULL;
@ -653,10 +670,10 @@ ExecGetIndexKeyInfo(IndexTupleForm indexTuple,
*/
CXT1_printf("ExecGetIndexKeyInfo: context is %d\n", CurrentMemoryContext);
attKeys = (AttrNumber*)
attKeys = (AttrNumber *)
palloc(numKeys * sizeof(AttrNumber));
for (i=0; i<numKeys; i++)
for (i = 0; i < numKeys; i++)
attKeys[i] = indexTuple->indkey[i];
/* ----------------
@ -689,7 +706,7 @@ ExecGetIndexKeyInfo(IndexTupleForm indexTuple,
*/
void
ExecOpenIndices(Oid resultRelationOid,
RelationInfo *resultRelationInfo)
RelationInfo * resultRelationInfo)
{
Relation indexRd;
HeapScanDesc indexSd;
@ -749,10 +766,11 @@ ExecOpenIndices(Oid resultRelationOid,
fiList = NIL;
predList = NIL;
while(tuple = heap_getnext(indexSd, /* scan desc */
while (tuple = heap_getnext(indexSd, /* scan desc */
false, /* scan backward flag */
NULL), /* return: buffer */
HeapTupleIsValid(tuple)) {
HeapTupleIsValid(tuple))
{
/* ----------------
* For each index relation we find, extract the information
@ -768,7 +786,7 @@ ExecOpenIndices(Oid resultRelationOid,
* allocate space for functional index information.
* ----------------
*/
fInfoP = (FuncIndexInfoPtr)palloc( sizeof(*fInfoP) );
fInfoP = (FuncIndexInfoPtr) palloc(sizeof(*fInfoP));
/* ----------------
* next get the index key information from the tuple
@ -783,11 +801,14 @@ ExecOpenIndices(Oid resultRelationOid,
* next get the index predicate from the tuple
* ----------------
*/
if (VARSIZE(&indexStruct->indpred) != 0) {
if (VARSIZE(&indexStruct->indpred) != 0)
{
predString = fmgr(F_TEXTOUT, &indexStruct->indpred);
predicate = (PredInfo*)stringToNode(predString);
predicate = (PredInfo *) stringToNode(predString);
pfree(predString);
} else {
}
else
{
predicate = NULL;
}
@ -816,7 +837,8 @@ ExecOpenIndices(Oid resultRelationOid,
* ----------------
*/
len = length(oidList);
if (len > 0) {
if (len > 0)
{
/* ----------------
* allocate space for relation descs
* ----------------
@ -830,13 +852,15 @@ ExecOpenIndices(Oid resultRelationOid,
* ----------------
*/
CXT1_printf("ExecOpenIndices: context is %d\n", CurrentMemoryContext);
indexInfoArray = (IndexInfo**)
palloc(len * sizeof(IndexInfo*));
indexInfoArray = (IndexInfo **)
palloc(len * sizeof(IndexInfo *));
for (i=0; i<len; i++) {
for (i = 0; i < len; i++)
{
IndexInfo *ii = makeNode(IndexInfo);
ii->ii_NumKeyAttributes = 0;
ii->ii_KeyAttributeNumbers = (AttrNumber*) NULL;
ii->ii_KeyAttributeNumbers = (AttrNumber *) NULL;
ii->ii_FuncIndexInfo = (FuncIndexInfoPtr) NULL;
ii->ii_Predicate = NULL;
indexInfoArray[i] = ii;
@ -849,7 +873,8 @@ ExecOpenIndices(Oid resultRelationOid,
* ----------------
*/
i = 0;
foreach (indexoid, oidList) {
foreach(indexoid, oidList)
{
Relation indexDesc;
indexOid = lfirsti(indexoid);
@ -872,25 +897,30 @@ ExecOpenIndices(Oid resultRelationOid,
* ----------------
*/
i = 0;
foreach (numkeys, nkeyList) {
foreach(numkeys, nkeyList)
{
numKeyAtts = lfirsti(numkeys);
indexInfoArray[i++]->ii_NumKeyAttributes = numKeyAtts;
}
i = 0;
foreach (indexkeys, keyList) {
indexKeyAtts = (AttrNumber*) lfirst(indexkeys);
foreach(indexkeys, keyList)
{
indexKeyAtts = (AttrNumber *) lfirst(indexkeys);
indexInfoArray[i++]->ii_KeyAttributeNumbers = indexKeyAtts;
}
i = 0;
foreach (indexfuncs, fiList) {
FuncIndexInfoPtr fiP = (FuncIndexInfoPtr)lfirst(indexfuncs);
foreach(indexfuncs, fiList)
{
FuncIndexInfoPtr fiP = (FuncIndexInfoPtr) lfirst(indexfuncs);
indexInfoArray[i++]->ii_FuncIndexInfo = fiP;
}
i = 0;
foreach (indexpreds, predList) {
foreach(indexpreds, predList)
{
indexInfoArray[i++]->ii_Predicate = lfirst(indexpreds);
}
/* ----------------
@ -922,7 +952,7 @@ ExecOpenIndices(Oid resultRelationOid,
* ----------------------------------------------------------------
*/
void
ExecCloseIndices(RelationInfo *resultRelationInfo)
ExecCloseIndices(RelationInfo * resultRelationInfo)
{
int i;
int numIndices;
@ -931,9 +961,10 @@ ExecCloseIndices(RelationInfo *resultRelationInfo)
numIndices = resultRelationInfo->ri_NumIndices;
relationDescs = resultRelationInfo->ri_IndexRelationDescs;
for (i=0; i<numIndices; i++)
for (i = 0; i < numIndices; i++)
if (relationDescs[i] != NULL)
index_close(relationDescs[i]);
/*
* XXX should free indexInfo array here too.
*/
@ -953,7 +984,7 @@ IndexTuple
ExecFormIndexTuple(HeapTuple heapTuple,
Relation heapRelation,
Relation indexRelation,
IndexInfo *indexInfo)
IndexInfo * indexInfo)
{
IndexTuple indexTuple;
TupleDesc heapDescriptor;
@ -999,7 +1030,8 @@ ExecFormIndexTuple(HeapTuple heapTuple,
keyAttributeNumbers, /* array of att nums to extract */
heapTuple, /* tuple from base relation */
heapDescriptor, /* heap tuple's descriptor */
InvalidBuffer, /* buffer associated with heap tuple */
InvalidBuffer, /* buffer associated with heap
* tuple */
datum, /* return: array of attributes */
nulls, /* return: array of char's */
fInfoP); /* functional index information */
@ -1022,6 +1054,7 @@ ExecFormIndexTuple(HeapTuple heapTuple,
return indexTuple;
}
#endif
/* ----------------------------------------------------------------
@ -1037,9 +1070,9 @@ ExecFormIndexTuple(HeapTuple heapTuple,
* ----------------------------------------------------------------
*/
void
ExecInsertIndexTuples(TupleTableSlot *slot,
ExecInsertIndexTuples(TupleTableSlot * slot,
ItemPointer tupleid,
EState *estate,
EState * estate,
bool is_update)
{
HeapTuple heapTuple;
@ -1078,19 +1111,23 @@ ExecInsertIndexTuples(TupleTableSlot *slot,
* ----------------
*/
econtext = NULL;
for (i=0; i<numIndices; i++) {
if (relationDescs[i] == NULL) continue;
for (i = 0; i < numIndices; i++)
{
if (relationDescs[i] == NULL)
continue;
indexInfo = indexInfoArray[i];
predicate = indexInfo->ii_Predicate;
if (predicate != NULL) {
if (econtext == NULL) {
if (predicate != NULL)
{
if (econtext == NULL)
{
econtext = makeNode(ExprContext);
}
econtext->ecxt_scantuple = slot;
/* Skip this index-update if the predicate isn't satisfied */
satisfied = ExecQual((List*)predicate, econtext);
satisfied = ExecQual((List *) predicate, econtext);
if (satisfied == false)
continue;
}
@ -1104,13 +1141,15 @@ ExecInsertIndexTuples(TupleTableSlot *slot,
fInfoP = indexInfo->ii_FuncIndexInfo;
datum = (Datum *) palloc(numberOfAttributes * sizeof *datum);
nulls = (char *) palloc(numberOfAttributes * sizeof *nulls);
heapDescriptor = (TupleDesc)RelationGetTupleDescriptor(heapRelation);
heapDescriptor = (TupleDesc) RelationGetTupleDescriptor(heapRelation);
FormIndexDatum(numberOfAttributes, /* num attributes */
keyAttributeNumbers, /* array of att nums to extract */
keyAttributeNumbers, /* array of att nums to
* extract */
heapTuple, /* tuple from base relation */
heapDescriptor, /* heap tuple's descriptor */
InvalidBuffer, /* buffer associated with heap tuple */
InvalidBuffer, /* buffer associated with heap
* tuple */
datum, /* return: array of attributes */
nulls, /* return: array of char's */
fInfoP); /* functional index information */
@ -1132,9 +1171,11 @@ ExecInsertIndexTuples(TupleTableSlot *slot,
* free index tuple after insertion
* ----------------
*/
if (result) pfree(result);
if (result)
pfree(result);
}
if (econtext != NULL) pfree(econtext);
if (econtext != NULL)
pfree(econtext);
}
/* ----------------------------------------------------------------
@ -1145,8 +1186,8 @@ ExecInsertIndexTuples(TupleTableSlot *slot,
* ----------------------------------------------------------------
*/
void
setVarAttrLenForCreateTable(TupleDesc tupType, List *targetList,
List *rangeTable)
setVarAttrLenForCreateTable(TupleDesc tupType, List * targetList,
List * rangeTable)
{
List *tl;
TargetEntry *tle;
@ -1155,23 +1196,26 @@ setVarAttrLenForCreateTable(TupleDesc tupType, List *targetList,
tl = targetList;
for (varno = 0; varno < tupType->natts; varno++) {
for (varno = 0; varno < tupType->natts; varno++)
{
tle = lfirst(tl);
if (tupType->attrs[varno]->atttypid == BPCHAROID ||
tupType->attrs[varno]->atttypid == VARCHAROID) {
tupType->attrs[varno]->atttypid == VARCHAROID)
{
expr = tle->expr;
if (expr && IsA(expr,Var)) {
if (expr && IsA(expr, Var))
{
Var *var;
RangeTblEntry *rtentry;
Relation rd;
var = (Var *)expr;
var = (Var *) expr;
rtentry = rt_fetch(var->varnoold, rangeTable);
rd = heap_open(rtentry->relid);
/* set length to that defined in relation */
tupType->attrs[varno]->attlen =
(*rd->rd_att->attrs[var->varoattno-1]).attlen;
(*rd->rd_att->attrs[var->varoattno - 1]).attlen;
heap_close(rd);
}
else
@ -1196,11 +1240,13 @@ resetVarAttrLenForCreateTable(TupleDesc tupType)
{
int varno;
for (varno = 0; varno < tupType->natts; varno++) {
for (varno = 0; varno < tupType->natts; varno++)
{
if (tupType->attrs[varno]->atttypid == BPCHAROID ||
tupType->attrs[varno]->atttypid == VARCHAROID)
/* set length to original -1 */
tupType->attrs[varno]->attlen = -1;
}
}
#endif

View File

@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/executor/functions.c,v 1.7 1997/08/29 09:02:50 vadim Exp $
* $Header: /cvsroot/pgsql/src/backend/executor/functions.c,v 1.8 1997/09/07 04:41:27 momjian Exp $
*
*-------------------------------------------------------------------------
*/
@ -41,9 +41,13 @@
#undef new
typedef enum {F_EXEC_START, F_EXEC_RUN, F_EXEC_DONE} ExecStatus;
typedef enum
{
F_EXEC_START, F_EXEC_RUN, F_EXEC_DONE
} ExecStatus;
typedef struct local_es {
typedef struct local_es
{
QueryDesc *qd;
EState *estate;
struct local_es *next;
@ -53,25 +57,29 @@ typedef struct local_es {
#define LAST_POSTQUEL_COMMAND(es) ((es)->next == (execution_state *)NULL)
/* non-export function prototypes */
static TupleDesc postquel_start(execution_state *es);
static execution_state *init_execution_state(FunctionCachePtr fcache,
static TupleDesc postquel_start(execution_state * es);
static execution_state *
init_execution_state(FunctionCachePtr fcache,
char *args[]);
static TupleTableSlot *postquel_getnext(execution_state *es);
static void postquel_end(execution_state *es);
static void postquel_sub_params(execution_state *es, int nargs,
char *args[], bool *nullV);
static Datum postquel_execute(execution_state *es, FunctionCachePtr fcache,
List *fTlist, char **args, bool *isNull);
static TupleTableSlot *postquel_getnext(execution_state * es);
static void postquel_end(execution_state * es);
static void
postquel_sub_params(execution_state * es, int nargs,
char *args[], bool * nullV);
static Datum
postquel_execute(execution_state * es, FunctionCachePtr fcache,
List * fTlist, char **args, bool * isNull);
Datum
ProjectAttribute(TupleDesc TD,
TargetEntry *tlist,
TargetEntry * tlist,
HeapTuple tup,
bool *isnullP)
bool * isnullP)
{
Datum val,valueP;
Var *attrVar = (Var *)tlist->expr;
Datum val,
valueP;
Var *attrVar = (Var *) tlist->expr;
AttrNumber attrno = attrVar->varattno;
@ -84,9 +92,9 @@ ProjectAttribute(TupleDesc TD,
return (Datum) NULL;
valueP = datumCopy(val,
TD->attrs[attrno-1]->atttypid,
TD->attrs[attrno-1]->attbyval,
(Size) TD->attrs[attrno-1]->attlen);
TD->attrs[attrno - 1]->atttypid,
TD->attrs[attrno - 1]->attbyval,
(Size) TD->attrs[attrno - 1]->attlen);
return valueP;
}
@ -106,15 +114,16 @@ init_execution_state(FunctionCachePtr fcache,
newes = (execution_state *) palloc(sizeof(execution_state));
nextes = newes;
preves = (execution_state *)NULL;
preves = (execution_state *) NULL;
planTree_list = (List *)
pg_plan(fcache->src, fcache->argOidVect, nargs, &queryTree_list, None);
for (i=0; i < queryTree_list->len; i++) {
for (i = 0; i < queryTree_list->len; i++)
{
EState *estate;
Query *queryTree = (Query*) (queryTree_list->qtrees[i]);
Query *queryTree = (Query *) (queryTree_list->qtrees[i]);
Plan *planTree = lfirst(planTree_list);
if (!nextes)
@ -129,30 +138,32 @@ init_execution_state(FunctionCachePtr fcache,
None);
estate = CreateExecutorState();
if (nargs > 0) {
if (nargs > 0)
{
int i;
ParamListInfo paramLI;
paramLI =
(ParamListInfo)palloc((nargs+1)*sizeof(ParamListInfoData));
(ParamListInfo) palloc((nargs + 1) * sizeof(ParamListInfoData));
memset(paramLI, 0, nargs*sizeof(ParamListInfoData));
memset(paramLI, 0, nargs * sizeof(ParamListInfoData));
estate->es_param_list_info = paramLI;
for (i=0; i<nargs; paramLI++, i++) {
for (i = 0; i < nargs; paramLI++, i++)
{
paramLI->kind = PARAM_NUM;
paramLI->id = i+1;
paramLI->id = i + 1;
paramLI->isnull = false;
paramLI->value = (Datum) NULL;
}
paramLI->kind = PARAM_INVALID;
}
else
estate->es_param_list_info = (ParamListInfo)NULL;
estate->es_param_list_info = (ParamListInfo) NULL;
nextes->estate = estate;
preves = nextes;
nextes = (execution_state *)NULL;
nextes = (execution_state *) NULL;
planTree_list = lnext(planTree_list);
}
@ -161,13 +172,16 @@ init_execution_state(FunctionCachePtr fcache,
}
static TupleDesc
postquel_start(execution_state *es)
postquel_start(execution_state * es)
{
#ifdef FUNC_UTIL_PATCH
/*
* Do nothing for utility commands. (create, destroy...) DZ - 30-8-1996
* Do nothing for utility commands. (create, destroy...) DZ -
* 30-8-1996
*/
if (es->qd->operation == CMD_UTILITY) {
if (es->qd->operation == CMD_UTILITY)
{
return (TupleDesc) NULL;
}
#endif
@ -175,18 +189,22 @@ postquel_start(execution_state *es)
}
static TupleTableSlot *
postquel_getnext(execution_state *es)
postquel_getnext(execution_state * es)
{
int feature;
#ifdef FUNC_UTIL_PATCH
if (es->qd->operation == CMD_UTILITY) {
if (es->qd->operation == CMD_UTILITY)
{
/*
* Process an utility command. (create, destroy...) DZ - 30-8-1996
* Process an utility command. (create, destroy...) DZ -
* 30-8-1996
*/
ProcessUtility(es->qd->parsetree->utilityStmt, es->qd->dest);
if (!LAST_POSTQUEL_COMMAND(es)) CommandCounterIncrement();
return (TupleTableSlot*) NULL;
if (!LAST_POSTQUEL_COMMAND(es))
CommandCounterIncrement();
return (TupleTableSlot *) NULL;
}
#endif
@ -196,13 +214,16 @@ postquel_getnext(execution_state *es)
}
static void
postquel_end(execution_state *es)
postquel_end(execution_state * es)
{
#ifdef FUNC_UTIL_PATCH
/*
* Do nothing for utility commands. (create, destroy...) DZ - 30-8-1996
* Do nothing for utility commands. (create, destroy...) DZ -
* 30-8-1996
*/
if (es->qd->operation == CMD_UTILITY) {
if (es->qd->operation == CMD_UTILITY)
{
return;
}
#endif
@ -210,10 +231,10 @@ postquel_end(execution_state *es)
}
static void
postquel_sub_params(execution_state *es,
postquel_sub_params(execution_state * es,
int nargs,
char *args[],
bool *nullV)
bool * nullV)
{
ParamListInfo paramLI;
EState *estate;
@ -221,10 +242,12 @@ postquel_sub_params(execution_state *es,
estate = es->estate;
paramLI = estate->es_param_list_info;
while (paramLI->kind != PARAM_INVALID) {
if (paramLI->kind == PARAM_NUM) {
while (paramLI->kind != PARAM_INVALID)
{
if (paramLI->kind == PARAM_NUM)
{
Assert(paramLI->id <= nargs);
paramLI->value = (Datum)args[(paramLI->id - 1)];
paramLI->value = (Datum) args[(paramLI->id - 1)];
paramLI->isnull = nullV[(paramLI->id - 1)];
}
paramLI++;
@ -233,33 +256,36 @@ postquel_sub_params(execution_state *es,
static TupleTableSlot *
copy_function_result(FunctionCachePtr fcache,
TupleTableSlot *resultSlot)
TupleTableSlot * resultSlot)
{
TupleTableSlot *funcSlot;
TupleDesc resultTd;
HeapTuple newTuple;
HeapTuple oldTuple;
Assert(! TupIsNull(resultSlot));
Assert(!TupIsNull(resultSlot));
oldTuple = resultSlot->val;
funcSlot = (TupleTableSlot*)fcache->funcSlot;
funcSlot = (TupleTableSlot *) fcache->funcSlot;
if (funcSlot == (TupleTableSlot*)NULL)
if (funcSlot == (TupleTableSlot *) NULL)
return resultSlot;
resultTd = resultSlot->ttc_tupleDescriptor;
/*
* When the funcSlot is NULL we have to initialize the funcSlot's
* tuple descriptor.
*/
if (TupIsNull(funcSlot)) {
int i= 0;
if (TupIsNull(funcSlot))
{
int i = 0;
TupleDesc funcTd = funcSlot->ttc_tupleDescriptor;
while (i < oldTuple->t_natts) {
while (i < oldTuple->t_natts)
{
funcTd->attrs[i] =
(AttributeTupleForm)palloc(ATTRIBUTE_TUPLE_SIZE);
(AttributeTupleForm) palloc(ATTRIBUTE_TUPLE_SIZE);
memmove(funcTd->attrs[i],
resultTd->attrs[i],
ATTRIBUTE_TUPLE_SIZE);
@ -269,24 +295,26 @@ copy_function_result(FunctionCachePtr fcache,
newTuple = heap_copytuple(oldTuple);
return ExecStoreTuple(newTuple,funcSlot,InvalidBuffer,true);
return ExecStoreTuple(newTuple, funcSlot, InvalidBuffer, true);
}
static Datum
postquel_execute(execution_state *es,
postquel_execute(execution_state * es,
FunctionCachePtr fcache,
List *fTlist,
List * fTlist,
char **args,
bool *isNull)
bool * isNull)
{
TupleTableSlot *slot;
Datum value;
#ifdef INDEXSCAN_PATCH
/*
* It's more right place to do it (before postquel_start->ExecutorStart).
* Now ExecutorStart->ExecInitIndexScan->ExecEvalParam works ok.
* (But note: I HOPE we can do it here). - vadim 01/22/97
* It's more right place to do it (before
* postquel_start->ExecutorStart). Now
* ExecutorStart->ExecInitIndexScan->ExecEvalParam works ok. (But
* note: I HOPE we can do it here). - vadim 01/22/97
*/
if (fcache->nargs > 0)
postquel_sub_params(es, fcache->nargs, args, fcache->nullVect);
@ -304,30 +332,34 @@ postquel_execute(execution_state *es,
slot = postquel_getnext(es);
if (TupIsNull(slot)) {
if (TupIsNull(slot))
{
postquel_end(es);
es->status = F_EXEC_DONE;
*isNull = true;
/*
* If this isn't the last command for the function
* we have to increment the command
* counter so that subsequent commands can see changes made
* by previous ones.
* If this isn't the last command for the function we have to
* increment the command counter so that subsequent commands can
* see changes made by previous ones.
*/
if (!LAST_POSTQUEL_COMMAND(es)) CommandCounterIncrement();
return (Datum)NULL;
if (!LAST_POSTQUEL_COMMAND(es))
CommandCounterIncrement();
return (Datum) NULL;
}
if (LAST_POSTQUEL_COMMAND(es)) {
if (LAST_POSTQUEL_COMMAND(es))
{
TupleTableSlot *resSlot;
/*
* Copy the result. copy_function_result is smart enough
* to do nothing when no action is called for. This helps
* reduce the logic and code redundancy here.
* Copy the result. copy_function_result is smart enough to do
* nothing when no action is called for. This helps reduce the
* logic and code redundancy here.
*/
resSlot = copy_function_result(fcache, slot);
if (fTlist != NIL) {
if (fTlist != NIL)
{
HeapTuple tup;
TargetEntry *tle = lfirst(fTlist);
@ -336,34 +368,37 @@ postquel_execute(execution_state *es,
tle,
tup,
isNull);
}else {
value = (Datum)resSlot;
}
else
{
value = (Datum) resSlot;
*isNull = false;
}
/*
* If this is a single valued function we have to end the
* function execution now.
* If this is a single valued function we have to end the function
* execution now.
*/
if (fcache->oneResult) {
if (fcache->oneResult)
{
postquel_end(es);
es->status = F_EXEC_DONE;
}
return value;
}
/*
* If this isn't the last command for the function, we don't
* return any results, but we have to increment the command
* counter so that subsequent commands can see changes made
* by previous ones.
* If this isn't the last command for the function, we don't return
* any results, but we have to increment the command counter so that
* subsequent commands can see changes made by previous ones.
*/
CommandCounterIncrement();
return (Datum)NULL;
return (Datum) NULL;
}
Datum
postquel_function(Func *funcNode, char **args, bool *isNull, bool *isDone)
postquel_function(Func * funcNode, char **args, bool * isNull, bool * isDone)
{
execution_state *es;
Datum result = 0;
@ -371,13 +406,12 @@ postquel_function(Func *funcNode, char **args, bool *isNull, bool *isDone)
CommandId savedId;
/*
* Before we start do anything we must save CurrentScanCommandId
* to restore it before return to upper Executor. Also, we have to
* set CurrentScanCommandId equal to CurrentCommandId.
* - vadim 08/29/97
* Before we start do anything we must save CurrentScanCommandId to
* restore it before return to upper Executor. Also, we have to set
* CurrentScanCommandId equal to CurrentCommandId. - vadim 08/29/97
*/
savedId = GetScanCommandId ();
SetScanCommandId (GetCurrentCommandId ());
savedId = GetScanCommandId();
SetScanCommandId(GetCurrentCommandId());
es = (execution_state *) fcache->func_state;
if (es == NULL)
@ -390,12 +424,13 @@ postquel_function(Func *funcNode, char **args, bool *isNull, bool *isDone)
es = es->next;
Assert(es);
/*
* Execute each command in the function one after another until we're
* executing the final command and get a result or we run out of
* commands.
*/
while (es != (execution_state *)NULL)
while (es != (execution_state *) NULL)
{
result = postquel_execute(es,
fcache,
@ -410,32 +445,34 @@ postquel_function(Func *funcNode, char **args, bool *isNull, bool *isDone)
/*
* If we've gone through every command in this function, we are done.
*/
if (es == (execution_state *)NULL)
if (es == (execution_state *) NULL)
{
/*
* Reset the execution states to start over again
*/
es = (execution_state *)fcache->func_state;
es = (execution_state *) fcache->func_state;
while (es)
{
es->status = F_EXEC_START;
es = es->next;
}
/*
* Let caller know we're finished.
*/
*isDone = true;
SetScanCommandId (savedId);
return (fcache->oneResult) ? result : (Datum)NULL;
SetScanCommandId(savedId);
return (fcache->oneResult) ? result : (Datum) NULL;
}
/*
* If we got a result from a command within the function it has
* to be the final command. All others shouldn't be returing
* anything.
* If we got a result from a command within the function it has to be
* the final command. All others shouldn't be returing anything.
*/
Assert ( LAST_POSTQUEL_COMMAND(es) );
Assert(LAST_POSTQUEL_COMMAND(es));
*isDone = false;
SetScanCommandId (savedId);
SetScanCommandId(savedId);
return result;
}

View File

@ -34,7 +34,8 @@
* AggFuncInfo -
* keeps the transition functions information around
*/
typedef struct AggFuncInfo {
typedef struct AggFuncInfo
{
Oid xfn1_oid;
Oid xfn2_oid;
Oid finalfn_oid;
@ -46,7 +47,7 @@ typedef struct AggFuncInfo {
int finalfn_nargs;
} AggFuncInfo;
static Datum aggGetAttr(TupleTableSlot *tuple, Aggreg *agg, bool *isNull);
static Datum aggGetAttr(TupleTableSlot * tuple, Aggreg * agg, bool * isNull);
/* ---------------------------------------
@ -87,14 +88,16 @@ static Datum aggGetAttr(TupleTableSlot *tuple, Aggreg *agg, bool *isNull);
* ------------------------------------------
*/
TupleTableSlot *
ExecAgg(Agg *node)
ExecAgg(Agg * node)
{
AggState *aggstate;
EState *estate;
Aggreg **aggregates;
Plan *outerPlan;
int i, nagg;
Datum *value1, *value2;
int i,
nagg;
Datum *value1,
*value2;
int *noInitValue;
AggFuncInfo *aggFuncInfo;
long nTuplesAgged = 0;
@ -102,9 +105,11 @@ ExecAgg(Agg *node)
ProjectionInfo *projInfo;
TupleTableSlot *resultSlot;
HeapTuple oneTuple;
char* nulls;
char *nulls;
bool isDone;
bool isNull = FALSE, isNull1 = FALSE, isNull2 = FALSE;
bool isNull = FALSE,
isNull1 = FALSE,
isNull2 = FALSE;
/* ---------------------
* get state info from node
@ -122,13 +127,13 @@ ExecAgg(Agg *node)
value1 = node->aggstate->csstate.cstate.cs_ExprContext->ecxt_values;
nulls = node->aggstate->csstate.cstate.cs_ExprContext->ecxt_nulls;
value2 = (Datum *)palloc(sizeof(Datum) * nagg);
value2 = (Datum *) palloc(sizeof(Datum) * nagg);
memset(value2, 0, sizeof(Datum) * nagg);
aggFuncInfo = (AggFuncInfo *)palloc(sizeof(AggFuncInfo) * nagg);
aggFuncInfo = (AggFuncInfo *) palloc(sizeof(AggFuncInfo) * nagg);
memset(aggFuncInfo, 0, sizeof(AggFuncInfo) * nagg);
noInitValue = (int *)palloc(sizeof(int) * nagg);
noInitValue = (int *) palloc(sizeof(int) * nagg);
memset(noInitValue, 0, sizeof(noInitValue) * nagg);
outerPlan = outerPlan(node);
@ -136,14 +141,21 @@ ExecAgg(Agg *node)
projInfo = aggstate->csstate.cstate.cs_ProjInfo;
for(i = 0; i < nagg; i++) {
for (i = 0; i < nagg; i++)
{
Aggreg *agg;
char *aggname;
HeapTuple aggTuple;
Form_pg_aggregate aggp;
Oid xfn1_oid, xfn2_oid, finalfn_oid;
func_ptr xfn1_ptr, xfn2_ptr, finalfn_ptr;
int xfn1_nargs, xfn2_nargs, finalfn_nargs;
Oid xfn1_oid,
xfn2_oid,
finalfn_oid;
func_ptr xfn1_ptr,
xfn2_ptr,
finalfn_ptr;
int xfn1_nargs,
xfn2_nargs,
finalfn_nargs;
agg = aggregates[i];
@ -156,7 +168,7 @@ ExecAgg(Agg *node)
aggTuple = SearchSysCacheTuple(AGGNAME,
PointerGetDatum(aggname),
ObjectIdGetDatum(agg->basetype),
0,0);
0, 0);
if (!HeapTupleIsValid(aggTuple))
elog(WARN, "ExecAgg: cache lookup failed for aggregate \"%s\"(%s)",
aggname,
@ -167,19 +179,21 @@ ExecAgg(Agg *node)
xfn2_oid = aggp->aggtransfn2;
finalfn_oid = aggp->aggfinalfn;
if (OidIsValid(finalfn_oid)) {
if (OidIsValid(finalfn_oid))
{
fmgr_info(finalfn_oid, &finalfn_ptr, &finalfn_nargs);
aggFuncInfo[i].finalfn_oid = finalfn_oid;
aggFuncInfo[i].finalfn = finalfn_ptr;
aggFuncInfo[i].finalfn_nargs = finalfn_nargs;
}
if (OidIsValid(xfn2_oid)) {
if (OidIsValid(xfn2_oid))
{
fmgr_info(xfn2_oid, &xfn2_ptr, &xfn2_nargs);
aggFuncInfo[i].xfn2_oid = xfn2_oid;
aggFuncInfo[i].xfn2 = xfn2_ptr;
aggFuncInfo[i].xfn2_nargs = xfn2_nargs;
value2[i] = (Datum)AggNameGetInitVal((char*)aggname,
value2[i] = (Datum) AggNameGetInitVal((char *) aggname,
aggp->aggbasetype,
2,
&isNull2);
@ -193,12 +207,13 @@ ExecAgg(Agg *node)
elog(WARN, "ExecAgg: agginitval2 is null");
}
if (OidIsValid(xfn1_oid)) {
if (OidIsValid(xfn1_oid))
{
fmgr_info(xfn1_oid, &xfn1_ptr, &xfn1_nargs);
aggFuncInfo[i].xfn1_oid = xfn1_oid;
aggFuncInfo[i].xfn1 = xfn1_ptr;
aggFuncInfo[i].xfn1_nargs = xfn1_nargs;
value1[i] = (Datum)AggNameGetInitVal((char*)aggname,
value1[i] = (Datum) AggNameGetInitVal((char *) aggname,
aggp->aggbasetype,
1,
&isNull1);
@ -211,7 +226,8 @@ ExecAgg(Agg *node)
* max{} and min{}.)
* ------------------------------------------
*/
if (isNull1) {
if (isNull1)
{
noInitValue[i] = 1;
nulls[i] = 1;
}
@ -222,30 +238,36 @@ ExecAgg(Agg *node)
* for each tuple from the the outer plan, apply all the aggregates
* ----------------
*/
for (;;) {
for (;;)
{
HeapTuple outerTuple = NULL;
TupleTableSlot *outerslot;
isNull = isNull1 = isNull2 = 0;
outerslot = ExecProcNode(outerPlan, (Plan*)node);
if (outerslot) outerTuple = outerslot->val;
if (!HeapTupleIsValid(outerTuple)) {
/* when the outerplan doesn't return a single tuple,
create a dummy heaptuple anyway
because we still need to return a valid aggregate value.
The value returned will be the initial values of the
transition functions */
if (nTuplesAgged == 0) {
outerslot = ExecProcNode(outerPlan, (Plan *) node);
if (outerslot)
outerTuple = outerslot->val;
if (!HeapTupleIsValid(outerTuple))
{
/*
* when the outerplan doesn't return a single tuple, create a
* dummy heaptuple anyway because we still need to return a
* valid aggregate value. The value returned will be the
* initial values of the transition functions
*/
if (nTuplesAgged == 0)
{
TupleDesc tupType;
Datum *tupValue;
char* null_array;
char *null_array;
tupType = aggstate->csstate.css_ScanTupleSlot->ttc_tupleDescriptor;
tupValue = projInfo->pi_tupValue;
/* initially, set all the values to NULL */
null_array = malloc(tupType->natts);
for (i=0;i<tupType->natts;i++)
for (i = 0; i < tupType->natts; i++)
null_array[i] = 'n';
oneTuple = heap_formtuple(tupType, tupValue, null_array);
free(null_array);
@ -253,7 +275,8 @@ ExecAgg(Agg *node)
break;
}
for(i = 0; i < nagg; i++) {
for (i = 0; i < nagg; i++)
{
AttrNumber attnum;
int2 attlen;
Datum newVal = (Datum) NULL;
@ -261,7 +284,7 @@ ExecAgg(Agg *node)
Datum args[2];
Node *tagnode = NULL;
switch(nodeTag(aggregates[i]->target))
switch (nodeTag(aggregates[i]->target))
{
case T_Var:
tagnode = NULL;
@ -270,9 +293,9 @@ ExecAgg(Agg *node)
&isNull);
break;
case T_Expr:
tagnode = ((Expr*)aggregates[i]->target)->oper;
tagnode = ((Expr *) aggregates[i]->target)->oper;
econtext->ecxt_scantuple = outerslot;
newVal = ExecEvalExpr (aggregates[i]->target, econtext,
newVal = ExecEvalExpr(aggregates[i]->target, econtext,
&isNull, NULL);
break;
default:
@ -282,78 +305,88 @@ ExecAgg(Agg *node)
if (isNull)
continue; /* ignore this tuple for this agg */
if (aggfns->xfn1) {
if (noInitValue[i]) {
if (aggfns->xfn1)
{
if (noInitValue[i])
{
int byVal;
/*
* value1 and value2 has not been initialized. This
* is the first non-NULL value. We use it as the
* initial value.
* value1 and value2 has not been initialized. This is
* the first non-NULL value. We use it as the initial
* value.
*/
/* but we can't just use it straight, we have
to make a copy of it since the tuple from which
it came will be freed on the next iteration
of the scan */
if ( tagnode != NULL )
/*
* but we can't just use it straight, we have to make
* a copy of it since the tuple from which it came
* will be freed on the next iteration of the scan
*/
if (tagnode != NULL)
{
FunctionCachePtr fcache_ptr;
if ( nodeTag(tagnode) == T_Func )
fcache_ptr = ((Func*)tagnode)->func_fcache;
if (nodeTag(tagnode) == T_Func)
fcache_ptr = ((Func *) tagnode)->func_fcache;
else
fcache_ptr = ((Oper*)tagnode)->op_fcache;
fcache_ptr = ((Oper *) tagnode)->op_fcache;
attlen = fcache_ptr->typlen;
byVal = fcache_ptr->typbyval;
}
else
{
attnum = ((Var*)aggregates[i]->target)->varattno;
attlen = outerslot->ttc_tupleDescriptor->attrs[attnum-1]->attlen;
byVal = outerslot->ttc_tupleDescriptor->attrs[attnum-1]->attbyval;
attnum = ((Var *) aggregates[i]->target)->varattno;
attlen = outerslot->ttc_tupleDescriptor->attrs[attnum - 1]->attlen;
byVal = outerslot->ttc_tupleDescriptor->attrs[attnum - 1]->attbyval;
}
if (attlen == -1) {
if (attlen == -1)
{
/* variable length */
attlen = VARSIZE((struct varlena*) newVal);
attlen = VARSIZE((struct varlena *) newVal);
}
value1[i] = (Datum)palloc(attlen);
if ( byVal )
value1[i] = (Datum) palloc(attlen);
if (byVal)
value1[i] = newVal;
else
memmove((char*)(value1[i]), (char*)newVal, attlen);
memmove((char *) (value1[i]), (char *) newVal, attlen);
/* value1[i] = newVal; */
noInitValue[i] = 0;
nulls[i] = 0;
} else {
}
else
{
/*
* apply the transition functions.
*/
args[0] = value1[i];
args[1] = newVal;
value1[i] =
(Datum)fmgr_c(aggfns->xfn1, aggfns->xfn1_oid,
aggfns->xfn1_nargs, (FmgrValues *)args,
(Datum) fmgr_c(aggfns->xfn1, aggfns->xfn1_oid,
aggfns->xfn1_nargs, (FmgrValues *) args,
&isNull1);
Assert(!isNull1);
}
}
if (aggfns->xfn2) {
if (aggfns->xfn2)
{
Datum xfn2_val = value2[i];
value2[i] =
(Datum)fmgr_c(aggfns->xfn2, aggfns->xfn2_oid,
(Datum) fmgr_c(aggfns->xfn2, aggfns->xfn2_oid,
aggfns->xfn2_nargs,
(FmgrValues *)&xfn2_val, &isNull2);
(FmgrValues *) & xfn2_val, &isNull2);
Assert(!isNull2);
}
}
/*
* keep this for the projection (we only need one of these -
* all the tuples we aggregate over share the same group column)
* keep this for the projection (we only need one of these - all
* the tuples we aggregate over share the same group column)
*/
if (!oneTuple) {
if (!oneTuple)
{
oneTuple = heap_copytuple(outerslot->val);
}
@ -364,37 +397,54 @@ ExecAgg(Agg *node)
* finalize the aggregate (if necessary), and get the resultant value
* --------------
*/
for(i = 0; i < nagg; i++) {
for (i = 0; i < nagg; i++)
{
char *args[2];
AggFuncInfo *aggfns = &aggFuncInfo[i];
if (noInitValue[i]) {
if (noInitValue[i])
{
/*
* No values found for this agg; return current state.
* This seems to fix behavior for avg() aggregate. -tgl 12/96
* No values found for this agg; return current state. This
* seems to fix behavior for avg() aggregate. -tgl 12/96
*/
} else if (aggfns->finalfn && nTuplesAgged > 0) {
if (aggfns->finalfn_nargs > 1) {
args[0] = (char*)value1[i];
args[1] = (char*)value2[i];
} else if (aggfns->xfn1) {
args[0] = (char*)value1[i];
} else if (aggfns->xfn2) {
args[0] = (char*)value2[i];
} else
}
else if (aggfns->finalfn && nTuplesAgged > 0)
{
if (aggfns->finalfn_nargs > 1)
{
args[0] = (char *) value1[i];
args[1] = (char *) value2[i];
}
else if (aggfns->xfn1)
{
args[0] = (char *) value1[i];
}
else if (aggfns->xfn2)
{
args[0] = (char *) value2[i];
}
else
elog(WARN, "ExecAgg: no valid transition functions??");
value1[i] =
(Datum)fmgr_c(aggfns->finalfn, aggfns->finalfn_oid,
(Datum) fmgr_c(aggfns->finalfn, aggfns->finalfn_oid,
aggfns->finalfn_nargs, (FmgrValues *) args,
&(nulls[i]));
} else if (aggfns->xfn1) {
}
else if (aggfns->xfn1)
{
/*
* value in the right place, ignore. (If you remove this
* case, fix the else part. -ay 2/95)
* value in the right place, ignore. (If you remove this case,
* fix the else part. -ay 2/95)
*/
} else if (aggfns->xfn2) {
}
else if (aggfns->xfn2)
{
value1[i] = value2[i];
} else
}
else
elog(WARN, "ExecAgg: no valid transition functions??");
}
@ -402,10 +452,13 @@ ExecAgg(Agg *node)
* whether the aggregation is done depends on whether we are doing
* aggregation over groups or the entire table
*/
if (nodeTag(outerPlan)==T_Group) {
if (nodeTag(outerPlan) == T_Group)
{
/* aggregation over groups */
aggstate->agg_done = ((Group*)outerPlan)->grpstate->grp_done;
} else {
aggstate->agg_done = ((Group *) outerPlan)->grpstate->grp_done;
}
else
{
aggstate->agg_done = TRUE;
}
@ -435,7 +488,7 @@ ExecAgg(Agg *node)
* -----------------
*/
bool
ExecInitAgg(Agg *node, EState *estate, Plan *parent)
ExecInitAgg(Agg * node, EState * estate, Plan * parent)
{
AggState *aggstate;
Plan *outerPlan;
@ -457,10 +510,11 @@ ExecInitAgg(Agg *node, EState *estate, Plan *parent)
* assign node's base id and create expression context
*/
ExecAssignNodeBaseInfo(estate, &aggstate->csstate.cstate,
(Plan*) parent);
(Plan *) parent);
ExecAssignExprContext(estate, &aggstate->csstate.cstate);
#define AGG_NSLOTS 2
/*
* tuple table initialization
*/
@ -469,16 +523,16 @@ ExecInitAgg(Agg *node, EState *estate, Plan *parent)
econtext = aggstate->csstate.cstate.cs_ExprContext;
econtext->ecxt_values =
(Datum *)palloc(sizeof(Datum) * node->numAgg);
(Datum *) palloc(sizeof(Datum) * node->numAgg);
memset(econtext->ecxt_values, 0, sizeof(Datum) * node->numAgg);
econtext->ecxt_nulls = (char *)palloc(node->numAgg);
econtext->ecxt_nulls = (char *) palloc(node->numAgg);
memset(econtext->ecxt_nulls, 0, node->numAgg);
/*
* initializes child nodes
*/
outerPlan = outerPlan(node);
ExecInitNode(outerPlan, estate, (Plan *)node);
ExecInitNode(outerPlan, estate, (Plan *) node);
/* ----------------
* initialize tuple type.
@ -487,17 +541,17 @@ ExecInitAgg(Agg *node, EState *estate, Plan *parent)
ExecAssignScanTypeFromOuterPlan((Plan *) node, &aggstate->csstate);
/*
* Initialize tuple type for both result and scan.
* This node does no projection
* Initialize tuple type for both result and scan. This node does no
* projection
*/
ExecAssignResultTypeFromTL((Plan*) node, &aggstate->csstate.cstate);
ExecAssignProjectionInfo((Plan*)node, &aggstate->csstate.cstate);
ExecAssignResultTypeFromTL((Plan *) node, &aggstate->csstate.cstate);
ExecAssignProjectionInfo((Plan *) node, &aggstate->csstate.cstate);
return TRUE;
}
int
ExecCountSlotsAgg(Agg *node)
ExecCountSlotsAgg(Agg * node)
{
return ExecCountSlotsNode(outerPlan(node)) +
ExecCountSlotsNode(innerPlan(node)) +
@ -510,7 +564,7 @@ ExecCountSlotsAgg(Agg *node)
* -----------------------
*/
void
ExecEndAgg(Agg *node)
ExecEndAgg(Agg * node)
{
AggState *aggstate;
Plan *outerPlan;
@ -520,7 +574,7 @@ ExecEndAgg(Agg *node)
ExecFreeProjectionInfo(&aggstate->csstate.cstate);
outerPlan = outerPlan(node);
ExecEndNode(outerPlan, (Plan*)node);
ExecEndNode(outerPlan, (Plan *) node);
/* clean up tuple table */
ExecClearTuple(aggstate->csstate.css_ScanTupleSlot);
@ -537,9 +591,9 @@ ExecEndAgg(Agg *node)
* over from the tuple
*/
static Datum
aggGetAttr(TupleTableSlot *slot,
Aggreg *agg,
bool *isNull)
aggGetAttr(TupleTableSlot * slot,
Aggreg * agg,
bool * isNull)
{
Datum result;
AttrNumber attnum;
@ -555,14 +609,15 @@ aggGetAttr(TupleTableSlot *slot,
tuple_type = slot->ttc_tupleDescriptor;
buffer = slot->ttc_buffer;
attnum = ((Var*)agg->target)->varattno;
attnum = ((Var *) agg->target)->varattno;
/*
* If the attribute number is invalid, then we are supposed to
* return the entire tuple, we give back a whole slot so that
* callers know what the tuple looks like.
* If the attribute number is invalid, then we are supposed to return
* the entire tuple, we give back a whole slot so that callers know
* what the tuple looks like.
*/
if (attnum == InvalidAttrNumber) {
if (attnum == InvalidAttrNumber)
{
TupleTableSlot *tempSlot;
TupleDesc td;
HeapTuple tup;
@ -570,7 +625,7 @@ aggGetAttr(TupleTableSlot *slot,
tempSlot = makeNode(TupleTableSlot);
tempSlot->ttc_shouldFree = false;
tempSlot->ttc_descIsNew = true;
tempSlot->ttc_tupleDescriptor = (TupleDesc)NULL,
tempSlot->ttc_tupleDescriptor = (TupleDesc) NULL,
tempSlot->ttc_buffer = InvalidBuffer;
tempSlot->ttc_whichplan = -1;
@ -587,7 +642,7 @@ aggGetAttr(TupleTableSlot *slot,
heap_getattr(heapTuple, /* tuple containing attribute */
buffer, /* buffer associated with tuple */
attnum, /* attribute number of desired attribute */
tuple_type, /* tuple descriptor of tuple */
tuple_type,/* tuple descriptor of tuple */
isNull); /* return: is attribute null? */
/* ----------------

View File

@ -7,7 +7,7 @@
*
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/executor/nodeAppend.c,v 1.5 1997/08/19 21:31:07 momjian Exp $
* $Header: /cvsroot/pgsql/src/backend/executor/nodeAppend.c,v 1.6 1997/09/07 04:41:30 momjian Exp $
*
*-------------------------------------------------------------------------
*/
@ -64,7 +64,7 @@
#include "utils/mcxt.h"
#include "parser/parsetree.h" /* for rt_store() macro */
static bool exec_append_initialize_next(Append *node);
static bool exec_append_initialize_next(Append * node);
/* ----------------------------------------------------------------
* exec-append-initialize-next
@ -76,7 +76,7 @@ static bool exec_append_initialize_next(Append *node);
* ----------------------------------------------------------------
*/
static bool
exec_append_initialize_next(Append *node)
exec_append_initialize_next(Append * node)
{
EState *estate;
AppendState *unionstate;
@ -103,7 +103,8 @@ exec_append_initialize_next(Append *node)
nplans = unionstate->as_nplans;
rtentries = node->unionrtentries;
if (whichplan < 0) {
if (whichplan < 0)
{
/* ----------------
* if scanning in reverse, we start at
* the last scan in the list and then
@ -115,7 +116,9 @@ exec_append_initialize_next(Append *node)
unionstate->as_whichplan = 0;
return FALSE;
} else if (whichplan >= nplans) {
}
else if (whichplan >= nplans)
{
/* ----------------
* as above, end the scan if we go beyond
* the last scan in our list..
@ -124,7 +127,9 @@ exec_append_initialize_next(Append *node)
unionstate->as_whichplan = nplans - 1;
return FALSE;
} else {
}
else
{
/* ----------------
* initialize the scan
* (and update the range table appropriately)
@ -132,7 +137,8 @@ exec_append_initialize_next(Append *node)
* of the Append node??? - jolly )
* ----------------
*/
if (node->unionrelid > 0) {
if (node->unionrelid > 0)
{
rtentry = nth(whichplan, rtentries);
if (rtentry == NULL)
elog(DEBUG, "exec_append_initialize_next: rtentry is nil");
@ -141,14 +147,16 @@ exec_append_initialize_next(Append *node)
rt_store(unionrelid, rangeTable, rtentry);
if (unionstate->as_junkFilter_list) {
if (unionstate->as_junkFilter_list)
{
estate->es_junkFilter =
(JunkFilter*)nth(whichplan,
(JunkFilter *) nth(whichplan,
unionstate->as_junkFilter_list);
}
if (unionstate->as_result_relation_info_list) {
if (unionstate->as_result_relation_info_list)
{
estate->es_result_relation_info =
(RelationInfo*) nth(whichplan,
(RelationInfo *) nth(whichplan,
unionstate->as_result_relation_info_list);
}
result_slot->ttc_whichplan = whichplan;
@ -174,7 +182,7 @@ exec_append_initialize_next(Append *node)
* ----------------------------------------------------------------
*/
bool
ExecInitAppend(Append *node, EState *estate, Plan *parent)
ExecInitAppend(Append * node, EState * estate, Plan * parent)
{
AppendState *unionstate;
int nplans;
@ -199,7 +207,7 @@ ExecInitAppend(Append *node, EState *estate, Plan *parent)
rtentries = node->unionrtentries;
CXT1_printf("ExecInitAppend: context is %d\n", CurrentMemoryContext);
initialized = (bool *)palloc(nplans * sizeof(bool));
initialized = (bool *) palloc(nplans * sizeof(bool));
/* ----------------
* create new AppendState for our append node
@ -234,19 +242,19 @@ ExecInitAppend(Append *node, EState *estate, Plan *parent)
ExecInitResultTupleSlot(estate, &unionstate->cstate);
/*
* If the inherits rtentry is the result relation, we have to make
* a result relation info list for all inheritors so we can update
* their indices and put the result tuples in the right place etc.
* If the inherits rtentry is the result relation, we have to make a
* result relation info list for all inheritors so we can update their
* indices and put the result tuples in the right place etc.
*
* e.g. replace p (age = p.age + 1) from p in person*
*/
if ((es_rri != (RelationInfo*)NULL) &&
if ((es_rri != (RelationInfo *) NULL) &&
(node->unionrelid == es_rri->ri_RangeTableIndex))
{
RelationInfo *rri;
List *rtentryP;
foreach(rtentryP,rtentries)
foreach(rtentryP, rtentries)
{
Oid reloid;
RangeTblEntry *rtentry = lfirst(rtentryP);
@ -259,7 +267,7 @@ ExecInitAppend(Append *node, EState *estate, Plan *parent)
rri->ri_IndexRelationDescs = NULL; /* index descs */
rri->ri_IndexRelationInfo = NULL; /* index key info */
resultList = lcons(rri,resultList);
resultList = lcons(rri, resultList);
ExecOpenIndices(reloid, rri);
}
unionstate->as_result_relation_info_list = resultList;
@ -271,9 +279,11 @@ ExecInitAppend(Append *node, EState *estate, Plan *parent)
*/
junkList = NIL;
for(i = 0; i < nplans ; i++ ) {
for (i = 0; i < nplans; i++)
{
JunkFilter *j;
List *targetList;
/* ----------------
* NOTE: we first modify range table in
* exec_append_initialize_next() and
@ -285,7 +295,7 @@ ExecInitAppend(Append *node, EState *estate, Plan *parent)
exec_append_initialize_next(node);
initNode = (Plan *) nth(i, unionplans);
initialized[i] = ExecInitNode(initNode, estate, (Plan*) node);
initialized[i] = ExecInitNode(initNode, estate, (Plan *) node);
/* ---------------
* Each targetlist in the subplan may need its own junk filter
@ -294,8 +304,9 @@ ExecInitAppend(Append *node, EState *estate, Plan *parent)
* the one that we're looking at the subclasses of
* ---------------
*/
if ((es_rri != (RelationInfo*)NULL) &&
(node->unionrelid == es_rri->ri_RangeTableIndex)) {
if ((es_rri != (RelationInfo *) NULL) &&
(node->unionrelid == es_rri->ri_RangeTableIndex))
{
targetList = initNode->targetlist;
j = (JunkFilter *) ExecInitJunkFilter(targetList);
@ -305,7 +316,7 @@ ExecInitAppend(Append *node, EState *estate, Plan *parent)
}
unionstate->as_junkFilter_list = junkList;
if (junkList != NIL)
estate->es_junkFilter = (JunkFilter *)lfirst(junkList);
estate->es_junkFilter = (JunkFilter *) lfirst(junkList);
/* ----------------
* initialize the return type from the appropriate subplan.
@ -330,14 +341,15 @@ ExecInitAppend(Append *node, EState *estate, Plan *parent)
}
int
ExecCountSlotsAppend(Append *node)
ExecCountSlotsAppend(Append * node)
{
List *plan;
List *unionplans = node->unionplans;
int nSlots = 0;
foreach (plan,unionplans) {
nSlots += ExecCountSlotsNode((Plan *)lfirst(plan));
foreach(plan, unionplans)
{
nSlots += ExecCountSlotsNode((Plan *) lfirst(plan));
}
return nSlots + APPEND_NSLOTS;
}
@ -351,7 +363,7 @@ ExecCountSlotsAppend(Append *node)
* ----------------------------------------------------------------
*/
TupleTableSlot *
ExecProcAppend(Append *node)
ExecProcAppend(Append * node)
{
EState *estate;
AppendState *unionstate;
@ -388,9 +400,10 @@ ExecProcAppend(Append *node)
* get a tuple from the subplan
* ----------------
*/
result = ExecProcNode(subnode, (Plan*)node);
result = ExecProcNode(subnode, (Plan *) node);
if (! TupIsNull(result)) {
if (!TupIsNull(result))
{
/* ----------------
* if the subplan gave us something then place a copy of
* whatever we get into our result slot and return it, else..
@ -399,7 +412,9 @@ ExecProcAppend(Append *node)
return ExecStoreTuple(result->val,
result_slot, result->ttc_buffer, false);
} else {
}
else
{
/* ----------------
* .. go on to the "next" subplan in the appropriate
* direction and try processing again (recursively)
@ -421,11 +436,13 @@ ExecProcAppend(Append *node)
* all of our subplans have been exhausted.
* ----------------
*/
if (exec_append_initialize_next(node)) {
if (exec_append_initialize_next(node))
{
ExecSetSlotDescriptorIsNew(result_slot, true);
return
ExecProcAppend(node);
} else
}
else
return ExecClearTuple(result_slot);
}
}
@ -439,7 +456,7 @@ ExecProcAppend(Append *node)
* ----------------------------------------------------------------
*/
void
ExecEndAppend(Append *node)
ExecEndAppend(Append * node)
{
AppendState *unionstate;
int nplans;
@ -462,9 +479,11 @@ ExecEndAppend(Append *node)
* shut down each of the subscans
* ----------------
*/
for(i = 0; i < nplans; i++) {
if (initialized[i]==TRUE) {
ExecEndNode( (Plan *) nth(i, unionplans), (Plan*)node );
for (i = 0; i < nplans; i++)
{
if (initialized[i] == TRUE)
{
ExecEndNode((Plan *) nth(i, unionplans), (Plan *) node);
}
}
@ -473,10 +492,11 @@ ExecEndAppend(Append *node)
* ----------------
*/
resultRelationInfoList = unionstate->as_result_relation_info_list;
while (resultRelationInfoList != NIL) {
while (resultRelationInfoList != NIL)
{
Relation resultRelationDesc;
resultRelationInfo = (RelationInfo*) lfirst(resultRelationInfoList);
resultRelationInfo = (RelationInfo *) lfirst(resultRelationInfoList);
resultRelationDesc = resultRelationInfo->ri_RelationDesc;
heap_close(resultRelationDesc);
pfree(resultRelationInfo);
@ -485,6 +505,8 @@ ExecEndAppend(Append *node)
if (unionstate->as_result_relation_info_list)
pfree(unionstate->as_result_relation_info_list);
/* XXX should free unionstate->as_rtentries and unionstate->as_junkfilter_list here */
/*
* XXX should free unionstate->as_rtentries and
* unionstate->as_junkfilter_list here
*/
}

View File

@ -13,7 +13,7 @@
* columns. (ie. tuples from the same group are consecutive)
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/executor/nodeGroup.c,v 1.5 1997/01/10 20:17:35 momjian Exp $
* $Header: /cvsroot/pgsql/src/backend/executor/nodeGroup.c,v 1.6 1997/09/07 04:41:31 momjian Exp $
*
*-------------------------------------------------------------------------
*/
@ -28,10 +28,11 @@
#include "executor/executor.h"
#include "executor/nodeGroup.h"
static TupleTableSlot *ExecGroupEveryTuple(Group *node);
static TupleTableSlot *ExecGroupOneTuple(Group *node);
static bool sameGroup(TupleTableSlot *oldslot, TupleTableSlot *newslot,
int numCols, AttrNumber *grpColIdx, TupleDesc tupdesc);
static TupleTableSlot *ExecGroupEveryTuple(Group * node);
static TupleTableSlot *ExecGroupOneTuple(Group * node);
static bool
sameGroup(TupleTableSlot * oldslot, TupleTableSlot * newslot,
int numCols, AttrNumber * grpColIdx, TupleDesc tupdesc);
/* ---------------------------------------
* ExecGroup -
@ -50,7 +51,7 @@ static bool sameGroup(TupleTableSlot *oldslot, TupleTableSlot *newslot,
* ------------------------------------------
*/
TupleTableSlot *
ExecGroup(Group *node)
ExecGroup(Group * node)
{
if (node->tuplePerGroup)
return ExecGroupEveryTuple(node);
@ -63,14 +64,15 @@ ExecGroup(Group *node)
* return every tuple with a NULL between each group
*/
static TupleTableSlot *
ExecGroupEveryTuple(Group *node)
ExecGroupEveryTuple(Group * node)
{
GroupState *grpstate;
EState *estate;
ExprContext *econtext;
HeapTuple outerTuple = NULL;
TupleTableSlot *outerslot, *lastslot;
TupleTableSlot *outerslot,
*lastslot;
ProjectionInfo *projInfo;
TupleTableSlot *resultSlot;
@ -88,7 +90,9 @@ ExecGroupEveryTuple(Group *node)
econtext = grpstate->csstate.cstate.cs_ExprContext;
if (grpstate->grp_useLastTuple) {
if (grpstate->grp_useLastTuple)
{
/*
* we haven't returned last tuple yet because it is not of the
* same group
@ -99,11 +103,14 @@ ExecGroupEveryTuple(Group *node)
grpstate->csstate.css_ScanTupleSlot,
grpstate->grp_lastSlot->ttc_buffer,
false);
} else {
outerslot = ExecProcNode(outerPlan(node), (Plan*)node);
}
else
{
outerslot = ExecProcNode(outerPlan(node), (Plan *) node);
if (outerslot)
outerTuple = outerslot->val;
if (!HeapTupleIsValid(outerTuple)) {
if (!HeapTupleIsValid(outerTuple))
{
grpstate->grp_done = TRUE;
return NULL;
}
@ -118,7 +125,8 @@ ExecGroupEveryTuple(Group *node)
if (lastslot->val != NULL &&
(!sameGroup(lastslot, outerslot,
node->numCols, node->grpColIdx,
ExecGetScanType(&grpstate->csstate)))) {
ExecGetScanType(&grpstate->csstate))))
{
/* ExecGetResultType(&grpstate->csstate.cstate)))) {*/
grpstate->grp_useLastTuple = TRUE;
@ -157,14 +165,15 @@ ExecGroupEveryTuple(Group *node)
* tuples.
*/
static TupleTableSlot *
ExecGroupOneTuple(Group *node)
ExecGroupOneTuple(Group * node)
{
GroupState *grpstate;
EState *estate;
ExprContext *econtext;
HeapTuple outerTuple = NULL;
TupleTableSlot *outerslot, *lastslot;
TupleTableSlot *outerslot,
*lastslot;
ProjectionInfo *projInfo;
TupleTableSlot *resultSlot;
@ -182,16 +191,21 @@ ExecGroupOneTuple(Group *node)
econtext = node->grpstate->csstate.cstate.cs_ExprContext;
if (grpstate->grp_useLastTuple) {
if (grpstate->grp_useLastTuple)
{
grpstate->grp_useLastTuple = FALSE;
ExecStoreTuple(grpstate->grp_lastSlot->val,
grpstate->csstate.css_ScanTupleSlot,
grpstate->grp_lastSlot->ttc_buffer,
false);
} else {
outerslot = ExecProcNode(outerPlan(node), (Plan*)node);
if (outerslot) outerTuple = outerslot->val;
if (!HeapTupleIsValid(outerTuple)) {
}
else
{
outerslot = ExecProcNode(outerPlan(node), (Plan *) node);
if (outerslot)
outerTuple = outerslot->val;
if (!HeapTupleIsValid(outerTuple))
{
grpstate->grp_done = TRUE;
return NULL;
}
@ -205,10 +219,13 @@ ExecGroupOneTuple(Group *node)
/*
* find all tuples that belong to a group
*/
for(;;) {
outerslot = ExecProcNode(outerPlan(node), (Plan*)node);
for (;;)
{
outerslot = ExecProcNode(outerPlan(node), (Plan *) node);
outerTuple = (outerslot) ? outerslot->val : NULL;
if (!HeapTupleIsValid(outerTuple)) {
if (!HeapTupleIsValid(outerTuple))
{
/*
* we have at least one tuple (lastslot) if we reach here
*/
@ -225,7 +242,8 @@ ExecGroupOneTuple(Group *node)
*/
if ((!sameGroup(lastslot, outerslot,
node->numCols, node->grpColIdx,
ExecGetScanType(&grpstate->csstate)))) {
ExecGetScanType(&grpstate->csstate))))
{
/* ExecGetResultType(&grpstate->csstate.cstate)))) {*/
grpstate->grp_useLastTuple = TRUE;
@ -271,7 +289,7 @@ ExecGroupOneTuple(Group *node)
* -----------------
*/
bool
ExecInitGroup(Group *node, EState *estate, Plan *parent)
ExecInitGroup(Group * node, EState * estate, Plan * parent)
{
GroupState *grpstate;
Plan *outerPlan;
@ -293,10 +311,11 @@ ExecInitGroup(Group *node, EState *estate, Plan *parent)
* assign node's base id and create expression context
*/
ExecAssignNodeBaseInfo(estate, &grpstate->csstate.cstate,
(Plan*) parent);
(Plan *) parent);
ExecAssignExprContext(estate, &grpstate->csstate.cstate);
#define GROUP_NSLOTS 2
/*
* tuple table initialization
*/
@ -307,7 +326,7 @@ ExecInitGroup(Group *node, EState *estate, Plan *parent)
* initializes child nodes
*/
outerPlan = outerPlan(node);
ExecInitNode(outerPlan, estate, (Plan *)node);
ExecInitNode(outerPlan, estate, (Plan *) node);
/* ----------------
* initialize tuple type.
@ -316,17 +335,17 @@ ExecInitGroup(Group *node, EState *estate, Plan *parent)
ExecAssignScanTypeFromOuterPlan((Plan *) node, &grpstate->csstate);
/*
* Initialize tuple type for both result and scan.
* This node does no projection
* Initialize tuple type for both result and scan. This node does no
* projection
*/
ExecAssignResultTypeFromTL((Plan*) node, &grpstate->csstate.cstate);
ExecAssignProjectionInfo((Plan*)node, &grpstate->csstate.cstate);
ExecAssignResultTypeFromTL((Plan *) node, &grpstate->csstate.cstate);
ExecAssignProjectionInfo((Plan *) node, &grpstate->csstate.cstate);
return TRUE;
}
int
ExecCountSlotsGroup(Group *node)
ExecCountSlotsGroup(Group * node)
{
return ExecCountSlotsNode(outerPlan(node)) + GROUP_NSLOTS;
}
@ -337,7 +356,7 @@ ExecCountSlotsGroup(Group *node)
* -----------------------
*/
void
ExecEndGroup(Group *node)
ExecEndGroup(Group * node)
{
GroupState *grpstate;
Plan *outerPlan;
@ -347,7 +366,7 @@ ExecEndGroup(Group *node)
ExecFreeProjectionInfo(&grpstate->csstate.cstate);
outerPlan = outerPlan(node);
ExecEndNode(outerPlan, (Plan*)node);
ExecEndNode(outerPlan, (Plan *) node);
/* clean up tuple table */
ExecClearTuple(grpstate->csstate.css_ScanTupleSlot);
@ -361,22 +380,26 @@ ExecEndGroup(Group *node)
* code swiped from nodeUnique.c
*/
static bool
sameGroup(TupleTableSlot *oldslot,
TupleTableSlot *newslot,
sameGroup(TupleTableSlot * oldslot,
TupleTableSlot * newslot,
int numCols,
AttrNumber *grpColIdx,
AttrNumber * grpColIdx,
TupleDesc tupdesc)
{
bool isNull1,isNull2;
char *attr1, *attr2;
char *val1, *val2;
bool isNull1,
isNull2;
char *attr1,
*attr2;
char *val1,
*val2;
int i;
AttrNumber att;
Oid typoutput;
for(i = 0; i < numCols; i++) {
for (i = 0; i < numCols; i++)
{
att = grpColIdx[i];
typoutput = typtoout((Oid)tupdesc->attrs[att-1]->atttypid);
typoutput = typtoout((Oid) tupdesc->attrs[att - 1]->atttypid);
attr1 = heap_getattr(oldslot->val,
InvalidBuffer,
@ -390,20 +413,25 @@ sameGroup(TupleTableSlot *oldslot,
tupdesc,
&isNull2);
if (isNull1 == isNull2) {
if (isNull1 == isNull2)
{
if (isNull1) /* both are null, they are equal */
continue;
val1 = fmgr(typoutput, attr1,
gettypelem(tupdesc->attrs[att-1]->atttypid));
gettypelem(tupdesc->attrs[att - 1]->atttypid));
val2 = fmgr(typoutput, attr2,
gettypelem(tupdesc->attrs[att-1]->atttypid));
gettypelem(tupdesc->attrs[att - 1]->atttypid));
/* now, val1 and val2 are ascii representations so we can
use strcmp for comparison */
if (strcmp(val1,val2) != 0)
/*
* now, val1 and val2 are ascii representations so we can use
* strcmp for comparison
*/
if (strcmp(val1, val2) != 0)
return FALSE;
} else {
}
else
{
/* one is null and the other isn't, they aren't equal */
return FALSE;
}

View File

@ -7,7 +7,7 @@
*
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/executor/nodeHash.c,v 1.10 1997/08/19 21:31:08 momjian Exp $
* $Header: /cvsroot/pgsql/src/backend/executor/nodeHash.c,v 1.11 1997/09/07 04:41:32 momjian Exp $
*
*-------------------------------------------------------------------------
*/
@ -47,9 +47,10 @@ static int HashTBSize;
static void mk_hj_temp(char *tempname);
static int hashFunc(char *key, int len);
static int ExecHashPartition(Hash *node);
static int ExecHashPartition(Hash * node);
static RelativeAddr hashTableAlloc(int size, HashJoinTable hashtable);
static void ExecHashOverflowInsert(HashJoinTable hashtable,
static void
ExecHashOverflowInsert(HashJoinTable hashtable,
HashBucket bucket,
HeapTuple heapTuple);
@ -61,7 +62,7 @@ static void ExecHashOverflowInsert(HashJoinTable hashtable,
* ----------------------------------------------------------------
*/
TupleTableSlot *
ExecHash(Hash *node)
ExecHash(Hash * node)
{
EState *estate;
HashState *hashstate;
@ -93,7 +94,8 @@ ExecHash(Hash *node)
nbatch = hashtable->nbatch;
if (nbatch > 0) { /* if needs hash partition */
if (nbatch > 0)
{ /* if needs hash partition */
innerbatchNames = (RelativeAddr *) ABSADDR(hashtable->innerbatchNames);
/* --------------
@ -101,14 +103,15 @@ ExecHash(Hash *node)
* then open the batch files in the current processes.
* --------------
*/
batches = (File*)palloc(nbatch * sizeof(File));
for (i=0; i<nbatch; i++) {
batches = (File *) palloc(nbatch * sizeof(File));
for (i = 0; i < nbatch; i++)
{
batches[i] = FileNameOpenFile(ABSADDR(innerbatchNames[i]),
O_CREAT | O_RDWR, 0600);
}
hashstate->hashBatches = batches;
batchPos = (RelativeAddr*) ABSADDR(hashtable->innerbatchPos);
batchSizes = (int*) ABSADDR(hashtable->innerbatchSizes);
batchPos = (RelativeAddr *) ABSADDR(hashtable->innerbatchPos);
batchSizes = (int *) ABSADDR(hashtable->innerbatchSizes);
}
/* ----------------
@ -122,8 +125,9 @@ ExecHash(Hash *node)
* get tuple and insert into the hash table
* ----------------
*/
for (;;) {
slot = ExecProcNode(outerNode, (Plan*)node);
for (;;)
{
slot = ExecProcNode(outerNode, (Plan *) node);
if (TupIsNull(slot))
break;
@ -137,10 +141,11 @@ ExecHash(Hash *node)
/*
* end of build phase, flush all the last pages of the batches.
*/
for (i=0; i<nbatch; i++) {
for (i = 0; i < nbatch; i++)
{
if (FileSeek(batches[i], 0L, SEEK_END) < 0)
perror("FileSeek");
if (FileWrite(batches[i],ABSADDR(hashtable->batch)+i*BLCKSZ,BLCKSZ) < 0)
if (FileWrite(batches[i], ABSADDR(hashtable->batch) + i * BLCKSZ, BLCKSZ) < 0)
perror("FileWrite");
NDirectFileWrite++;
}
@ -160,7 +165,7 @@ ExecHash(Hash *node)
* ----------------------------------------------------------------
*/
bool
ExecInitHash(Hash *node, EState *estate, Plan *parent)
ExecInitHash(Hash * node, EState * estate, Plan * parent)
{
HashState *hashstate;
Plan *outerPlan;
@ -205,7 +210,7 @@ ExecInitHash(Hash *node, EState *estate, Plan *parent)
* ----------------
*/
outerPlan = outerPlan(node);
ExecInitNode(outerPlan, estate, (Plan *)node);
ExecInitNode(outerPlan, estate, (Plan *) node);
/* ----------------
* initialize tuple type. no need to initialize projection
@ -219,7 +224,7 @@ ExecInitHash(Hash *node, EState *estate, Plan *parent)
}
int
ExecCountSlotsHash(Hash *node)
ExecCountSlotsHash(Hash * node)
{
return ExecCountSlotsNode(outerPlan(node)) +
ExecCountSlotsNode(innerPlan(node)) +
@ -233,7 +238,7 @@ ExecCountSlotsHash(Hash *node)
* ----------------------------------------------------------------
*/
void
ExecEndHash(Hash *node)
ExecEndHash(Hash * node)
{
HashState *hashstate;
Plan *outerPlan;
@ -260,13 +265,14 @@ ExecEndHash(Hash *node)
* ----------------
*/
outerPlan = outerPlan(node);
ExecEndNode(outerPlan, (Plan*)node);
ExecEndNode(outerPlan, (Plan *) node);
}
static RelativeAddr
hashTableAlloc(int size, HashJoinTable hashtable)
{
RelativeAddr p;
p = hashtable->top;
hashtable->top += size;
return p;
@ -282,7 +288,7 @@ hashTableAlloc(int size, HashJoinTable hashtable)
#define FUDGE_FAC 1.5
HashJoinTable
ExecHashTableCreate(Hash *node)
ExecHashTableCreate(Hash * node)
{
Plan *outerNode;
int nbatch;
@ -303,8 +309,10 @@ ExecHashTableCreate(Hash *node)
RelativeAddr tempname;
nbatch = -1;
HashTBSize = NBuffers/2;
while (nbatch < 0) {
HashTBSize = NBuffers / 2;
while (nbatch < 0)
{
/*
* determine number of batches for the hashjoin
*/
@ -322,15 +330,15 @@ ExecHashTableCreate(Hash *node)
tupsize = outerNode->plan_width + sizeof(HeapTupleData);
/*
* totalbuckets is the total number of hash buckets needed for
* the entire relation
* totalbuckets is the total number of hash buckets needed for the
* entire relation
*/
totalbuckets = ceil((double)ntuples/NTUP_PER_BUCKET);
bucketsize = LONGALIGN (NTUP_PER_BUCKET * tupsize + sizeof(*bucket));
totalbuckets = ceil((double) ntuples / NTUP_PER_BUCKET);
bucketsize = LONGALIGN(NTUP_PER_BUCKET * tupsize + sizeof(*bucket));
/*
* nbuckets is the number of hash buckets for the first pass
* of hybrid hashjoin
* nbuckets is the number of hash buckets for the first pass of hybrid
* hashjoin
*/
nbuckets = (HashTBSize - nbatch) * BLCKSZ / (bucketsize * FUDGE_FAC);
if (totalbuckets < nbuckets)
@ -346,10 +354,11 @@ ExecHashTableCreate(Hash *node)
* in the shared memory. We just palloc it.
* ----------------
*/
hashtable = (HashJoinTable)palloc((HashTBSize+1)*BLCKSZ);
hashtable = (HashJoinTable) palloc((HashTBSize + 1) * BLCKSZ);
shmid = 0;
if (hashtable == NULL) {
if (hashtable == NULL)
{
elog(WARN, "not enough memory for hashjoin.");
}
/* ----------------
@ -362,6 +371,7 @@ ExecHashTableCreate(Hash *node)
hashtable->shmid = shmid;
hashtable->top = sizeof(HashTableData);
hashtable->bottom = HashTBSize * BLCKSZ;
/*
* hashtable->readbuf has to be long aligned!!!
*/
@ -369,16 +379,18 @@ ExecHashTableCreate(Hash *node)
hashtable->nbatch = nbatch;
hashtable->curbatch = 0;
hashtable->pcount = hashtable->nprocess = 0;
if (nbatch > 0) {
if (nbatch > 0)
{
/* ---------------
* allocate and initialize the outer batches
* ---------------
*/
outerbatchNames = (RelativeAddr*)ABSADDR(
outerbatchNames = (RelativeAddr *) ABSADDR(
hashTableAlloc(nbatch * sizeof(RelativeAddr), hashtable));
outerbatchPos = (RelativeAddr*)ABSADDR(
outerbatchPos = (RelativeAddr *) ABSADDR(
hashTableAlloc(nbatch * sizeof(RelativeAddr), hashtable));
for (i=0; i<nbatch; i++) {
for (i = 0; i < nbatch; i++)
{
tempname = hashTableAlloc(12, hashtable);
mk_hj_temp(ABSADDR(tempname));
outerbatchNames[i] = tempname;
@ -390,13 +402,14 @@ ExecHashTableCreate(Hash *node)
* allocate and initialize the inner batches
* ---------------
*/
innerbatchNames = (RelativeAddr*)ABSADDR(
innerbatchNames = (RelativeAddr *) ABSADDR(
hashTableAlloc(nbatch * sizeof(RelativeAddr), hashtable));
innerbatchPos = (RelativeAddr*)ABSADDR(
innerbatchPos = (RelativeAddr *) ABSADDR(
hashTableAlloc(nbatch * sizeof(RelativeAddr), hashtable));
innerbatchSizes = (int*)ABSADDR(
innerbatchSizes = (int *) ABSADDR(
hashTableAlloc(nbatch * sizeof(int), hashtable));
for (i=0; i<nbatch; i++) {
for (i = 0; i < nbatch; i++)
{
tempname = hashTableAlloc(12, hashtable);
mk_hj_temp(ABSADDR(tempname));
innerbatchNames[i] = tempname;
@ -407,29 +420,31 @@ ExecHashTableCreate(Hash *node)
hashtable->innerbatchPos = RELADDR(innerbatchPos);
hashtable->innerbatchSizes = RELADDR(innerbatchSizes);
}
else {
hashtable->outerbatchNames = (RelativeAddr)NULL;
hashtable->outerbatchPos = (RelativeAddr)NULL;
hashtable->innerbatchNames = (RelativeAddr)NULL;
hashtable->innerbatchPos = (RelativeAddr)NULL;
hashtable->innerbatchSizes = (RelativeAddr)NULL;
else
{
hashtable->outerbatchNames = (RelativeAddr) NULL;
hashtable->outerbatchPos = (RelativeAddr) NULL;
hashtable->innerbatchNames = (RelativeAddr) NULL;
hashtable->innerbatchPos = (RelativeAddr) NULL;
hashtable->innerbatchSizes = (RelativeAddr) NULL;
}
hashtable->batch = (RelativeAddr)LONGALIGN(hashtable->top +
hashtable->batch = (RelativeAddr) LONGALIGN(hashtable->top +
bucketsize * nbuckets);
hashtable->overflownext=hashtable->batch + nbatch * BLCKSZ;
hashtable->overflownext = hashtable->batch + nbatch * BLCKSZ;
/* ----------------
* initialize each hash bucket
* ----------------
*/
bucket = (HashBucket)ABSADDR(hashtable->top);
for (i=0; i<nbuckets; i++) {
bucket->top = RELADDR((char*)bucket + sizeof(*bucket));
bucket = (HashBucket) ABSADDR(hashtable->top);
for (i = 0; i < nbuckets; i++)
{
bucket->top = RELADDR((char *) bucket + sizeof(*bucket));
bucket->bottom = bucket->top;
bucket->firstotuple = bucket->lastotuple = -1;
bucket = (HashBucket)LONGALIGN(((char*)bucket + bucketsize));
bucket = (HashBucket) LONGALIGN(((char *) bucket + bucketsize));
}
return(hashtable);
return (hashtable);
}
/* ----------------------------------------------------------------
@ -441,9 +456,9 @@ ExecHashTableCreate(Hash *node)
*/
void
ExecHashTableInsert(HashJoinTable hashtable,
ExprContext *econtext,
Var *hashkey,
File *batches)
ExprContext * econtext,
Var * hashkey,
File * batches)
{
TupleTableSlot *slot;
HeapTuple heapTuple;
@ -457,8 +472,8 @@ ExecHashTableInsert(HashJoinTable hashtable,
char *pos;
nbatch = hashtable->nbatch;
batchPos = (RelativeAddr*)ABSADDR(hashtable->innerbatchPos);
batchSizes = (int*)ABSADDR(hashtable->innerbatchSizes);
batchPos = (RelativeAddr *) ABSADDR(hashtable->innerbatchPos);
batchSizes = (int *) ABSADDR(hashtable->innerbatchSizes);
slot = econtext->ecxt_innertuple;
heapTuple = slot->val;
@ -473,39 +488,42 @@ ExecHashTableInsert(HashJoinTable hashtable,
* decide whether to put the tuple in the hash table or a tmp file
* ----------------
*/
if (bucketno < hashtable->nbuckets) {
if (bucketno < hashtable->nbuckets)
{
/* ---------------
* put the tuple in hash table
* ---------------
*/
bucket = (HashBucket)
(ABSADDR(hashtable->top) + bucketno * hashtable->bucketsize);
if ((char*)LONGALIGN(ABSADDR(bucket->bottom))
-(char*)bucket+heapTuple->t_len > hashtable->bucketsize)
if ((char *) LONGALIGN(ABSADDR(bucket->bottom))
- (char *) bucket + heapTuple->t_len > hashtable->bucketsize)
ExecHashOverflowInsert(hashtable, bucket, heapTuple);
else {
memmove((char*)LONGALIGN(ABSADDR(bucket->bottom)),
else
{
memmove((char *) LONGALIGN(ABSADDR(bucket->bottom)),
heapTuple,
heapTuple->t_len);
bucket->bottom =
((RelativeAddr)LONGALIGN(bucket->bottom) + heapTuple->t_len);
((RelativeAddr) LONGALIGN(bucket->bottom) + heapTuple->t_len);
}
}
else {
else
{
/* -----------------
* put the tuple into a tmp file for other batches
* -----------------
*/
batchno = (float)(bucketno - hashtable->nbuckets)/
(float)(hashtable->totalbuckets - hashtable->nbuckets)
batchno = (float) (bucketno - hashtable->nbuckets) /
(float) (hashtable->totalbuckets - hashtable->nbuckets)
* nbatch;
buffer = ABSADDR(hashtable->batch) + batchno * BLCKSZ;
batchSizes[batchno]++;
pos= (char *)
pos = (char *)
ExecHashJoinSaveTuple(heapTuple,
buffer,
batches[batchno],
(char*)ABSADDR(batchPos[batchno]));
(char *) ABSADDR(batchPos[batchno]));
batchPos[batchno] = RELADDR(pos);
}
}
@ -530,8 +548,8 @@ ExecHashTableDestroy(HashJoinTable hashtable)
*/
int
ExecHashGetBucket(HashJoinTable hashtable,
ExprContext *econtext,
Var *hashkey)
ExprContext * econtext,
Var * hashkey)
{
int bucketno;
Datum keyval;
@ -544,16 +562,17 @@ ExecHashGetBucket(HashJoinTable hashtable,
* ...It's quick hack - use ExecEvalExpr instead of ExecEvalVar:
* hashkey may be T_ArrayRef, not just T_Var. - vadim 04/22/97
*/
keyval = ExecEvalExpr((Node*)hashkey, econtext, &isNull, NULL);
keyval = ExecEvalExpr((Node *) hashkey, econtext, &isNull, NULL);
/*
* keyval could be null, so we better point it to something
* valid before trying to run hashFunc on it. --djm 8/17/96
* keyval could be null, so we better point it to something valid
* before trying to run hashFunc on it. --djm 8/17/96
*/
if(isNull) {
if (isNull)
{
execConstByVal = 0;
execConstLen = 0;
keyval = (Datum)"";
keyval = (Datum) "";
}
/* ------------------
@ -573,7 +592,7 @@ ExecHashGetBucket(HashJoinTable hashtable,
printf("hash(%d) = %d\n", keyval, bucketno);
#endif
return(bucketno);
return (bucketno);
}
/* ----------------------------------------------------------------
@ -592,15 +611,16 @@ ExecHashOverflowInsert(HashJoinTable hashtable,
OverflowTuple firstotuple;
OverflowTuple lastotuple;
firstotuple = (OverflowTuple)ABSADDR(bucket->firstotuple);
lastotuple = (OverflowTuple)ABSADDR(bucket->lastotuple);
firstotuple = (OverflowTuple) ABSADDR(bucket->firstotuple);
lastotuple = (OverflowTuple) ABSADDR(bucket->lastotuple);
/* ----------------
* see if we run out of overflow space
* ----------------
*/
newend = (RelativeAddr)LONGALIGN(hashtable->overflownext + sizeof(*otuple)
newend = (RelativeAddr) LONGALIGN(hashtable->overflownext + sizeof(*otuple)
+ heapTuple->t_len);
if (newend > hashtable->bottom) {
if (newend > hashtable->bottom)
{
#if 0
elog(DEBUG, "hash table out of memory. expanding.");
/* ------------------
@ -611,8 +631,9 @@ ExecHashOverflowInsert(HashJoinTable hashtable,
*/
hashtable->readbuf = hashtable->bottom = 2 * hashtable->bottom;
hashtable =
(HashJoinTable)repalloc(hashtable, hashtable->bottom+BLCKSZ);
if (hashtable == NULL) {
(HashJoinTable) repalloc(hashtable, hashtable->bottom + BLCKSZ);
if (hashtable == NULL)
{
perror("repalloc");
elog(WARN, "can't expand hashtable.");
}
@ -632,11 +653,12 @@ ExecHashOverflowInsert(HashJoinTable hashtable,
* establish the overflow chain
* ----------------
*/
otuple = (OverflowTuple)ABSADDR(hashtable->overflownext);
otuple = (OverflowTuple) ABSADDR(hashtable->overflownext);
hashtable->overflownext = newend;
if (firstotuple == NULL)
bucket->firstotuple = bucket->lastotuple = RELADDR(otuple);
else {
else
{
lastotuple->next = RELADDR(otuple);
bucket->lastotuple = RELADDR(otuple);
}
@ -646,7 +668,7 @@ ExecHashOverflowInsert(HashJoinTable hashtable,
* ----------------
*/
otuple->next = -1;
otuple->tuple = RELADDR(LONGALIGN(((char*)otuple + sizeof(*otuple))));
otuple->tuple = RELADDR(LONGALIGN(((char *) otuple + sizeof(*otuple))));
memmove(ABSADDR(otuple->tuple),
heapTuple,
heapTuple->t_len);
@ -659,11 +681,11 @@ ExecHashOverflowInsert(HashJoinTable hashtable,
* ----------------------------------------------------------------
*/
HeapTuple
ExecScanHashBucket(HashJoinState *hjstate,
ExecScanHashBucket(HashJoinState * hjstate,
HashBucket bucket,
HeapTuple curtuple,
List *hjclauses,
ExprContext *econtext)
List * hjclauses,
ExprContext * econtext)
{
HeapTuple heapTuple;
bool qualResult;
@ -675,36 +697,38 @@ ExecScanHashBucket(HashJoinState *hjstate,
HashJoinTable hashtable;
hashtable = hjstate->hj_HashTable;
firstotuple = (OverflowTuple)ABSADDR(bucket->firstotuple);
lastotuple = (OverflowTuple)ABSADDR(bucket->lastotuple);
firstotuple = (OverflowTuple) ABSADDR(bucket->firstotuple);
lastotuple = (OverflowTuple) ABSADDR(bucket->lastotuple);
/* ----------------
* search the hash bucket
* ----------------
*/
if (curtuple == NULL || curtuple < (HeapTuple)ABSADDR(bucket->bottom)) {
if (curtuple == NULL || curtuple < (HeapTuple) ABSADDR(bucket->bottom))
{
if (curtuple == NULL)
heapTuple = (HeapTuple)
LONGALIGN(ABSADDR(bucket->top));
else
heapTuple = (HeapTuple)
LONGALIGN(((char*)curtuple+curtuple->t_len));
LONGALIGN(((char *) curtuple + curtuple->t_len));
while (heapTuple < (HeapTuple)ABSADDR(bucket->bottom)) {
while (heapTuple < (HeapTuple) ABSADDR(bucket->bottom))
{
inntuple = ExecStoreTuple(heapTuple, /* tuple to store */
hjstate->hj_HashTupleSlot, /* slot */
InvalidBuffer,/* tuple has no buffer */
InvalidBuffer, /* tuple has no buffer */
false); /* do not pfree this tuple */
econtext->ecxt_innertuple = inntuple;
qualResult = ExecQual((List*)hjclauses, econtext);
qualResult = ExecQual((List *) hjclauses, econtext);
if (qualResult)
return heapTuple;
heapTuple = (HeapTuple)
LONGALIGN(((char*)heapTuple+heapTuple->t_len));
LONGALIGN(((char *) heapTuple + heapTuple->t_len));
}
if (firstotuple == NULL)
@ -716,28 +740,32 @@ ExecScanHashBucket(HashJoinState *hjstate,
* search the overflow area of the hash bucket
* ----------------
*/
if (otuple == NULL) {
if (otuple == NULL)
{
curotuple = hjstate->hj_CurOTuple;
otuple = (OverflowTuple)ABSADDR(curotuple->next);
otuple = (OverflowTuple) ABSADDR(curotuple->next);
}
while (otuple != NULL) {
heapTuple = (HeapTuple)ABSADDR(otuple->tuple);
while (otuple != NULL)
{
heapTuple = (HeapTuple) ABSADDR(otuple->tuple);
inntuple = ExecStoreTuple(heapTuple, /* tuple to store */
hjstate->hj_HashTupleSlot, /* slot */
InvalidBuffer, /* SP?? this tuple has no buffer */
InvalidBuffer, /* SP?? this tuple has
* no buffer */
false); /* do not pfree this tuple */
econtext->ecxt_innertuple = inntuple;
qualResult = ExecQual((List*)hjclauses, econtext);
qualResult = ExecQual((List *) hjclauses, econtext);
if (qualResult) {
if (qualResult)
{
hjstate->hj_CurOTuple = otuple;
return heapTuple;
}
otuple = (OverflowTuple)ABSADDR(otuple->next);
otuple = (OverflowTuple) ABSADDR(otuple->next);
}
/* ----------------
@ -761,19 +789,20 @@ hashFunc(char *key, int len)
register unsigned char *k;
/*
* If this is a variable length type, then 'k' points
* to a "struct varlena" and len == -1.
* NOTE:
* VARSIZE returns the "real" data length plus the sizeof the
* "vl_len" attribute of varlena (the length information).
* 'k' points to the beginning of the varlena struct, so
* we have to use "VARDATA" to find the beginning of the "real"
* data.
* If this is a variable length type, then 'k' points to a "struct
* varlena" and len == -1. NOTE: VARSIZE returns the "real" data
* length plus the sizeof the "vl_len" attribute of varlena (the
* length information). 'k' points to the beginning of the varlena
* struct, so we have to use "VARDATA" to find the beginning of the
* "real" data.
*/
if (len == -1) {
if (len == -1)
{
l = VARSIZE(key) - VARHDRSZ;
k = (unsigned char*) VARDATA(key);
} else {
k = (unsigned char *) VARDATA(key);
}
else
{
l = len;
k = (unsigned char *) key;
}
@ -783,7 +812,8 @@ hashFunc(char *key, int len)
/*
* Convert string to integer
*/
while (l--) h = h * PRIME1 ^ (*k++);
while (l--)
h = h * PRIME1 ^ (*k++);
h %= PRIME2;
return (h);
@ -796,7 +826,7 @@ hashFunc(char *key, int len)
* ----------------------------------------------------------------
*/
static int
ExecHashPartition(Hash *node)
ExecHashPartition(Hash * node)
{
Plan *outerNode;
int b;
@ -809,20 +839,20 @@ ExecHashPartition(Hash *node)
*/
outerNode = outerPlan(node);
ntuples = outerNode->plan_size;
if (ntuples == 0) ntuples = 1000;
if (ntuples == 0)
ntuples = 1000;
tupsize = outerNode->plan_width + sizeof(HeapTupleData);
pages = ceil((double)ntuples * tupsize * FUDGE_FAC / BLCKSZ);
pages = ceil((double) ntuples * tupsize * FUDGE_FAC / BLCKSZ);
/*
* if amount of buffer space below hashjoin threshold,
* return negative
* if amount of buffer space below hashjoin threshold, return negative
*/
if (ceil(sqrt((double)pages)) > HashTBSize)
if (ceil(sqrt((double) pages)) > HashTBSize)
return -1;
if (pages <= HashTBSize)
b = 0; /* fit in memory, no partitioning */
else
b = ceil((double)(pages - HashTBSize)/(double)(HashTBSize - 1));
b = ceil((double) (pages - HashTBSize) / (double) (HashTBSize - 1));
return b;
}
@ -840,17 +870,18 @@ ExecHashTableReset(HashJoinTable hashtable, int ntuples)
HashBucket bucket;
hashtable->nbuckets = hashtable->totalbuckets
= ceil((double)ntuples/NTUP_PER_BUCKET);
= ceil((double) ntuples / NTUP_PER_BUCKET);
hashtable->overflownext = hashtable->top + hashtable->bucketsize *
hashtable->nbuckets;
bucket = (HashBucket)ABSADDR(hashtable->top);
for (i=0; i<hashtable->nbuckets; i++) {
bucket->top = RELADDR((char*)bucket + sizeof(*bucket));
bucket = (HashBucket) ABSADDR(hashtable->top);
for (i = 0; i < hashtable->nbuckets; i++)
{
bucket->top = RELADDR((char *) bucket + sizeof(*bucket));
bucket->bottom = bucket->top;
bucket->firstotuple = bucket->lastotuple = -1;
bucket = (HashBucket)((char*)bucket + hashtable->bucketsize);
bucket = (HashBucket) ((char *) bucket + hashtable->bucketsize);
}
hashtable->pcount = hashtable->nprocess;
}
@ -860,9 +891,6 @@ static int hjtmpcnt = 0;
static void
mk_hj_temp(char *tempname)
{
sprintf(tempname, "HJ%d.%d", (int)getpid(), hjtmpcnt);
sprintf(tempname, "HJ%d.%d", (int) getpid(), hjtmpcnt);
hjtmpcnt = (hjtmpcnt + 1) % 1000;
}

View File

@ -7,7 +7,7 @@
*
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/executor/nodeHashjoin.c,v 1.5 1997/08/19 21:31:09 momjian Exp $
* $Header: /cvsroot/pgsql/src/backend/executor/nodeHashjoin.c,v 1.6 1997/09/07 04:41:33 momjian Exp $
*
*-------------------------------------------------------------------------
*/
@ -33,16 +33,17 @@
#include "utils/palloc.h"
static TupleTableSlot *
ExecHashJoinOuterGetTuple(Plan *node, Plan* parent, HashJoinState *hjstate);
ExecHashJoinOuterGetTuple(Plan * node, Plan * parent, HashJoinState * hjstate);
static TupleTableSlot *
ExecHashJoinGetSavedTuple(HashJoinState *hjstate, char *buffer,
File file, TupleTableSlot *tupleSlot, int *block, char **position);
ExecHashJoinGetSavedTuple(HashJoinState * hjstate, char *buffer,
File file, TupleTableSlot * tupleSlot, int *block, char **position);
static int ExecHashJoinGetBatch(int bucketno, HashJoinTable hashtable,
static int
ExecHashJoinGetBatch(int bucketno, HashJoinTable hashtable,
int nbatch);
static int ExecHashJoinNewBatch(HashJoinState *hjstate);
static int ExecHashJoinNewBatch(HashJoinState * hjstate);
@ -56,7 +57,7 @@ static int ExecHashJoinNewBatch(HashJoinState *hjstate);
* ----------------------------------------------------------------
*/
TupleTableSlot * /* return: a tuple or NULL */
ExecHashJoin(HashJoin *node)
ExecHashJoin(HashJoin * node)
{
HashJoinState *hjstate;
EState *estate;
@ -101,7 +102,7 @@ ExecHashJoin(HashJoin *node)
clause = lfirst(hjclauses);
estate = node->join.state;
qual = node->join.qual;
hashNode = (Hash *)innerPlan(node);
hashNode = (Hash *) innerPlan(node);
outerNode = outerPlan(node);
hashPhaseDone = node->hashdone;
@ -121,7 +122,8 @@ ExecHashJoin(HashJoin *node)
*/
econtext = hjstate->jstate.cs_ExprContext;
if (hjstate->jstate.cs_TupFromTlist) {
if (hjstate->jstate.cs_TupFromTlist)
{
TupleTableSlot *result;
bool isDone;
@ -133,9 +135,11 @@ ExecHashJoin(HashJoin *node)
* if this is the first call, build the hash table for inner relation
* ----------------
*/
if (!hashPhaseDone) { /* if the hash phase not completed */
if (!hashPhaseDone)
{ /* if the hash phase not completed */
hashtable = node->hashjointable;
if (hashtable == NULL) { /* if the hash table has not been created */
if (hashtable == NULL)
{ /* if the hash table has not been created */
/* ----------------
* create the hash table
* ----------------
@ -150,7 +154,7 @@ ExecHashJoin(HashJoin *node)
* ----------------
*/
hashNode->hashtable = hashtable;
innerTupleSlot = ExecProcNode((Plan *)hashNode, (Plan*) node);
innerTupleSlot = ExecProcNode((Plan *) hashNode, (Plan *) node);
}
bucket = NULL;
curtuple = NULL;
@ -159,7 +163,8 @@ ExecHashJoin(HashJoin *node)
}
nbatch = hashtable->nbatch;
outerbatches = hjstate->hj_OuterBatches;
if (nbatch > 0 && outerbatches == NULL) { /* if needs hash partition */
if (nbatch > 0 && outerbatches == NULL)
{ /* if needs hash partition */
/* -----------------
* allocate space for file descriptors of outer batch files
* then open the batch files in the current process
@ -167,11 +172,12 @@ ExecHashJoin(HashJoin *node)
*/
innerhashkey = hashNode->hashkey;
hjstate->hj_InnerHashKey = innerhashkey;
outerbatchNames = (RelativeAddr*)
outerbatchNames = (RelativeAddr *)
ABSADDR(hashtable->outerbatchNames);
outerbatches = (File*)
outerbatches = (File *)
palloc(nbatch * sizeof(File));
for (i=0; i<nbatch; i++) {
for (i = 0; i < nbatch; i++)
{
outerbatches[i] = FileNameOpenFile(
ABSADDR(outerbatchNames[i]),
O_CREAT | O_RDWR, 0600);
@ -186,9 +192,9 @@ ExecHashJoin(HashJoin *node)
hjstate->hj_InnerBatches =
hashNode->hashstate->hashBatches;
}
outerbatchPos = (RelativeAddr*)ABSADDR(hashtable->outerbatchPos);
outerbatchPos = (RelativeAddr *) ABSADDR(hashtable->outerbatchPos);
curbatch = hashtable->curbatch;
outerbatchNames = (RelativeAddr*)ABSADDR(hashtable->outerbatchNames);
outerbatchNames = (RelativeAddr *) ABSADDR(hashtable->outerbatchNames);
/* ----------------
* Now get an outer tuple and probe into the hash table for matches
@ -197,20 +203,27 @@ ExecHashJoin(HashJoin *node)
outerTupleSlot = hjstate->jstate.cs_OuterTupleSlot;
outerVar = get_leftop(clause);
bucketno = -1; /* if bucketno remains -1, means use old outer tuple */
if (TupIsNull(outerTupleSlot)) {
bucketno = -1; /* if bucketno remains -1, means use old
* outer tuple */
if (TupIsNull(outerTupleSlot))
{
/*
* if the current outer tuple is nil, get a new one
*/
outerTupleSlot = (TupleTableSlot*)
ExecHashJoinOuterGetTuple(outerNode, (Plan*)node, hjstate);
outerTupleSlot = (TupleTableSlot *)
ExecHashJoinOuterGetTuple(outerNode, (Plan *) node, hjstate);
while (curbatch <= nbatch && TupIsNull(outerTupleSlot))
{
while (curbatch <= nbatch && TupIsNull(outerTupleSlot)) {
/*
* if the current batch runs out, switch to new batch
*/
curbatch = ExecHashJoinNewBatch(hjstate);
if (curbatch > nbatch) {
if (curbatch > nbatch)
{
/*
* when the last batch runs out, clean up
*/
@ -219,9 +232,10 @@ ExecHashJoin(HashJoin *node)
return NULL;
}
else
outerTupleSlot = (TupleTableSlot*)
ExecHashJoinOuterGetTuple(outerNode, (Plan*)node, hjstate);
outerTupleSlot = (TupleTableSlot *)
ExecHashJoinOuterGetTuple(outerNode, (Plan *) node, hjstate);
}
/*
* now we get an outer tuple, find the corresponding bucket for
* this tuple from the hash table
@ -232,25 +246,28 @@ ExecHashJoin(HashJoin *node)
printf("Probing ");
#endif
bucketno = ExecHashGetBucket(hashtable, econtext, outerVar);
bucket=(HashBucket)(ABSADDR(hashtable->top)
bucket = (HashBucket) (ABSADDR(hashtable->top)
+ bucketno * hashtable->bucketsize);
}
for (;;) {
for (;;)
{
/* ----------------
* Now we've got an outer tuple and the corresponding hash bucket,
* but this tuple may not belong to the current batch.
* ----------------
*/
if (curbatch == 0 && bucketno != -1) /* if this is the first pass */
if (curbatch == 0 && bucketno != -1) /* if this is the first
* pass */
batch = ExecHashJoinGetBatch(bucketno, hashtable, nbatch);
else
batch = 0;
if (batch > 0) {
if (batch > 0)
{
/*
* if the current outer tuple does not belong to
* the current batch, save to the tmp file for
* the corresponding batch.
* if the current outer tuple does not belong to the current
* batch, save to the tmp file for the corresponding batch.
*/
buffer = ABSADDR(hashtable->batch) + (batch - 1) * BLCKSZ;
batchno = batch - 1;
@ -261,8 +278,11 @@ ExecHashJoin(HashJoin *node)
outerbatchPos[batchno] = RELADDR(pos);
}
else if (bucket != NULL) {
do {
else if (bucket != NULL)
{
do
{
/*
* scan the hash bucket for matches
*/
@ -272,14 +292,17 @@ ExecHashJoin(HashJoin *node)
hjclauses,
econtext);
if (curtuple != NULL) {
if (curtuple != NULL)
{
/*
* we've got a match, but still need to test qpqual
*/
inntuple = ExecStoreTuple(curtuple,
hjstate->hj_HashTupleSlot,
InvalidBuffer,
false); /* don't pfree this tuple */
false); /* don't pfree this
* tuple */
econtext->ecxt_innertuple = inntuple;
@ -287,7 +310,7 @@ ExecHashJoin(HashJoin *node)
* test to see if we pass the qualification
* ----------------
*/
qualResult = ExecQual((List*)qual, econtext);
qualResult = ExecQual((List *) qual, econtext);
/* ----------------
* if we pass the qual, then save state for next call and
@ -295,7 +318,8 @@ ExecHashJoin(HashJoin *node)
* in the tuple table, and return the slot.
* ----------------
*/
if (qualResult) {
if (qualResult)
{
ProjectionInfo *projInfo;
TupleTableSlot *result;
bool isDone;
@ -320,15 +344,19 @@ ExecHashJoin(HashJoin *node)
* so we free it and get a new outer tuple.
* ----------------
*/
outerTupleSlot = (TupleTableSlot*)
ExecHashJoinOuterGetTuple(outerNode, (Plan*) node, hjstate);
outerTupleSlot = (TupleTableSlot *)
ExecHashJoinOuterGetTuple(outerNode, (Plan *) node, hjstate);
while (curbatch <= nbatch && TupIsNull(outerTupleSlot))
{
while (curbatch <= nbatch && TupIsNull(outerTupleSlot)) {
/*
* if the current batch runs out, switch to new batch
*/
curbatch = ExecHashJoinNewBatch(hjstate);
if (curbatch > nbatch) {
if (curbatch > nbatch)
{
/*
* when the last batch runs out, clean up
*/
@ -337,8 +365,8 @@ ExecHashJoin(HashJoin *node)
return NULL;
}
else
outerTupleSlot = (TupleTableSlot*)
ExecHashJoinOuterGetTuple(outerNode, (Plan*)node, hjstate);
outerTupleSlot = (TupleTableSlot *)
ExecHashJoinOuterGetTuple(outerNode, (Plan *) node, hjstate);
}
/* ----------------
@ -351,7 +379,7 @@ ExecHashJoin(HashJoin *node)
printf("Probing ");
#endif
bucketno = ExecHashGetBucket(hashtable, econtext, outerVar);
bucket=(HashBucket)(ABSADDR(hashtable->top)
bucket = (HashBucket) (ABSADDR(hashtable->top)
+ bucketno * hashtable->bucketsize);
curtuple = NULL;
}
@ -364,7 +392,7 @@ ExecHashJoin(HashJoin *node)
* ----------------------------------------------------------------
*/
bool /* return: initialization status */
ExecInitHashJoin(HashJoin *node, EState *estate, Plan *parent)
ExecInitHashJoin(HashJoin * node, EState * estate, Plan * parent)
{
HashJoinState *hjstate;
Plan *outerNode;
@ -407,11 +435,11 @@ ExecInitHashJoin(HashJoin *node, EState *estate, Plan *parent)
* initializes child nodes
* ----------------
*/
outerNode = outerPlan((Plan *)node);
hashNode = (Hash*)innerPlan((Plan *)node);
outerNode = outerPlan((Plan *) node);
hashNode = (Hash *) innerPlan((Plan *) node);
ExecInitNode(outerNode, estate, (Plan *) node);
ExecInitNode((Plan*)hashNode, estate, (Plan *) node);
ExecInitNode((Plan *) hashNode, estate, (Plan *) node);
/* ----------------
* now for some voodoo. our temporary tuple slot
@ -426,6 +454,7 @@ ExecInitHashJoin(HashJoin *node, EState *estate, Plan *parent)
HashState *hashstate = hashNode->hashstate;
TupleTableSlot *slot =
hashstate->cstate.cs_ResultTupleSlot;
hjstate->hj_HashTupleSlot = slot;
}
hjstate->hj_OuterTupleSlot->ttc_tupleDescriptor =
@ -440,8 +469,8 @@ ExecInitHashJoin(HashJoin *node, EState *estate, Plan *parent)
* initialize tuple type and projection info
* ----------------
*/
ExecAssignResultTypeFromTL((Plan*) node, &hjstate->jstate);
ExecAssignProjectionInfo((Plan*) node, &hjstate->jstate);
ExecAssignResultTypeFromTL((Plan *) node, &hjstate->jstate);
ExecAssignProjectionInfo((Plan *) node, &hjstate->jstate);
/* ----------------
* XXX comment me
@ -450,25 +479,25 @@ ExecInitHashJoin(HashJoin *node, EState *estate, Plan *parent)
node->hashdone = false;
hjstate->hj_HashTable = (HashJoinTable)NULL;
hjstate->hj_HashTableShmId = (IpcMemoryId)0;
hjstate->hj_CurBucket = (HashBucket )NULL;
hjstate->hj_CurTuple = (HeapTuple )NULL;
hjstate->hj_CurOTuple = (OverflowTuple )NULL;
hjstate->hj_InnerHashKey = (Var*)NULL;
hjstate->hj_OuterBatches = (File*)NULL;
hjstate->hj_InnerBatches = (File*)NULL;
hjstate->hj_OuterReadPos = (char*)NULL;
hjstate->hj_OuterReadBlk = (int)0;
hjstate->hj_HashTable = (HashJoinTable) NULL;
hjstate->hj_HashTableShmId = (IpcMemoryId) 0;
hjstate->hj_CurBucket = (HashBucket) NULL;
hjstate->hj_CurTuple = (HeapTuple) NULL;
hjstate->hj_CurOTuple = (OverflowTuple) NULL;
hjstate->hj_InnerHashKey = (Var *) NULL;
hjstate->hj_OuterBatches = (File *) NULL;
hjstate->hj_InnerBatches = (File *) NULL;
hjstate->hj_OuterReadPos = (char *) NULL;
hjstate->hj_OuterReadBlk = (int) 0;
hjstate->jstate.cs_OuterTupleSlot = (TupleTableSlot*) NULL;
hjstate->jstate.cs_OuterTupleSlot = (TupleTableSlot *) NULL;
hjstate->jstate.cs_TupFromTlist = (bool) false;
return TRUE;
}
int
ExecCountSlotsHashJoin(HashJoin *node)
ExecCountSlotsHashJoin(HashJoin * node)
{
return ExecCountSlotsNode(outerPlan(node)) +
ExecCountSlotsNode(innerPlan(node)) +
@ -482,7 +511,7 @@ ExecCountSlotsHashJoin(HashJoin *node)
* ----------------------------------------------------------------
*/
void
ExecEndHashJoin(HashJoin *node)
ExecEndHashJoin(HashJoin * node)
{
HashJoinState *hjstate;
@ -496,7 +525,8 @@ ExecEndHashJoin(HashJoin *node)
* free hash table in case we end plan before all tuples are retrieved
* ---------------
*/
if (hjstate->hj_HashTable) {
if (hjstate->hj_HashTable)
{
ExecHashTableDestroy(hjstate->hj_HashTable);
hjstate->hj_HashTable = NULL;
}
@ -516,8 +546,8 @@ ExecEndHashJoin(HashJoin *node)
* clean up subtrees
* ----------------
*/
ExecEndNode(outerPlan((Plan *) node), (Plan*)node);
ExecEndNode(innerPlan((Plan *) node), (Plan*)node);
ExecEndNode(outerPlan((Plan *) node), (Plan *) node);
ExecEndNode(innerPlan((Plan *) node), (Plan *) node);
/* ----------------
* clean out the tuple table
@ -539,7 +569,7 @@ ExecEndHashJoin(HashJoin *node)
*/
static TupleTableSlot *
ExecHashJoinOuterGetTuple(Plan *node, Plan* parent, HashJoinState *hjstate)
ExecHashJoinOuterGetTuple(Plan * node, Plan * parent, HashJoinState * hjstate)
{
TupleTableSlot *slot;
HashJoinTable hashtable;
@ -553,7 +583,8 @@ ExecHashJoinOuterGetTuple(Plan *node, Plan* parent, HashJoinState *hjstate)
hashtable = hjstate->hj_HashTable;
curbatch = hashtable->curbatch;
if (curbatch == 0) { /* if it is the first pass */
if (curbatch == 0)
{ /* if it is the first pass */
slot = ExecProcNode(node, parent);
return slot;
}
@ -588,10 +619,10 @@ ExecHashJoinOuterGetTuple(Plan *node, Plan* parent, HashJoinState *hjstate)
*/
static TupleTableSlot *
ExecHashJoinGetSavedTuple(HashJoinState *hjstate,
ExecHashJoinGetSavedTuple(HashJoinState * hjstate,
char *buffer,
File file,
TupleTableSlot *tupleSlot,
TupleTableSlot * tupleSlot,
int *block, /* return parameter */
char **position) /* return parameter */
{
@ -602,9 +633,10 @@ ExecHashJoinGetSavedTuple(HashJoinState *hjstate,
HashJoinTable hashtable;
hashtable = hjstate->hj_HashTable;
bufend = buffer + *(long*)buffer;
bufstart = (char*)(buffer + sizeof(long));
if ((*position == NULL) || (*position >= bufend)) {
bufend = buffer + *(long *) buffer;
bufstart = (char *) (buffer + sizeof(long));
if ((*position == NULL) || (*position >= bufend))
{
if (*position == NULL)
(*block) = 0;
else
@ -620,9 +652,9 @@ ExecHashJoinGetSavedTuple(HashJoinState *hjstate,
(*position) = bufstart;
}
heapTuple = (HeapTuple) (*position);
(*position) = (char*)LONGALIGN(*position + heapTuple->t_len);
(*position) = (char *) LONGALIGN(*position + heapTuple->t_len);
return ExecStoreTuple(heapTuple,tupleSlot,InvalidBuffer,false);
return ExecStoreTuple(heapTuple, tupleSlot, InvalidBuffer, false);
}
/* ----------------------------------------------------------------
@ -632,7 +664,7 @@ ExecHashJoinGetSavedTuple(HashJoinState *hjstate,
* ----------------------------------------------------------------
*/
static int
ExecHashJoinNewBatch(HashJoinState *hjstate)
ExecHashJoinNewBatch(HashJoinState * hjstate)
{
File *innerBatches;
File *outerBatches;
@ -660,13 +692,16 @@ ExecHashJoinNewBatch(HashJoinState *hjstate)
* batch-switching.
* ------------------
*/
if (newbatch == 1) {
if (newbatch == 1)
{
/*
* if it is end of the first pass, flush all the last pages for
* the batches.
*/
outerBatches = hjstate->hj_OuterBatches;
for (i=0; i<nbatch; i++) {
for (i = 0; i < nbatch; i++)
{
cc = FileSeek(outerBatches[i], 0L, SEEK_END);
if (cc < 0)
perror("FileSeek");
@ -677,26 +712,31 @@ ExecHashJoinNewBatch(HashJoinState *hjstate)
perror("FileWrite");
}
}
if (newbatch > 1) {
if (newbatch > 1)
{
/*
* remove the previous outer batch
*/
FileUnlink(outerBatches[newbatch - 2]);
}
/*
* rebuild the hash table for the new inner batch
*/
innerBatchSizes = (int*)ABSADDR(hashtable->innerbatchSizes);
innerBatchSizes = (int *) ABSADDR(hashtable->innerbatchSizes);
/* --------------
* skip over empty inner batches
* --------------
*/
while (newbatch <= nbatch && innerBatchSizes[newbatch - 1] == 0) {
FileUnlink(outerBatches[newbatch-1]);
FileUnlink(innerBatches[newbatch-1]);
while (newbatch <= nbatch && innerBatchSizes[newbatch - 1] == 0)
{
FileUnlink(outerBatches[newbatch - 1]);
FileUnlink(innerBatches[newbatch - 1]);
newbatch++;
}
if (newbatch > nbatch) {
if (newbatch > nbatch)
{
hashtable->pcount = hashtable->nprocess;
return newbatch;
@ -712,13 +752,14 @@ ExecHashJoinNewBatch(HashJoinState *hjstate)
while ((slot = ExecHashJoinGetSavedTuple(hjstate,
readBuf,
innerBatches[newbatch-1],
innerBatches[newbatch - 1],
hjstate->hj_HashTupleSlot,
&readBlk,
&readPos))
&& ! TupIsNull(slot)) {
&& !TupIsNull(slot))
{
econtext->ecxt_innertuple = slot;
ExecHashTableInsert(hashtable, econtext, innerhashkey,NULL);
ExecHashTableInsert(hashtable, econtext, innerhashkey, NULL);
/* possible bug - glass */
}
@ -753,13 +794,14 @@ static int
ExecHashJoinGetBatch(int bucketno, HashJoinTable hashtable, int nbatch)
{
int b;
if (bucketno < hashtable->nbuckets || nbatch == 0)
return 0;
b = (float)(bucketno - hashtable->nbuckets) /
(float)(hashtable->totalbuckets - hashtable->nbuckets) *
b = (float) (bucketno - hashtable->nbuckets) /
(float) (hashtable->totalbuckets - hashtable->nbuckets) *
nbatch;
return b+1;
return b + 1;
}
/* ----------------------------------------------------------------
@ -782,13 +824,14 @@ ExecHashJoinSaveTuple(HeapTuple heapTuple,
char *pagebound;
int cc;
pageend = (long*)buffer;
pagestart = (char*)(buffer + sizeof(long));
pageend = (long *) buffer;
pagestart = (char *) (buffer + sizeof(long));
pagebound = buffer + BLCKSZ;
if (position == NULL)
position = pagestart;
if (position + heapTuple->t_len >= pagebound) {
if (position + heapTuple->t_len >= pagebound)
{
cc = FileSeek(file, 0L, SEEK_END);
if (cc < 0)
perror("FileSeek");
@ -800,7 +843,7 @@ ExecHashJoinSaveTuple(HeapTuple heapTuple,
*pageend = 0;
}
memmove(position, heapTuple, heapTuple->t_len);
position = (char*)LONGALIGN(position + heapTuple->t_len);
position = (char *) LONGALIGN(position + heapTuple->t_len);
*pageend = position - buffer;
return position;

View File

@ -7,7 +7,7 @@
*
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/executor/nodeIndexscan.c,v 1.7 1997/03/12 20:58:26 scrappy Exp $
* $Header: /cvsroot/pgsql/src/backend/executor/nodeIndexscan.c,v 1.8 1997/09/07 04:41:35 momjian Exp $
*
*-------------------------------------------------------------------------
*/
@ -55,7 +55,7 @@
#define LEFT_OP 1
#define RIGHT_OP 2
static TupleTableSlot *IndexNext(IndexScan *node);
static TupleTableSlot *IndexNext(IndexScan * node);
/* ----------------------------------------------------------------
* IndexNext
@ -80,7 +80,7 @@ static TupleTableSlot *IndexNext(IndexScan *node);
* ----------------------------------------------------------------
*/
static TupleTableSlot *
IndexNext(IndexScan *node)
IndexNext(IndexScan * node)
{
EState *estate;
CommonScanState *scanstate;
@ -106,7 +106,7 @@ IndexNext(IndexScan *node)
indexstate = node->indxstate;
indexPtr = indexstate->iss_IndexPtr;
scanDescs = indexstate->iss_ScanDescs;
scandesc = scanDescs[ indexPtr ];
scandesc = scanDescs[indexPtr];
heapRelation = scanstate->css_currentRelation;
slot = scanstate->css_ScanTupleSlot;
@ -116,14 +116,16 @@ IndexNext(IndexScan *node)
* ----------------
*/
for(;;) {
for (;;)
{
result = index_getnext(scandesc, direction);
/* ----------------
* if scanning this index succeeded then return the
* appropriate heap tuple.. else return NULL.
* ----------------
*/
if (result) {
if (result)
{
iptr = &result->heap_iptr;
tuple = heap_fetch(heapRelation,
NowTimeQual,
@ -132,7 +134,8 @@ IndexNext(IndexScan *node)
/* be tidy */
pfree(result);
if (tuple == NULL) {
if (tuple == NULL)
{
/* ----------------
* we found a deleted tuple, so keep on scanning..
* ----------------
@ -151,7 +154,7 @@ IndexNext(IndexScan *node)
* ----------------
*/
ExecStoreTuple(tuple, /* tuple to store */
slot, /* slot to store in */
slot,/* slot to store in */
buffer, /* buffer associated with tuple */
false); /* don't pfree */
@ -189,7 +192,7 @@ IndexNext(IndexScan *node)
* ----------------------------------------------------------------
*/
TupleTableSlot *
ExecIndexScan(IndexScan *node)
ExecIndexScan(IndexScan * node)
{
TupleTableSlot *returnTuple;
@ -214,7 +217,7 @@ ExecIndexScan(IndexScan *node)
* ----------------------------------------------------------------
*/
void
ExecIndexReScan(IndexScan *node, ExprContext *exprCtxt, Plan* parent)
ExecIndexReScan(IndexScan * node, ExprContext * exprCtxt, Plan * parent)
{
EState *estate;
IndexScanState *indexstate;
@ -251,10 +254,12 @@ ExecIndexReScan(IndexScan *node, ExprContext *exprCtxt, Plan* parent)
runtimeKeyInfo = (Pointer *) indexstate->iss_RuntimeKeyInfo;
if (runtimeKeyInfo != NULL) {
if (runtimeKeyInfo != NULL)
{
/*
* get the index qualifications and
* recalculate the appropriate values
* get the index qualifications and recalculate the appropriate
* values
*/
indexPtr = indexstate->iss_IndexPtr;
indxqual = node->indxqual;
@ -264,24 +269,33 @@ ExecIndexReScan(IndexScan *node, ExprContext *exprCtxt, Plan* parent)
run_keys = (int *) runtimeKeyInfo[indexPtr];
scan_keys = (ScanKey) scanKeys[indexPtr];
for (j=0; j < n_keys; j++) {
for (j = 0; j < n_keys; j++)
{
/*
* If we have a run-time key, then extract the run-time
* expression and evaluate it with respect to the current
* outer tuple. We then stick the result into the scan
* key.
* outer tuple. We then stick the result into the scan key.
*/
if (run_keys[j] != NO_OP) {
if (run_keys[j] != NO_OP)
{
clause = nth(j, qual);
scanexpr = (run_keys[j] == RIGHT_OP) ?
(Node*) get_rightop(clause) : (Node*) get_leftop(clause) ;
/* pass in isDone but ignore it. We don't iterate in quals */
(Node *) get_rightop(clause) : (Node *) get_leftop(clause);
/*
* pass in isDone but ignore it. We don't iterate in
* quals
*/
scanvalue = (Datum)
ExecEvalExpr(scanexpr, exprCtxt, &isNull, &isDone);
scan_keys[j].sk_argument = scanvalue;
if (isNull) {
if (isNull)
{
scan_keys[j].sk_flags |= SK_ISNULL;
} else {
}
else
{
scan_keys[j].sk_flags &= ~SK_ISNULL;
}
}
@ -291,12 +305,13 @@ ExecIndexReScan(IndexScan *node, ExprContext *exprCtxt, Plan* parent)
/*
* rescans all indices
*
* note: AMrescan assumes only one scan key. This may have
* to change if we ever decide to support multiple keys.
* note: AMrescan assumes only one scan key. This may have to change if
* we ever decide to support multiple keys.
*/
for (i = 0; i < numIndices; i++) {
sdesc = scanDescs[ i ];
skey = scanKeys[ i ];
for (i = 0; i < numIndices; i++)
{
sdesc = scanDescs[i];
skey = scanKeys[i];
index_rescan(sdesc, direction, skey);
}
@ -316,7 +331,7 @@ ExecIndexReScan(IndexScan *node, ExprContext *exprCtxt, Plan* parent)
* ----------------------------------------------------------------
*/
void
ExecEndIndexScan(IndexScan *node)
ExecEndIndexScan(IndexScan * node)
{
CommonScanState *scanstate;
IndexScanState *indexstate;
@ -355,8 +370,9 @@ ExecEndIndexScan(IndexScan *node)
* free the scan keys used in scanning the indices
* ----------------
*/
for (i=0; i<numIndices; i++) {
if (scanKeys[i]!=NULL)
for (i = 0; i < numIndices; i++)
{
if (scanKeys[i] != NULL)
pfree(scanKeys[i]);
}
@ -379,7 +395,7 @@ ExecEndIndexScan(IndexScan *node)
* ----------------------------------------------------------------
*/
void
ExecIndexMarkPos(IndexScan *node)
ExecIndexMarkPos(IndexScan * node)
{
IndexScanState *indexstate;
IndexScanDescPtr indexScanDescs;
@ -389,13 +405,13 @@ ExecIndexMarkPos(IndexScan *node)
indexstate = node->indxstate;
indexPtr = indexstate->iss_IndexPtr;
indexScanDescs = indexstate->iss_ScanDescs;
scanDesc = indexScanDescs[ indexPtr ];
scanDesc = indexScanDescs[indexPtr];
/* ----------------
* XXX access methods don't return marked positions so
* ----------------
*/
IndexScanMarkPosition( scanDesc );
IndexScanMarkPosition(scanDesc);
return;
}
@ -410,7 +426,7 @@ ExecIndexMarkPos(IndexScan *node)
* ----------------------------------------------------------------
*/
void
ExecIndexRestrPos(IndexScan *node)
ExecIndexRestrPos(IndexScan * node)
{
IndexScanState *indexstate;
IndexScanDescPtr indexScanDescs;
@ -420,9 +436,9 @@ ExecIndexRestrPos(IndexScan *node)
indexstate = node->indxstate;
indexPtr = indexstate->iss_IndexPtr;
indexScanDescs = indexstate->iss_ScanDescs;
scanDesc = indexScanDescs[ indexPtr ];
scanDesc = indexScanDescs[indexPtr];
IndexScanRestorePosition( scanDesc );
IndexScanRestorePosition(scanDesc);
}
/* ----------------------------------------------------------------
@ -445,7 +461,7 @@ ExecIndexRestrPos(IndexScan *node)
* ----------------------------------------------------------------
*/
bool
ExecInitIndexScan(IndexScan *node, EState *estate, Plan *parent)
ExecInitIndexScan(IndexScan * node, EState * estate, Plan * parent)
{
IndexScanState *indexstate;
CommonScanState *scanstate;
@ -582,7 +598,8 @@ ExecInitIndexScan(IndexScan *node, EState *estate, Plan *parent)
* build the index scan keys from the index qualification
* ----------------
*/
for (i=0; i < numIndices; i++) {
for (i = 0; i < numIndices; i++)
{
int j;
List *qual;
int n_keys;
@ -592,9 +609,9 @@ ExecInitIndexScan(IndexScan *node, EState *estate, Plan *parent)
qual = nth(i, indxqual);
n_keys = length(qual);
scan_keys = (n_keys <= 0) ? NULL :
(ScanKey)palloc(n_keys * sizeof(ScanKeyData));
(ScanKey) palloc(n_keys * sizeof(ScanKeyData));
run_keys = (n_keys <= 0) ? NULL :
(int *)palloc(n_keys * sizeof(int));
(int *) palloc(n_keys * sizeof(int));
CXT1_printf("ExecInitIndexScan: context is %d\n",
CurrentMemoryContext);
@ -604,7 +621,8 @@ ExecInitIndexScan(IndexScan *node, EState *estate, Plan *parent)
* convert each qual's opclause into a single scan key
* ----------------
*/
for (j=0; j < n_keys; j++) {
for (j = 0; j < n_keys; j++)
{
Expr *clause; /* one part of index qual */
Oper *op; /* operator used in scan.. */
Node *leftop; /* expr on lhs of operator */
@ -614,7 +632,8 @@ ExecInitIndexScan(IndexScan *node, EState *estate, Plan *parent)
int scanvar; /* which var identifies varattno */
AttrNumber varattno = 0; /* att number used in scan */
Oid opid; /* operator id used in scan */
Datum scanvalue = 0; /* value used in scan (if const) */
Datum scanvalue = 0; /* value used in scan (if
* const) */
/* ----------------
* extract clause information from the qualification
@ -622,8 +641,8 @@ ExecInitIndexScan(IndexScan *node, EState *estate, Plan *parent)
*/
clause = nth(j, qual);
op = (Oper*)clause->oper;
if (!IsA(op,Oper))
op = (Oper *) clause->oper;
if (!IsA(op, Oper))
elog(WARN, "ExecInitIndexScan: op not an Oper!");
opid = op->opid;
@ -657,43 +676,51 @@ ExecInitIndexScan(IndexScan *node, EState *estate, Plan *parent)
* determine information in leftop
* ----------------
*/
leftop = (Node*) get_leftop(clause);
leftop = (Node *) get_leftop(clause);
if (IsA(leftop,Var) && var_is_rel((Var*)leftop)) {
if (IsA(leftop, Var) && var_is_rel((Var *) leftop))
{
/* ----------------
* if the leftop is a "rel-var", then it means
* that it is a var node which tells us which
* attribute to use for our scan key.
* ----------------
*/
varattno = ((Var*) leftop)->varattno;
varattno = ((Var *) leftop)->varattno;
scanvar = LEFT_OP;
} else if (IsA(leftop,Const)) {
}
else if (IsA(leftop, Const))
{
/* ----------------
* if the leftop is a const node then it means
* it identifies the value to place in our scan key.
* ----------------
*/
run_keys[ j ] = NO_OP;
scanvalue = ((Const*) leftop)->constvalue;
run_keys[j] = NO_OP;
scanvalue = ((Const *) leftop)->constvalue;
#ifdef INDEXSCAN_PATCH
} else if (IsA(leftop,Param)) {
}
else if (IsA(leftop, Param))
{
bool isnull;
/* ----------------
* if the leftop is a Param node then it means
* it identifies the value to place in our scan key.
* ----------------
*/
run_keys[ j ] = NO_OP;
scanvalue = ExecEvalParam((Param*) leftop,
run_keys[j] = NO_OP;
scanvalue = ExecEvalParam((Param *) leftop,
scanstate->cstate.cs_ExprContext,
&isnull);
if ( isnull )
if (isnull)
flags |= SK_ISNULL;
#endif
} else if (leftop != NULL &&
}
else if (leftop != NULL &&
is_funcclause(leftop) &&
var_is_rel(lfirst(((Expr*)leftop)->args))) {
var_is_rel(lfirst(((Expr *) leftop)->args)))
{
/* ----------------
* if the leftop is a func node then it means
* it identifies the value to place in our scan key.
@ -704,7 +731,9 @@ ExecInitIndexScan(IndexScan *node, EState *estate, Plan *parent)
varattno = 1;
scanvar = LEFT_OP;
} else {
}
else
{
/* ----------------
* otherwise, the leftop contains information usable
* at runtime to figure out the value to place in our
@ -712,7 +741,7 @@ ExecInitIndexScan(IndexScan *node, EState *estate, Plan *parent)
* ----------------
*/
have_runtime_keys = true;
run_keys[ j ] = LEFT_OP;
run_keys[j] = LEFT_OP;
scanvalue = Int32GetDatum((int32) true);
}
@ -720,9 +749,10 @@ ExecInitIndexScan(IndexScan *node, EState *estate, Plan *parent)
* now determine information in rightop
* ----------------
*/
rightop = (Node*) get_rightop(clause);
rightop = (Node *) get_rightop(clause);
if (IsA(rightop,Var) && var_is_rel((Var*)rightop)) {
if (IsA(rightop, Var) && var_is_rel((Var *) rightop))
{
/* ----------------
* here we make sure only one op identifies the
* scan-attribute...
@ -738,35 +768,42 @@ ExecInitIndexScan(IndexScan *node, EState *estate, Plan *parent)
* attribute to use for our scan key.
* ----------------
*/
varattno = ((Var*) rightop)->varattno;
varattno = ((Var *) rightop)->varattno;
scanvar = RIGHT_OP;
} else if (IsA(rightop,Const)) {
}
else if (IsA(rightop, Const))
{
/* ----------------
* if the leftop is a const node then it means
* it identifies the value to place in our scan key.
* ----------------
*/
run_keys[ j ] = NO_OP;
scanvalue = ((Const*) rightop)->constvalue;
run_keys[j] = NO_OP;
scanvalue = ((Const *) rightop)->constvalue;
#ifdef INDEXSCAN_PATCH
} else if (IsA(rightop,Param)) {
}
else if (IsA(rightop, Param))
{
bool isnull;
/* ----------------
* if the rightop is a Param node then it means
* it identifies the value to place in our scan key.
* ----------------
*/
run_keys[ j ] = NO_OP;
scanvalue = ExecEvalParam((Param*) rightop,
run_keys[j] = NO_OP;
scanvalue = ExecEvalParam((Param *) rightop,
scanstate->cstate.cs_ExprContext,
&isnull);
if ( isnull )
if (isnull)
flags |= SK_ISNULL;
#endif
} else if (rightop!=NULL &&
}
else if (rightop != NULL &&
is_funcclause(rightop) &&
var_is_rel(lfirst(((Expr*)rightop)->args))) {
var_is_rel(lfirst(((Expr *) rightop)->args)))
{
/* ----------------
* if the rightop is a func node then it means
* it identifies the value to place in our scan key.
@ -781,7 +818,9 @@ ExecInitIndexScan(IndexScan *node, EState *estate, Plan *parent)
varattno = 1;
scanvar = RIGHT_OP;
} else {
}
else
{
/* ----------------
* otherwise, the leftop contains information usable
* at runtime to figure out the value to place in our
@ -789,7 +828,7 @@ ExecInitIndexScan(IndexScan *node, EState *estate, Plan *parent)
* ----------------
*/
have_runtime_keys = true;
run_keys[ j ] = RIGHT_OP;
run_keys[j] = RIGHT_OP;
scanvalue = Int32GetDatum((int32) true);
}
@ -808,7 +847,8 @@ ExecInitIndexScan(IndexScan *node, EState *estate, Plan *parent)
*/
ScanKeyEntryInitialize(&scan_keys[j],
flags,
varattno, /* attribute number to scan */
varattno, /* attribute number to
* scan */
(RegProcedure) opid, /* reg proc to use */
(Datum) scanvalue); /* constant */
}
@ -817,9 +857,9 @@ ExecInitIndexScan(IndexScan *node, EState *estate, Plan *parent)
* store the key information into our array.
* ----------------
*/
numScanKeys[ i ] = n_keys;
scanKeys[ i ] = scan_keys;
runtimeKeyInfo[ i ] = (Pointer) run_keys;
numScanKeys[i] = n_keys;
scanKeys[i] = scan_keys;
runtimeKeyInfo[i] = (Pointer) run_keys;
}
indexstate->iss_NumIndices = numIndices;
@ -840,11 +880,14 @@ ExecInitIndexScan(IndexScan *node, EState *estate, Plan *parent)
{
indexstate->iss_RuntimeKeyInfo = (Pointer) runtimeKeyInfo;
}
else {
else
{
indexstate->iss_RuntimeKeyInfo = NULL;
for (i=0; i < numIndices; i++) {
for (i = 0; i < numIndices; i++)
{
List *qual;
int n_keys;
qual = nth(i, indxqual);
n_keys = length(qual);
if (n_keys > 0)
@ -878,7 +921,7 @@ ExecInitIndexScan(IndexScan *node, EState *estate, Plan *parent)
direction, /* scan direction */
timeQual, /* time qual */
&currentRelation, /* return: rel desc */
(Pointer *) &currentScanDesc); /* return: scan desc */
(Pointer *) & currentScanDesc); /* return: scan desc */
scanstate->css_currentRelation = currentRelation;
scanstate->css_currentScanDesc = currentScanDesc;
@ -902,20 +945,22 @@ ExecInitIndexScan(IndexScan *node, EState *estate, Plan *parent)
* relation and scan descriptors.
* ----------------
*/
for (i=0; i < numIndices; i++) {
for (i = 0; i < numIndices; i++)
{
Oid indexOid;
indexOid = (Oid)nthi(i, indxid);
indexOid = (Oid) nthi(i, indxid);
if (indexOid != 0) {
if (indexOid != 0)
{
ExecOpenScanR(indexOid, /* relation */
numScanKeys[ i ], /* nkeys */
scanKeys[ i ], /* scan key */
numScanKeys[i], /* nkeys */
scanKeys[i], /* scan key */
true, /* is index */
direction, /* scan direction */
timeQual, /* time qual */
&(relationDescs[ i ]), /* return: rel desc */
(Pointer *) &(scanDescs[ i ]));
&(relationDescs[i]), /* return: rel desc */
(Pointer *) & (scanDescs[i]));
/* return: scan desc */
}
}
@ -933,9 +978,9 @@ ExecInitIndexScan(IndexScan *node, EState *estate, Plan *parent)
}
int
ExecCountSlotsIndexScan(IndexScan *node)
ExecCountSlotsIndexScan(IndexScan * node)
{
return ExecCountSlotsNode(outerPlan((Plan *)node)) +
ExecCountSlotsNode(innerPlan((Plan *)node)) +
return ExecCountSlotsNode(outerPlan((Plan *) node)) +
ExecCountSlotsNode(innerPlan((Plan *) node)) +
INDEXSCAN_NSLOTS;
}

View File

@ -7,7 +7,7 @@
*
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/executor/nodeMaterial.c,v 1.6 1997/08/20 14:53:24 momjian Exp $
* $Header: /cvsroot/pgsql/src/backend/executor/nodeMaterial.c,v 1.7 1997/09/07 04:41:36 momjian Exp $
*
*-------------------------------------------------------------------------
*/
@ -48,7 +48,7 @@
* ----------------------------------------------------------------
*/
TupleTableSlot * /* result tuple from subplan */
ExecMaterial(Material *node)
ExecMaterial(Material * node)
{
EState *estate;
MaterialState *matstate;
@ -77,7 +77,8 @@ ExecMaterial(Material *node)
* ----------------
*/
if (matstate->mat_Flag == false) {
if (matstate->mat_Flag == false)
{
/* ----------------
* set all relations to be scanned in the forward direction
* while creating the temporary relation.
@ -91,13 +92,15 @@ ExecMaterial(Material *node)
* ----------------
*/
tempRelation = matstate->mat_TempRelation;
if (tempRelation == NULL) {
if (tempRelation == NULL)
{
elog(DEBUG, "ExecMaterial: temp relation is NULL! aborting...");
return NULL;
}
currentRelation = matstate->csstate.css_currentRelation;
if (currentRelation == NULL) {
if (currentRelation == NULL)
{
elog(DEBUG, "ExecMaterial: current relation is NULL! aborting...");
return NULL;
}
@ -108,8 +111,9 @@ ExecMaterial(Material *node)
* ----------------
*/
outerNode = outerPlan((Plan *) node);
for (;;) {
slot = ExecProcNode(outerNode, (Plan*) node);
for (;;)
{
slot = ExecProcNode(outerNode, (Plan *) node);
heapTuple = slot->val;
if (heapTuple == NULL)
@ -118,7 +122,7 @@ ExecMaterial(Material *node)
heap_insert(tempRelation, /* relation desc */
heapTuple); /* heap tuple to insert */
ExecClearTuple( slot);
ExecClearTuple(slot);
}
currentRelation = tempRelation;
@ -170,7 +174,7 @@ ExecMaterial(Material *node)
* to call pfree() on it..
* ----------------
*/
slot = (TupleTableSlot *)matstate->csstate.css_ScanTupleSlot;
slot = (TupleTableSlot *) matstate->csstate.css_ScanTupleSlot;
return ExecStoreTuple(heapTuple, /* tuple to store */
slot, /* slot to store in */
@ -184,12 +188,13 @@ ExecMaterial(Material *node)
* ----------------------------------------------------------------
*/
bool /* initialization status */
ExecInitMaterial(Material *node, EState *estate, Plan *parent)
ExecInitMaterial(Material * node, EState * estate, Plan * parent)
{
MaterialState *matstate;
Plan *outerPlan;
TupleDesc tupType;
Relation tempDesc;
/* int len; */
/* ----------------
@ -286,10 +291,10 @@ ExecInitMaterial(Material *node, EState *estate, Plan *parent)
}
int
ExecCountSlotsMaterial(Material *node)
ExecCountSlotsMaterial(Material * node)
{
return ExecCountSlotsNode(outerPlan((Plan *)node)) +
ExecCountSlotsNode(innerPlan((Plan *)node)) +
return ExecCountSlotsNode(outerPlan((Plan *) node)) +
ExecCountSlotsNode(innerPlan((Plan *) node)) +
MATERIAL_NSLOTS;
}
@ -301,7 +306,7 @@ ExecCountSlotsMaterial(Material *node)
* ----------------------------------------------------------------
*/
void
ExecEndMaterial(Material *node)
ExecEndMaterial(Material * node)
{
MaterialState *matstate;
Relation tempRelation;
@ -327,7 +332,7 @@ ExecEndMaterial(Material *node)
* ----------------
*/
outerPlan = outerPlan((Plan *) node);
ExecEndNode(outerPlan, (Plan*) node);
ExecEndNode(outerPlan, (Plan *) node);
/* ----------------
* clean out the tuple table
@ -361,7 +366,7 @@ ExecMaterialMarkPos(Material node)
* they will never return positions for all I know -cim 10/16/89
* ----------------
*/
sdesc = get_css_currentScanDesc((CommonScanState)matstate);
sdesc = get_css_currentScanDesc((CommonScanState) matstate);
heap_markpos(sdesc);
return NIL;
@ -389,8 +394,8 @@ ExecMaterialRestrPos(Material node)
* restore the scan to the previously marked position
* ----------------
*/
sdesc = get_css_currentScanDesc((CommonScanState)matstate);
sdesc = get_css_currentScanDesc((CommonScanState) matstate);
heap_restrpos(sdesc);
}
#endif
#endif

Some files were not shown because too many files have changed in this diff Show More