Ye-old pgindent run. Same 4-space tabs.

This commit is contained in:
Bruce Momjian 2000-04-12 17:17:23 +00:00
parent db4518729d
commit 52f77df613
434 changed files with 24799 additions and 21246 deletions

View File

@ -34,6 +34,7 @@ int32 array_all_int4le(ArrayType *array, int4 value);
int32 array_oideq(ArrayType *array, Oid value); int32 array_oideq(ArrayType *array, Oid value);
int32 array_all_oidne(ArrayType *array, Oid value); int32 array_all_oidne(ArrayType *array, Oid value);
#endif #endif
/* /*

View File

@ -4,7 +4,7 @@
* Functions for the built-in type bit() and varying bit(). * Functions for the built-in type bit() and varying bit().
* *
* IDENTIFICATION * IDENTIFICATION
* $Header: /cvsroot/pgsql/contrib/bit/Attic/varbit.c,v 1.2 2000/04/03 20:56:40 momjian Exp $ * $Header: /cvsroot/pgsql/contrib/bit/Attic/varbit.c,v 1.3 2000/04/12 17:14:21 momjian Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
@ -49,7 +49,8 @@ zpbitin(char *s, int dummy, int32 atttypmod)
bitlen, /* Number of bits in the bit string */ bitlen, /* Number of bits in the bit string */
slen; /* Length of the input string */ slen; /* Length of the input string */
int bit_not_hex = 0;/* 0 = hex string 1=bit string */ int bit_not_hex = 0;/* 0 = hex string 1=bit string */
int bc, ipad; int bc,
ipad;
bits8 x = 0; bits8 x = 0;
@ -70,15 +71,16 @@ zpbitin(char *s, int dummy, int32 atttypmod)
if (!bit_not_hex) if (!bit_not_hex)
bitlen *= 4; bitlen *= 4;
/* Sometimes atttypmod is not supplied. If it is supplied we need to make /*
sure that the bitstring fits. Note that the number of infered bits can * Sometimes atttypmod is not supplied. If it is supplied we need to
be larger than the number of actual bits needed, but only if we are * make sure that the bitstring fits. Note that the number of infered
reading a hex string and not by more than 3 bits, as a hex string gives * bits can be larger than the number of actual bits needed, but only
and accurate length upto 4 bits */ * if we are reading a hex string and not by more than 3 bits, as a
* hex string gives and accurate length upto 4 bits
*/
if (atttypmod == -1) if (atttypmod == -1)
atttypmod = bitlen; atttypmod = bitlen;
else else if ((bitlen > atttypmod && bit_not_hex) ||
if ((bitlen>atttypmod && bit_not_hex) ||
(bitlen > atttypmod + 3 && !bit_not_hex)) (bitlen > atttypmod + 3 && !bit_not_hex))
elog(ERROR, "zpbitin: bit string of size %d cannot be written into bits(%d)", elog(ERROR, "zpbitin: bit string of size %d cannot be written into bits(%d)",
bitlen, atttypmod); bitlen, atttypmod);
@ -96,9 +98,11 @@ zpbitin(char *s, int dummy, int32 atttypmod)
VARSIZE(result) = len; VARSIZE(result) = len;
VARBITLEN(result) = atttypmod; VARBITLEN(result) = atttypmod;
/* We need to read the bitstring from the end, as we store it least /*
significant byte first. s points to the byte before the beginning * We need to read the bitstring from the end, as we store it least
of the bitstring */ * significant byte first. s points to the byte before the beginning
* of the bitstring
*/
sp = s + 1; sp = s + 1;
r = VARBITS(result); r = VARBITS(result);
if (bit_not_hex) if (bit_not_hex)
@ -110,11 +114,13 @@ zpbitin(char *s, int dummy, int32 atttypmod)
{ {
if (*sp == '1') if (*sp == '1')
*r |= x; *r |= x;
if (bc==7) { if (bc == 7)
{
bc = 0; bc = 0;
x = BITHIGH; x = BITHIGH;
r++; r++;
} else }
else
x >>= 1; x >>= 1;
} }
} }
@ -131,23 +137,33 @@ zpbitin(char *s, int dummy, int32 atttypmod)
x = (bits8) (*sp - 'a') + 10; x = (bits8) (*sp - 'a') + 10;
else else
elog(ERROR, "Cannot parse %c as a hex digit", *sp); elog(ERROR, "Cannot parse %c as a hex digit", *sp);
if (bc) { if (bc)
{
bc = 0; bc = 0;
*r++ |= x; *r++ |= x;
} else { }
else
{
bc++; bc++;
*r = x << 4; *r = x << 4;
} }
} }
} }
if (bitlen > atttypmod) { if (bitlen > atttypmod)
{
/* Check that this fitted */ /* Check that this fitted */
r = (bits8 *) (result + len - 1); r = (bits8 *) (result + len - 1);
ipad = VARBITPAD(result); ipad = VARBITPAD(result);
/* The bottom ipad bits of the byte pointed to by r need to be zero */
/* printf("Byte %X shift %X %d\n",*r,(*r << (8-ipad)) & BITMASK, /*
(*r << (8-ipad)) & BITMASK > 0); * The bottom ipad bits of the byte pointed to by r need to be
* zero
*/
/*
* printf("Byte %X shift %X %d\n",*r,(*r << (8-ipad)) & BITMASK,
* (*r << (8-ipad)) & BITMASK > 0);
*/ */
if (((*r << (BITSPERBYTE - ipad)) & BITMASK) > 0) if (((*r << (BITSPERBYTE - ipad)) & BITMASK) > 0)
elog(ERROR, "zpbitin: bit string too large for bit(%d) data type", elog(ERROR, "zpbitin: bit string too large for bit(%d) data type",
@ -165,9 +181,12 @@ zpbitin(char *s, int dummy, int32 atttypmod)
char * char *
zpbitout(bits8 *s) zpbitout(bits8 *s)
{ {
char *result, *r; char *result,
*r;
bits8 *sp; bits8 *sp;
int i, len, bitlen; int i,
len,
bitlen;
if (s == NULL) if (s == NULL)
{ {
@ -185,12 +204,16 @@ zpbitout(bits8 *s)
*r++ = 'X'; *r++ = 'X';
*r++ = '\''; *r++ = '\'';
/* we cheat by knowing that we store full bytes zero padded */ /* we cheat by knowing that we store full bytes zero padded */
for (i=0; i<len; i+=2, sp++) { for (i = 0; i < len; i += 2, sp++)
{
*r++ = HEXDIG((*sp) >> 4); *r++ = HEXDIG((*sp) >> 4);
*r++ = HEXDIG((*sp) & 0xF); *r++ = HEXDIG((*sp) & 0xF);
} }
/* Go back one step if we printed a hex number that was not part
of the bitstring anymore */ /*
* Go back one step if we printed a hex number that was not part
* of the bitstring anymore
*/
if (i == len + 1) if (i == len + 1)
r--; r--;
*r++ = '\''; *r++ = '\'';
@ -205,10 +228,13 @@ zpbitout(bits8 *s)
char * char *
zpbitsout(bits8 *s) zpbitsout(bits8 *s)
{ {
char *result, *r; char *result,
*r;
bits8 *sp; bits8 *sp;
bits8 x; bits8 x;
int i, k, len; int i,
k,
len;
if (s == NULL) if (s == NULL)
{ {
@ -224,7 +250,8 @@ zpbitsout(bits8 *s)
r = result; r = result;
*r++ = 'B'; *r++ = 'B';
*r++ = '\''; *r++ = '\'';
for (i=0; i<len-BITSPERBYTE; i+=BITSPERBYTE, sp++) { for (i = 0; i < len - BITSPERBYTE; i += BITSPERBYTE, sp++)
{
x = *sp; x = *sp;
for (k = 0; k < BITSPERBYTE; k++) for (k = 0; k < BITSPERBYTE; k++)
{ {
@ -259,7 +286,8 @@ varbitin(char *s, int dummy, int32 atttypmod)
bitlen, /* Number of bits in the bit string */ bitlen, /* Number of bits in the bit string */
slen; /* Length of the input string */ slen; /* Length of the input string */
int bit_not_hex = 0; int bit_not_hex = 0;
int bc, ipad; int bc,
ipad;
bits8 x = 0; bits8 x = 0;
@ -280,11 +308,13 @@ varbitin(char *s, int dummy, int32 atttypmod)
if (!bit_not_hex) if (!bit_not_hex)
bitlen *= 4; bitlen *= 4;
/* Sometimes atttypmod is not supplied. If it is supplied we need to make /*
sure that the bitstring fits. Note that the number of infered bits can * Sometimes atttypmod is not supplied. If it is supplied we need to
be larger than the number of actual bits needed, but only if we are * make sure that the bitstring fits. Note that the number of infered
reading a hex string and not by more than 3 bits, as a hex string gives * bits can be larger than the number of actual bits needed, but only
and accurate length upto 4 bits */ * if we are reading a hex string and not by more than 3 bits, as a
* hex string gives and accurate length upto 4 bits
*/
if (atttypmod > -1) if (atttypmod > -1)
if ((bitlen > atttypmod && bit_not_hex) || if ((bitlen > atttypmod && bit_not_hex) ||
(bitlen > atttypmod + 3 && !bit_not_hex)) (bitlen > atttypmod + 3 && !bit_not_hex))
@ -304,9 +334,11 @@ varbitin(char *s, int dummy, int32 atttypmod)
VARSIZE(result) = len; VARSIZE(result) = len;
VARBITLEN(result) = bitlen; VARBITLEN(result) = bitlen;
/* We need to read the bitstring from the end, as we store it least /*
significant byte first. s points to the byte before the beginning * We need to read the bitstring from the end, as we store it least
of the bitstring */ * significant byte first. s points to the byte before the beginning
* of the bitstring
*/
sp = s + 1; sp = s + 1;
r = VARBITS(result); r = VARBITS(result);
if (bit_not_hex) if (bit_not_hex)
@ -317,11 +349,13 @@ varbitin(char *s, int dummy, int32 atttypmod)
{ {
if (*sp == '1') if (*sp == '1')
*r |= x; *r |= x;
if (bc==7) { if (bc == 7)
{
bc = 0; bc = 0;
x = BITHIGH; x = BITHIGH;
r++; r++;
} else }
else
x >>= 1; x >>= 1;
} }
} }
@ -337,21 +371,29 @@ varbitin(char *s, int dummy, int32 atttypmod)
x = (bits8) (*sp - 'a') + 10; x = (bits8) (*sp - 'a') + 10;
else else
elog(ERROR, "Cannot parse %c as a hex digit", *sp); elog(ERROR, "Cannot parse %c as a hex digit", *sp);
if (bc) { if (bc)
{
bc = 0; bc = 0;
*r++ |= x; *r++ |= x;
} else { }
else
{
bc++; bc++;
*r = x << 4; *r = x << 4;
} }
} }
} }
if (bitlen > atttypmod) { if (bitlen > atttypmod)
{
/* Check that this fitted */ /* Check that this fitted */
r = (bits8 *) (result + len - 1); r = (bits8 *) (result + len - 1);
ipad = VARBITPAD(result); ipad = VARBITPAD(result);
/* The bottom ipad bits of the byte pointed to by r need to be zero */
/*
* The bottom ipad bits of the byte pointed to by r need to be
* zero
*/
if (((*r << (BITSPERBYTE - ipad)) & BITMASK) > 0) if (((*r << (BITSPERBYTE - ipad)) & BITMASK) > 0)
elog(ERROR, "varbitin: bit string too large for varying bit(%d) data type", elog(ERROR, "varbitin: bit string too large for varying bit(%d) data type",
atttypmod); atttypmod);
@ -427,8 +469,10 @@ bitne (bits8 *arg1, bits8 *arg2)
int int
bitcmp(bits8 *arg1, bits8 *arg2) bitcmp(bits8 *arg1, bits8 *arg2)
{ {
int bitlen1, bytelen1, int bitlen1,
bitlen2, bytelen2; bytelen1,
bitlen2,
bytelen2;
int cmp; int cmp;
if (!PointerIsValid(arg1) || !PointerIsValid(arg2)) if (!PointerIsValid(arg1) || !PointerIsValid(arg2))
@ -437,7 +481,8 @@ bitcmp (bits8 *arg1, bits8 *arg2)
bytelen2 = VARBITBYTES(arg2); bytelen2 = VARBITBYTES(arg2);
cmp = memcmp(VARBITS(arg1), VARBITS(arg2), Min(bytelen1, bytelen2)); cmp = memcmp(VARBITS(arg1), VARBITS(arg2), Min(bytelen1, bytelen2));
if (cmp==0) { if (cmp == 0)
{
bitlen1 = VARBITLEN(arg1); bitlen1 = VARBITLEN(arg1);
bitlen2 = VARBITLEN(arg2); bitlen2 = VARBITLEN(arg2);
if (bitlen1 != bitlen2) if (bitlen1 != bitlen2)
@ -476,9 +521,14 @@ bitgt (bits8 *arg1, bits8 *arg2)
bits8 * bits8 *
bitcat(bits8 *arg1, bits8 *arg2) bitcat(bits8 *arg1, bits8 *arg2)
{ {
int bitlen1, bitlen2, bytelen, bit1pad, bit2shift; int bitlen1,
bitlen2,
bytelen,
bit1pad,
bit2shift;
bits8 *result; bits8 *result;
bits8 *pr, *pa; bits8 *pr,
*pa;
if (!PointerIsValid(arg1) || !PointerIsValid(arg2)) if (!PointerIsValid(arg1) || !PointerIsValid(arg2))
return NULL; return NULL;
@ -507,7 +557,8 @@ bitcat (bits8 *arg1, bits8 *arg2)
bit2shift = BITSPERBYTE - bit1pad; bit2shift = BITSPERBYTE - bit1pad;
pa = VARBITS(arg2); pa = VARBITS(arg2);
pr = VARBITS(result) + VARBITBYTES(arg1) - 1; pr = VARBITS(result) + VARBITBYTES(arg1) - 1;
for ( ; pa < VARBITEND(arg2); pa++) { for (; pa < VARBITEND(arg2); pa++)
{
*pr |= ((*pa >> bit2shift) & BITMASK); *pr |= ((*pa >> bit2shift) & BITMASK);
pr++; pr++;
if (pr < VARBITEND(result)) if (pr < VARBITEND(result))
@ -532,9 +583,13 @@ bitsubstr (bits8 *arg, int32 s, int32 l)
ipad = 0, ipad = 0,
ishift, ishift,
i; i;
int e, s1, e1; int e,
s1,
e1;
bits8 *result; bits8 *result;
bits8 mask, *r, *ps; bits8 mask,
*r,
*ps;
if (!PointerIsValid(arg)) if (!PointerIsValid(arg))
return NULL; return NULL;
@ -553,8 +608,11 @@ bitsubstr (bits8 *arg, int32 s, int32 l)
} }
else else
{ {
/* OK, we've got a true substring starting at position s1-1 and
ending at position e1-1 */ /*
* OK, we've got a true substring starting at position s1-1 and
* ending at position e1-1
*/
rbitlen = e1 - s1; rbitlen = e1 - s1;
len = VARBITDATALEN(rbitlen); len = VARBITDATALEN(rbitlen);
result = (bits8 *) palloc(len); result = (bits8 *) palloc(len);
@ -689,9 +747,7 @@ bitxor (bits8 * arg1, bits8 * arg2)
p2 = (bits8 *) VARBITS(arg2); p2 = (bits8 *) VARBITS(arg2);
r = (bits8 *) VARBITS(result); r = (bits8 *) VARBITS(result);
for (i = 0; i < Min(VARBITBYTES(arg1), VARBITBYTES(arg2)); i++) for (i = 0; i < Min(VARBITBYTES(arg1), VARBITBYTES(arg2)); i++)
{
*r++ = *p1++ ^ *p2++; *r++ = *p1++ ^ *p2++;
}
/* Pad the result */ /* Pad the result */
mask = BITMASK << VARBITPAD(result); mask = BITMASK << VARBITPAD(result);
@ -736,7 +792,9 @@ bitnot (bits8 * arg)
bits8 * bits8 *
bitshiftleft(bits8 *arg, int shft) bitshiftleft(bits8 *arg, int shft)
{ {
int byte_shift, ishift, len; int byte_shift,
ishift,
len;
bits8 *result; bits8 *result;
bits8 *p, bits8 *p,
*r; *r;
@ -757,13 +815,17 @@ bitshiftleft (bits8 * arg, int shft)
ishift = shft % BITSPERBYTE; ishift = shft % BITSPERBYTE;
p = ((bits8 *) VARBITS(arg)) + byte_shift; p = ((bits8 *) VARBITS(arg)) + byte_shift;
if (ishift == 0) { if (ishift == 0)
{
/* Special case: we can do a memcpy */ /* Special case: we can do a memcpy */
len = VARBITBYTES(arg) - byte_shift; len = VARBITBYTES(arg) - byte_shift;
memcpy(r, p, len); memcpy(r, p, len);
memset(r + len, 0, byte_shift); memset(r + len, 0, byte_shift);
} else { }
for ( ; p < VARBITEND(arg); r++) { else
{
for (; p < VARBITEND(arg); r++)
{
*r = *p << ishift; *r = *p << ishift;
if ((++p) < VARBITEND(arg)) if ((++p) < VARBITEND(arg))
*r |= *p >> (BITSPERBYTE - ishift); *r |= *p >> (BITSPERBYTE - ishift);
@ -781,7 +843,9 @@ bitshiftleft (bits8 * arg, int shft)
bits8 * bits8 *
bitshiftright(bits8 *arg, int shft) bitshiftright(bits8 *arg, int shft)
{ {
int byte_shift, ishift, len; int byte_shift,
ishift,
len;
bits8 *result; bits8 *result;
bits8 *p, bits8 *p,
*r; *r;
@ -815,7 +879,8 @@ bitshiftright (bits8 * arg, int shft)
{ {
r += byte_shift; r += byte_shift;
*r = 0; /* Initialise first byte */ *r = 0; /* Initialise first byte */
for ( ; r < VARBITEND(result); p++) { for (; r < VARBITEND(result); p++)
{
*r |= *p >> ishift; *r |= *p >> ishift;
if ((++r) < VARBITEND(result)) if ((++r) < VARBITEND(result))
*r = (*p << (BITSPERBYTE - ishift)) & BITMASK; *r = (*p << (BITSPERBYTE - ishift)) & BITMASK;

View File

@ -6,7 +6,8 @@ bits8 * varbit_in (char * s);
char *varbit_out(bits8 *s); char *varbit_out(bits8 *s);
bits8 * bits8 *
varbit_in (char * s) { varbit_in(char *s)
{
return varbitin(s, 0, -1); return varbitin(s, 0, -1);
} }
@ -17,6 +18,7 @@ varbit_out (bits8 *s) {
*/ */
char * char *
varbit_out (bits8 *s) { varbit_out(bits8 *s)
{
return zpbitsout(s); return zpbitsout(s);
} }

View File

@ -5,6 +5,7 @@
void print_details(unsigned char *s); void print_details(unsigned char *s);
const int numb = 8; const int numb = 8;
/* /*
const char *b[] = { "B0010", "B11011011", "B0001", "X3F12", "X27", "B", const char *b[] = { "B0010", "B11011011", "B0001", "X3F12", "X27", "B",
"X11", "B100111"}; "X11", "B100111"};
@ -15,9 +16,11 @@ const char *b[] = { "B0010", "B11011011", "B10001", "X3D12", "X27", "B",
int atttypmod[] = {7, 9, 6, 18, 11, 6, -1, -1}; int atttypmod[] = {7, 9, 6, 18, 11, 6, -1, -1};
void print_details (unsigned char *s) void
print_details(unsigned char *s)
{ {
int i; int i;
printf("Length in bytes : %d\n", VARSIZE(s)); printf("Length in bytes : %d\n", VARSIZE(s));
printf("Length of bitstring: %d\n", VARBITLEN(s)); printf("Length of bitstring: %d\n", VARBITLEN(s));
for (i = 8; i < VARSIZE(s); i++) for (i = 8; i < VARSIZE(s); i++)
@ -28,10 +31,12 @@ void print_details (unsigned char *s)
int int
main() main()
{ {
int i, j; int i,
j;
char *s[numb]; char *s[numb];
for (i=0; i<numb; i++) { for (i = 0; i < numb; i++)
{
printf("Input: %s\n", b[i]); printf("Input: %s\n", b[i]);
s[i] = zpbitin(b[i], 0, atttypmod[i]); s[i] = zpbitin(b[i], 0, atttypmod[i]);
//print_details(s[i]); //print_details(s[i]);
@ -87,21 +92,24 @@ main ()
printf("\nSHIFT LEFT:\n"); printf("\nSHIFT LEFT:\n");
for (i=0; i<numb; i++) { for (i = 0; i < numb; i++)
{
printf("%s\n", zpbitsout(s[i])); printf("%s\n", zpbitsout(s[i]));
for (j = 0; j <= VARBITLEN(s[i]); j++) for (j = 0; j <= VARBITLEN(s[i]); j++)
printf("\t%3d\t%s\n", j, zpbitsout(bitshiftleft(s[i], j))); printf("\t%3d\t%s\n", j, zpbitsout(bitshiftleft(s[i], j)));
} }
printf("\nSHIFT RIGHT:\n"); printf("\nSHIFT RIGHT:\n");
for (i=0; i<numb; i++) { for (i = 0; i < numb; i++)
{
printf("%s\n", zpbitsout(s[i])); printf("%s\n", zpbitsout(s[i]));
for (j = 0; j <= VARBITLEN(s[i]); j++) for (j = 0; j <= VARBITLEN(s[i]); j++)
printf("\t%3d\t%s\n", j, zpbitsout(bitshiftright(s[i], j))); printf("\t%3d\t%s\n", j, zpbitsout(bitshiftright(s[i], j)));
} }
printf("\n\n ********** VARYING **********\n"); printf("\n\n ********** VARYING **********\n");
for (i=0; i<numb; i++) { for (i = 0; i < numb; i++)
{
printf("Input: %s\n", b[i]); printf("Input: %s\n", b[i]);
s[i] = varbitin(b[i], 0, atttypmod[i]); s[i] = varbitin(b[i], 0, atttypmod[i]);
/* print_details(s); */ /* print_details(s); */
@ -158,14 +166,16 @@ main ()
printf("\nSHIFT LEFT:\n"); printf("\nSHIFT LEFT:\n");
for (i=0; i<numb; i++) { for (i = 0; i < numb; i++)
{
printf("%s\n", zpbitsout(s[i])); printf("%s\n", zpbitsout(s[i]));
for (j = 0; j <= VARBITLEN(s[i]); j++) for (j = 0; j <= VARBITLEN(s[i]); j++)
printf("\t%3d\t%s\n", j, zpbitsout(bitshiftleft(s[i], j))); printf("\t%3d\t%s\n", j, zpbitsout(bitshiftleft(s[i], j)));
} }
printf("\nSHIFT RIGHT:\n"); printf("\nSHIFT RIGHT:\n");
for (i=0; i<numb; i++) { for (i = 0; i < numb; i++)
{
printf("%s\n", zpbitsout(s[i])); printf("%s\n", zpbitsout(s[i]));
for (j = 0; j <= VARBITLEN(s[i]); j++) for (j = 0; j <= VARBITLEN(s[i]); j++)
printf("\t%3d\t%s\n", j, zpbitsout(bitshiftright(s[i], j))); printf("\t%3d\t%s\n", j, zpbitsout(bitshiftright(s[i], j)));

View File

@ -51,9 +51,7 @@ decode_24h_time(char *str, struct tm *tm, double *fsec)
*fsec = 0; *fsec = 0;
} }
else if (*cp != ':') else if (*cp != ':')
{
return -1; return -1;
}
else else
{ {
str = cp + 1; str = cp + 1;

View File

@ -38,6 +38,7 @@ extern int assertTest(int val);
#ifdef ASSERT_CHECKING_TEST #ifdef ASSERT_CHECKING_TEST
extern int assertEnable(int val); extern int assertEnable(int val);
#endif #endif
int int
@ -84,7 +85,8 @@ active_listeners(text *relname)
ScanKeyData key; ScanKeyData key;
Datum d; Datum d;
bool isnull; bool isnull;
int len, pid; int len,
pid;
int count = 0; int count = 0;
int ourpid = getpid(); int ourpid = getpid();
char listen_name[NAMEDATALEN]; char listen_name[NAMEDATALEN];
@ -92,7 +94,8 @@ active_listeners(text *relname)
lRel = heap_openr(ListenerRelationName, AccessShareLock); lRel = heap_openr(ListenerRelationName, AccessShareLock);
tdesc = RelationGetDescr(lRel); tdesc = RelationGetDescr(lRel);
if (relname && (VARSIZE(relname) > VARHDRSZ)) { if (relname && (VARSIZE(relname) > VARHDRSZ))
{
len = MIN(VARSIZE(relname) - VARHDRSZ, NAMEDATALEN - 1); len = MIN(VARSIZE(relname) - VARHDRSZ, NAMEDATALEN - 1);
strncpy(listen_name, VARDATA(relname), len); strncpy(listen_name, VARDATA(relname), len);
listen_name[len] = '\0'; listen_name[len] = '\0';
@ -101,15 +104,16 @@ active_listeners(text *relname)
F_NAMEEQ, F_NAMEEQ,
PointerGetDatum(listen_name)); PointerGetDatum(listen_name));
sRel = heap_beginscan(lRel, 0, SnapshotNow, 1, &key); sRel = heap_beginscan(lRel, 0, SnapshotNow, 1, &key);
} else {
sRel = heap_beginscan(lRel, 0, SnapshotNow, 0, (ScanKey)NULL);
} }
else
sRel = heap_beginscan(lRel, 0, SnapshotNow, 0, (ScanKey) NULL);
while (HeapTupleIsValid(lTuple = heap_getnext(sRel, 0))) while (HeapTupleIsValid(lTuple = heap_getnext(sRel, 0)))
{ {
d = heap_getattr(lTuple, Anum_pg_listener_pid, tdesc, &isnull); d = heap_getattr(lTuple, Anum_pg_listener_pid, tdesc, &isnull);
pid = DatumGetInt32(d); pid = DatumGetInt32(d);
if ((pid == ourpid) || (kill(pid, SIGTSTP) == 0)) { if ((pid == ourpid) || (kill(pid, SIGTSTP) == 0))
{
/* elog(NOTICE, "%d ok", pid); */ /* elog(NOTICE, "%d ok", pid); */
count++; count++;
} }
@ -134,6 +138,7 @@ assert_test(int val)
{ {
return assertTest(val); return assertTest(val);
} }
#endif #endif
#endif #endif

View File

@ -10,8 +10,10 @@ int active_listeners(text *relname);
#ifdef USE_ASSERT_CHECKING #ifdef USE_ASSERT_CHECKING
int assert_enable(int val); int assert_enable(int val);
#ifdef ASSERT_CHECKING_TEST #ifdef ASSERT_CHECKING_TEST
int assert_test(int val); int assert_test(int val);
#endif #endif
#endif #endif

View File

@ -1,5 +1,5 @@
/* /*
* $Header: /cvsroot/pgsql/contrib/pgbench/pgbench.c,v 1.2 2000/04/08 18:32:24 tgl Exp $ * $Header: /cvsroot/pgsql/contrib/pgbench/pgbench.c,v 1.3 2000/04/12 17:14:27 momjian Exp $
* *
* pgbench: a simple TPC-B like benchmark program for PostgreSQL * pgbench: a simple TPC-B like benchmark program for PostgreSQL
* written by Tatsuo Ishii * written by Tatsuo Ishii
@ -53,7 +53,8 @@
#define MAXCLIENTS 1024 /* max number of clients allowed */ #define MAXCLIENTS 1024 /* max number of clients allowed */
int nclients = 1; /* default number of simulated clients */ int nclients = 1; /* default number of simulated clients */
int nxacts = 10; /* default number of transactions per clients */ int nxacts = 10; /* default number of transactions per
* clients */
/* /*
* scaling factor. for example, tps = 10 will make 1000000 tuples of * scaling factor. for example, tps = 10 will make 1000000 tuples of
@ -71,12 +72,14 @@ int tps = 1;
int remains; /* number of remained clients */ int remains; /* number of remained clients */
typedef struct { typedef struct
{
PGconn *con; /* connection handle to DB */ PGconn *con; /* connection handle to DB */
int state; /* state No. */ int state; /* state No. */
int cnt; /* xacts count */ int cnt; /* xacts count */
int ecnt; /* error count */ int ecnt; /* error count */
int listen; /* none 0 indicates that an async query has been sent */ int listen; /* none 0 indicates that an async query
* has been sent */
int aid; /* account id for this transaction */ int aid; /* account id for this transaction */
int bid; /* branch id for this transaction */ int bid; /* branch id for this transaction */
int tid; /* teller id for this transaction */ int tid; /* teller id for this transaction */
@ -84,31 +87,41 @@ typedef struct {
int abalance; int abalance;
} CState; } CState;
static void usage() { static void
usage()
{
fprintf(stderr, "usage: pgbench [-h hostname][-p port][-c nclients][-t ntransactions][-s scaling_factor][-n][-v][-S][-d][dbname]\n"); fprintf(stderr, "usage: pgbench [-h hostname][-p port][-c nclients][-t ntransactions][-s scaling_factor][-n][-v][-S][-d][dbname]\n");
fprintf(stderr, "(initialize mode): pgbench -i [-h hostname][-p port][-s scaling_factor][-d][dbname]\n"); fprintf(stderr, "(initialize mode): pgbench -i [-h hostname][-p port][-s scaling_factor][-d][dbname]\n");
} }
/* random number generator */ /* random number generator */
static int getrand(int min, int max) { static int
getrand(int min, int max)
{
return (min + (int) (max * 1.0 * rand() / (RAND_MAX + 1.0))); return (min + (int) (max * 1.0 * rand() / (RAND_MAX + 1.0)));
} }
/* throw away response from backend */ /* throw away response from backend */
static void discard_response(CState *state) { static void
discard_response(CState * state)
{
PGresult *res; PGresult *res;
do {
do
{
res = PQgetResult(state->con); res = PQgetResult(state->con);
if (res) if (res)
PQclear(res); PQclear(res);
} while (res); } while (res);
} }
static int check(CState *state, PGresult *res, int n, int good) static int
check(CState * state, PGresult *res, int n, int good)
{ {
CState *st = &state[n]; CState *st = &state[n];
if (res && PQresultStatus(res) != good) { if (res && PQresultStatus(res) != good)
{
fprintf(stderr, "Client %d aborted in state %d: %s", n, st->state, PQerrorMessage(st->con)); fprintf(stderr, "Client %d aborted in state %d: %s", n, st->state, PQerrorMessage(st->con));
remains--; /* I've aborted */ remains--; /* I've aborted */
PQfinish(st->con); PQfinish(st->con);
@ -119,17 +132,21 @@ static int check(CState *state, PGresult *res, int n, int good)
} }
/* process a transaction */ /* process a transaction */
static void doOne(CState *state, int n, int debug) { static void
doOne(CState * state, int n, int debug)
{
char sql[256]; char sql[256];
PGresult *res; PGresult *res;
CState *st = &state[n]; CState *st = &state[n];
if (st->listen) { /* are we receiver? */ if (st->listen)
if (debug) { { /* are we receiver? */
if (debug)
fprintf(stderr, "client %d receiving\n", n); fprintf(stderr, "client %d receiving\n", n);
} while (PQisBusy(st->con) == TRUE)
while (PQisBusy(st->con) == TRUE) { {
if (!PQconsumeInput(st->con)) { /* there's something wrong */ if (!PQconsumeInput(st->con))
{ /* there's something wrong */
fprintf(stderr, "Client %d aborted in state %d. Probably the backend died while processing.\n", n, st->state); fprintf(stderr, "Client %d aborted in state %d. Probably the backend died while processing.\n", n, st->state);
remains--; /* I've aborted */ remains--; /* I've aborted */
PQfinish(st->con); PQfinish(st->con);
@ -138,64 +155,59 @@ static void doOne(CState *state, int n, int debug) {
} }
} }
switch (st->state) { switch (st->state)
{
case 0: /* response to "begin" */ case 0: /* response to "begin" */
res = PQgetResult(st->con); res = PQgetResult(st->con);
if (check(state, res, n, PGRES_COMMAND_OK)) { if (check(state, res, n, PGRES_COMMAND_OK))
return; return;
}
PQclear(res); PQclear(res);
discard_response(st); discard_response(st);
break; break;
case 1: /* response to "update accounts..." */ case 1: /* response to "update accounts..." */
res = PQgetResult(st->con); res = PQgetResult(st->con);
if (check(state, res, n, PGRES_COMMAND_OK)) { if (check(state, res, n, PGRES_COMMAND_OK))
return; return;
}
PQclear(res); PQclear(res);
discard_response(st); discard_response(st);
break; break;
case 2: /* response to "select abalance ..." */ case 2: /* response to "select abalance ..." */
res = PQgetResult(st->con); res = PQgetResult(st->con);
if (check(state, res, n, PGRES_TUPLES_OK)) { if (check(state, res, n, PGRES_TUPLES_OK))
return; return;
}
PQclear(res); PQclear(res);
discard_response(st); discard_response(st);
break; break;
case 3: /* response to "update tellers ..." */ case 3: /* response to "update tellers ..." */
res = PQgetResult(st->con); res = PQgetResult(st->con);
if (check(state, res, n, PGRES_COMMAND_OK)) { if (check(state, res, n, PGRES_COMMAND_OK))
return; return;
}
PQclear(res); PQclear(res);
discard_response(st); discard_response(st);
break; break;
case 4: /* response to "update branches ..." */ case 4: /* response to "update branches ..." */
res = PQgetResult(st->con); res = PQgetResult(st->con);
if (check(state, res, n, PGRES_COMMAND_OK)) { if (check(state, res, n, PGRES_COMMAND_OK))
return; return;
}
PQclear(res); PQclear(res);
discard_response(st); discard_response(st);
break; break;
case 5: /* response to "insert into history ..." */ case 5: /* response to "insert into history ..." */
res = PQgetResult(st->con); res = PQgetResult(st->con);
if (check(state, res, n, PGRES_COMMAND_OK)) { if (check(state, res, n, PGRES_COMMAND_OK))
return; return;
}
PQclear(res); PQclear(res);
discard_response(st); discard_response(st);
break; break;
case 6: /* response to "end" */ case 6: /* response to "end" */
res = PQgetResult(st->con); res = PQgetResult(st->con);
if (check(state, res, n, PGRES_COMMAND_OK)) { if (check(state, res, n, PGRES_COMMAND_OK))
return; return;
}
PQclear(res); PQclear(res);
discard_response(st); discard_response(st);
if (++st->cnt >= nxacts) { if (++st->cnt >= nxacts)
{
remains--; /* I've done */ remains--; /* I've done */
PQfinish(st->con); PQfinish(st->con);
st->con = NULL; st->con = NULL;
@ -206,12 +218,12 @@ static void doOne(CState *state, int n, int debug) {
/* increment state counter */ /* increment state counter */
st->state++; st->state++;
if (st->state > 6) { if (st->state > 6)
st->state = 0; st->state = 0;
} }
}
switch (st->state) { switch (st->state)
{
case 0: /* about to start */ case 0: /* about to start */
strcpy(sql, "begin"); strcpy(sql, "begin");
st->aid = getrand(1, naccounts * tps); st->aid = getrand(1, naccounts * tps);
@ -241,31 +253,36 @@ static void doOne(CState *state, int n, int debug) {
break; break;
} }
if (debug) { if (debug)
fprintf(stderr, "client %d sending %s\n", n, sql); fprintf(stderr, "client %d sending %s\n", n, sql);
} if (PQsendQuery(st->con, sql) == 0)
if (PQsendQuery(st->con, sql) == 0) { {
if (debug) { if (debug)
fprintf(stderr, "PQsendQuery(%s)failed\n", sql); fprintf(stderr, "PQsendQuery(%s)failed\n", sql);
}
st->ecnt++; st->ecnt++;
} else { }
else
{
st->listen++; /* flags that should be listned */ st->listen++; /* flags that should be listned */
} }
} }
/* process a select only transaction */ /* process a select only transaction */
static void doSelectOnly(CState *state, int n, int debug) { static void
doSelectOnly(CState * state, int n, int debug)
{
char sql[256]; char sql[256];
PGresult *res; PGresult *res;
CState *st = &state[n]; CState *st = &state[n];
if (st->listen) { /* are we receiver? */ if (st->listen)
if (debug) { { /* are we receiver? */
if (debug)
fprintf(stderr, "client %d receiving\n", n); fprintf(stderr, "client %d receiving\n", n);
} while (PQisBusy(st->con) == TRUE)
while (PQisBusy(st->con) == TRUE) { {
if (!PQconsumeInput(st->con)) { /* there's something wrong */ if (!PQconsumeInput(st->con))
{ /* there's something wrong */
fprintf(stderr, "Client %d aborted in state %d. Probably the backend died while processing.\n", n, st->state); fprintf(stderr, "Client %d aborted in state %d. Probably the backend died while processing.\n", n, st->state);
remains--; /* I've aborted */ remains--; /* I've aborted */
PQfinish(st->con); PQfinish(st->con);
@ -274,16 +291,17 @@ static void doSelectOnly(CState *state, int n, int debug) {
} }
} }
switch (st->state) { switch (st->state)
{
case 0: /* response to "select abalance ..." */ case 0: /* response to "select abalance ..." */
res = PQgetResult(st->con); res = PQgetResult(st->con);
if (check(state, res, n, PGRES_TUPLES_OK)) { if (check(state, res, n, PGRES_TUPLES_OK))
return; return;
}
PQclear(res); PQclear(res);
discard_response(st); discard_response(st);
if (++st->cnt >= nxacts) { if (++st->cnt >= nxacts)
{
remains--; /* I've done */ remains--; /* I've done */
PQfinish(st->con); PQfinish(st->con);
st->con = NULL; st->con = NULL;
@ -294,44 +312,50 @@ static void doSelectOnly(CState *state, int n, int debug) {
/* increment state counter */ /* increment state counter */
st->state++; st->state++;
if (st->state > 0) { if (st->state > 0)
st->state = 0; st->state = 0;
} }
}
switch (st->state) { switch (st->state)
{
case 0: case 0:
st->aid = getrand(1, naccounts * tps); st->aid = getrand(1, naccounts * tps);
sprintf(sql, "select abalance from accounts where aid = %d", st->aid); sprintf(sql, "select abalance from accounts where aid = %d", st->aid);
break; break;
} }
if (debug) { if (debug)
fprintf(stderr, "client %d sending %s\n", n, sql); fprintf(stderr, "client %d sending %s\n", n, sql);
}
if (PQsendQuery(st->con, sql) == 0) { if (PQsendQuery(st->con, sql) == 0)
if (debug) { {
if (debug)
fprintf(stderr, "PQsendQuery(%s)failed\n", sql); fprintf(stderr, "PQsendQuery(%s)failed\n", sql);
}
st->ecnt++; st->ecnt++;
} else { }
else
{
st->listen++; /* flags that should be listned */ st->listen++; /* flags that should be listned */
} }
} }
/* discard connections */ /* discard connections */
static void disconnect_all(CState *state) { static void
disconnect_all(CState * state)
{
int i; int i;
for (i=0;i<nclients;i++) {
if (state[i].con) { for (i = 0; i < nclients; i++)
{
if (state[i].con)
PQfinish(state[i].con); PQfinish(state[i].con);
} }
} }
}
/* create tables and setup data */ /* create tables and setup data */
static void init(char *pghost, char *pgport,char *dbName) { static void
init(char *pghost, char *pgport, char *dbName)
{
PGconn *con; PGconn *con;
PGresult *res; PGresult *res;
static char *DDLs[] = { static char *DDLs[] = {
@ -348,15 +372,18 @@ static void init(char *pghost, char *pgport,char *dbName) {
int i; int i;
con = PQsetdb(pghost, pgport, NULL, NULL, dbName); con = PQsetdb(pghost, pgport, NULL, NULL, dbName);
if (PQstatus(con) == CONNECTION_BAD) { if (PQstatus(con) == CONNECTION_BAD)
{
fprintf(stderr, "Connection to database '%s' on %s failed.\n", dbName, pghost); fprintf(stderr, "Connection to database '%s' on %s failed.\n", dbName, pghost);
fprintf(stderr, "%s", PQerrorMessage(con)); fprintf(stderr, "%s", PQerrorMessage(con));
exit(1); exit(1);
} }
for (i=0;i<(sizeof(DDLs)/sizeof(char *));i++) { for (i = 0; i < (sizeof(DDLs) / sizeof(char *)); i++)
{
res = PQexec(con, DDLs[i]); res = PQexec(con, DDLs[i]);
if (strncmp(DDLs[i],"drop",4) && PQresultStatus(res) != PGRES_COMMAND_OK) { if (strncmp(DDLs[i], "drop", 4) && PQresultStatus(res) != PGRES_COMMAND_OK)
{
fprintf(stderr, "%s", PQerrorMessage(con)); fprintf(stderr, "%s", PQerrorMessage(con));
exit(1); exit(1);
} }
@ -364,26 +391,31 @@ static void init(char *pghost, char *pgport,char *dbName) {
} }
res = PQexec(con, "begin"); res = PQexec(con, "begin");
if (PQresultStatus(res) != PGRES_COMMAND_OK) { if (PQresultStatus(res) != PGRES_COMMAND_OK)
{
fprintf(stderr, "%s", PQerrorMessage(con)); fprintf(stderr, "%s", PQerrorMessage(con));
exit(1); exit(1);
} }
for(i = 0; i < nbranches * tps; i++) { for (i = 0; i < nbranches * tps; i++)
{
sprintf(sql, "insert into branches(bid,bbalance) values(%d,0)", i + 1); sprintf(sql, "insert into branches(bid,bbalance) values(%d,0)", i + 1);
res = PQexec(con, sql); res = PQexec(con, sql);
if (PQresultStatus(res) != PGRES_COMMAND_OK) { if (PQresultStatus(res) != PGRES_COMMAND_OK)
{
fprintf(stderr, "%s", PQerrorMessage(con)); fprintf(stderr, "%s", PQerrorMessage(con));
exit(1); exit(1);
} }
PQclear(res); PQclear(res);
} }
for(i = 0; i < ntellers * tps; i++) { for (i = 0; i < ntellers * tps; i++)
{
sprintf(sql, "insert into tellers(tid,bid,tbalance) values (%d,%d,0)" sprintf(sql, "insert into tellers(tid,bid,tbalance) values (%d,%d,0)"
,i + 1, i / ntellers + 1); ,i + 1, i / ntellers + 1);
res = PQexec(con, sql); res = PQexec(con, sql);
if (PQresultStatus(res) != PGRES_COMMAND_OK) { if (PQresultStatus(res) != PGRES_COMMAND_OK)
{
fprintf(stderr, "%s", PQerrorMessage(con)); fprintf(stderr, "%s", PQerrorMessage(con));
exit(1); exit(1);
} }
@ -391,36 +423,42 @@ static void init(char *pghost, char *pgport,char *dbName) {
} }
res = PQexec(con, "copy accounts from stdin"); res = PQexec(con, "copy accounts from stdin");
if (PQresultStatus(res) != PGRES_COPY_IN) { if (PQresultStatus(res) != PGRES_COPY_IN)
{
fprintf(stderr, "%s", PQerrorMessage(con)); fprintf(stderr, "%s", PQerrorMessage(con));
exit(1); exit(1);
} }
PQclear(res); PQclear(res);
fprintf(stderr, "creating tables...\n"); fprintf(stderr, "creating tables...\n");
for(i = 0; i < naccounts*tps; i++) { for (i = 0; i < naccounts * tps; i++)
{
int j = i + 1; int j = i + 1;
sprintf(sql, "%d\t%d\t%d\t\n", i + 1, (i + 1) / naccounts, 0); sprintf(sql, "%d\t%d\t%d\t\n", i + 1, (i + 1) / naccounts, 0);
if (PQputline(con,sql)) { if (PQputline(con, sql))
{
fprintf(stderr, "PQputline failed\n"); fprintf(stderr, "PQputline failed\n");
exit(1); exit(1);
} }
if (j % 10000 == 0) { if (j % 10000 == 0)
fprintf(stderr, "%d tuples done.\n", j); fprintf(stderr, "%d tuples done.\n", j);
} }
} if (PQputline(con, "\\.\n"))
if (PQputline(con,"\\.\n")) { {
fprintf(stderr, "very last PQputline failed\n"); fprintf(stderr, "very last PQputline failed\n");
exit(1); exit(1);
} }
if (PQendcopy(con)) { if (PQendcopy(con))
{
fprintf(stderr, "PQendcopy failed\n"); fprintf(stderr, "PQendcopy failed\n");
exit(1); exit(1);
} }
res = PQexec(con, "end"); res = PQexec(con, "end");
if (PQresultStatus(res) != PGRES_COMMAND_OK) { if (PQresultStatus(res) != PGRES_COMMAND_OK)
{
fprintf(stderr, "%s", PQerrorMessage(con)); fprintf(stderr, "%s", PQerrorMessage(con));
exit(1); exit(1);
} }
@ -428,7 +466,8 @@ static void init(char *pghost, char *pgport,char *dbName) {
/* vacuum */ /* vacuum */
fprintf(stderr, "vacuum..."); fprintf(stderr, "vacuum...");
res = PQexec(con, "vacuum analyze"); res = PQexec(con, "vacuum analyze");
if (PQresultStatus(res) != PGRES_COMMAND_OK) { if (PQresultStatus(res) != PGRES_COMMAND_OK)
{
fprintf(stderr, "%s", PQerrorMessage(con)); fprintf(stderr, "%s", PQerrorMessage(con));
exit(1); exit(1);
} }
@ -438,17 +477,19 @@ static void init(char *pghost, char *pgport,char *dbName) {
} }
/* print out results */ /* print out results */
static void printResults( static void
printResults(
int ttype, CState * state, int ttype, CState * state,
struct timeval * tv1, struct timeval * tv2, struct timeval * tv1, struct timeval * tv2,
struct timeval *tv3) { struct timeval * tv3)
double t1,t2; {
double t1,
t2;
int i; int i;
int normal_xacts = 0; int normal_xacts = 0;
for (i=0;i<nclients;i++) { for (i = 0; i < nclients; i++)
normal_xacts += state[i].cnt; normal_xacts += state[i].cnt;
}
t1 = (tv3->tv_sec - tv1->tv_sec) * 1000000.0 + (tv3->tv_usec - tv1->tv_usec); t1 = (tv3->tv_sec - tv1->tv_sec) * 1000000.0 + (tv3->tv_usec - tv1->tv_usec);
t1 = normal_xacts * 1000000.0 / t1; t1 = normal_xacts * 1000000.0 / t1;
@ -465,23 +506,30 @@ static void printResults(
printf("tps = %f(excluding connections establishing)\n", t2); printf("tps = %f(excluding connections establishing)\n", t2);
} }
int main(int argc, char **argv) { int
main(int argc, char **argv)
{
extern char *optarg; extern char *optarg;
extern int optind, opterr, optopt; extern int optind,
opterr,
optopt;
int c; int c;
char *pghost = ""; char *pghost = "";
char *pgport = ""; char *pgport = "";
char *dbName; char *dbName;
int is_init_mode = 0; /* initialize mode? */ int is_init_mode = 0; /* initialize mode? */
int is_no_vacuum = 0; /* no vacuum at all before testing? */ int is_no_vacuum = 0; /* no vacuum at all before
* testing? */
int is_full_vacuum = 0; /* do full vacuum before testing? */ int is_full_vacuum = 0; /* do full vacuum before testing? */
int debug = 0; /* debug flag */ int debug = 0; /* debug flag */
int ttype = 0; /* transaction type. 0: TPC-B, 1: SELECT only */ int ttype = 0; /* transaction type. 0: TPC-B, 1: SELECT
* only */
static CState state[MAXCLIENTS]; /* clients status */ static CState state[MAXCLIENTS]; /* clients status */
struct timeval tv1; /* start up time */ struct timeval tv1; /* start up time */
struct timeval tv2; /* after establishing all connections to the backend */ struct timeval tv2; /* after establishing all connections to
* the backend */
struct timeval tv3; /* end time */ struct timeval tv3; /* end time */
int i; int i;
@ -492,13 +540,16 @@ int main(int argc, char **argv) {
#ifndef __CYGWIN32__ #ifndef __CYGWIN32__
struct rlimit rlim; struct rlimit rlim;
#endif #endif
PGconn *con; PGconn *con;
PGresult *res; PGresult *res;
while ((c = getopt(argc, argv, "ih:nvp:dc:t:s:S")) != EOF) { while ((c = getopt(argc, argv, "ih:nvp:dc:t:s:S")) != EOF)
switch (c) { {
switch (c)
{
case 'i': case 'i':
is_init_mode++; is_init_mode++;
break; break;
@ -522,20 +573,24 @@ int main(int argc, char **argv) {
break; break;
case 'c': case 'c':
nclients = atoi(optarg); nclients = atoi(optarg);
if (nclients <= 0 || nclients > MAXCLIENTS) { if (nclients <= 0 || nclients > MAXCLIENTS)
{
fprintf(stderr, "wrong number of clients: %d\n", nclients); fprintf(stderr, "wrong number of clients: %d\n", nclients);
exit(1); exit(1);
} }
#ifndef __CYGWIN32__ #ifndef __CYGWIN32__
#ifdef RLIMIT_NOFILE /* most platform uses RLIMIT_NOFILE */ #ifdef RLIMIT_NOFILE /* most platform uses RLIMIT_NOFILE */
if (getrlimit(RLIMIT_NOFILE,&rlim) == -1) { if (getrlimit(RLIMIT_NOFILE, &rlim) == -1)
{
#else /* but BSD doesn't ... */ #else /* but BSD doesn't ... */
if (getrlimit(RLIMIT_OFILE,&rlim) == -1) { if (getrlimit(RLIMIT_OFILE, &rlim) == -1)
{
#endif /* HAVE_RLIMIT_NOFILE */ #endif /* HAVE_RLIMIT_NOFILE */
fprintf(stderr, "getrlimit failed. reason: %s\n", strerror(errno)); fprintf(stderr, "getrlimit failed. reason: %s\n", strerror(errno));
exit(1); exit(1);
} }
if (rlim.rlim_cur <= (nclients+2)) { if (rlim.rlim_cur <= (nclients + 2))
{
fprintf(stderr, "You need at least %d open files resource but you are only allowed to use %ld.\n", nclients + 2, rlim.rlim_cur); fprintf(stderr, "You need at least %d open files resource but you are only allowed to use %ld.\n", nclients + 2, rlim.rlim_cur);
fprintf(stderr, "Use limit/ulimt to increase the limit before using pgbench.\n"); fprintf(stderr, "Use limit/ulimt to increase the limit before using pgbench.\n");
exit(1); exit(1);
@ -544,14 +599,16 @@ int main(int argc, char **argv) {
break; break;
case 's': case 's':
tps = atoi(optarg); tps = atoi(optarg);
if (tps <= 0) { if (tps <= 0)
{
fprintf(stderr, "wrong scaling factor: %d\n", tps); fprintf(stderr, "wrong scaling factor: %d\n", tps);
exit(1); exit(1);
} }
break; break;
case 't': case 't':
nxacts = atoi(optarg); nxacts = atoi(optarg);
if (nxacts <= 0) { if (nxacts <= 0)
{
fprintf(stderr, "wrong number of transactions: %d\n", nxacts); fprintf(stderr, "wrong number of transactions: %d\n", nxacts);
exit(1); exit(1);
} }
@ -563,72 +620,85 @@ int main(int argc, char **argv) {
} }
} }
if (argc > optind) { if (argc > optind)
dbName = argv[optind]; dbName = argv[optind];
} else { else
{
dbName = getenv("USER"); dbName = getenv("USER");
if (dbName == NULL) { if (dbName == NULL)
dbName = ""; dbName = "";
} }
}
if (is_init_mode) { if (is_init_mode)
{
init(pghost, pgport, dbName); init(pghost, pgport, dbName);
exit(0); exit(0);
} }
remains = nclients; remains = nclients;
if (debug) { if (debug)
{
printf("pghost: %s pgport: %s nclients: %d nxacts: %d dbName: %s\n", printf("pghost: %s pgport: %s nclients: %d nxacts: %d dbName: %s\n",
pghost, pgport, nclients, nxacts, dbName); pghost, pgport, nclients, nxacts, dbName);
} }
/* opening connection... */ /* opening connection... */
con = PQsetdb(pghost, pgport, NULL, NULL, dbName); con = PQsetdb(pghost, pgport, NULL, NULL, dbName);
if (PQstatus(con) == CONNECTION_BAD) { if (PQstatus(con) == CONNECTION_BAD)
{
fprintf(stderr, "Connection to database '%s' failed.\n", dbName); fprintf(stderr, "Connection to database '%s' failed.\n", dbName);
fprintf(stderr, "%s", PQerrorMessage(con)); fprintf(stderr, "%s", PQerrorMessage(con));
exit(1); exit(1);
} }
/* get the scaling factor that should be same as count(*) from branches... */ /*
* get the scaling factor that should be same as count(*) from
* branches...
*/
res = PQexec(con, "select count(*) from branches"); res = PQexec(con, "select count(*) from branches");
if (PQresultStatus(res) != PGRES_TUPLES_OK) { if (PQresultStatus(res) != PGRES_TUPLES_OK)
{
fprintf(stderr, "%s", PQerrorMessage(con)); fprintf(stderr, "%s", PQerrorMessage(con));
exit(1); exit(1);
} }
tps = atoi(PQgetvalue(res, 0, 0)); tps = atoi(PQgetvalue(res, 0, 0));
if (tps < 0) { if (tps < 0)
{
fprintf(stderr, "count(*) from branches invalid (%d)\n", tps); fprintf(stderr, "count(*) from branches invalid (%d)\n", tps);
exit(1); exit(1);
} }
PQclear(res); PQclear(res);
if (!is_no_vacuum) { if (!is_no_vacuum)
{
fprintf(stderr, "starting vacuum..."); fprintf(stderr, "starting vacuum...");
res = PQexec(con, "vacuum branches"); res = PQexec(con, "vacuum branches");
if (PQresultStatus(res) != PGRES_COMMAND_OK) { if (PQresultStatus(res) != PGRES_COMMAND_OK)
{
fprintf(stderr, "%s", PQerrorMessage(con)); fprintf(stderr, "%s", PQerrorMessage(con));
exit(1); exit(1);
} }
PQclear(res); PQclear(res);
res = PQexec(con, "vacuum tellers"); res = PQexec(con, "vacuum tellers");
if (PQresultStatus(res) != PGRES_COMMAND_OK) { if (PQresultStatus(res) != PGRES_COMMAND_OK)
{
fprintf(stderr, "%s", PQerrorMessage(con)); fprintf(stderr, "%s", PQerrorMessage(con));
exit(1); exit(1);
} }
PQclear(res); PQclear(res);
res = PQexec(con, "delete from history"); res = PQexec(con, "delete from history");
if (PQresultStatus(res) != PGRES_COMMAND_OK) { if (PQresultStatus(res) != PGRES_COMMAND_OK)
{
fprintf(stderr, "%s", PQerrorMessage(con)); fprintf(stderr, "%s", PQerrorMessage(con));
exit(1); exit(1);
} }
PQclear(res); PQclear(res);
res = PQexec(con, "vacuum history"); res = PQexec(con, "vacuum history");
if (PQresultStatus(res) != PGRES_COMMAND_OK) { if (PQresultStatus(res) != PGRES_COMMAND_OK)
{
fprintf(stderr, "%s", PQerrorMessage(con)); fprintf(stderr, "%s", PQerrorMessage(con));
exit(1); exit(1);
} }
@ -636,10 +706,12 @@ int main(int argc, char **argv) {
fprintf(stderr, "end.\n"); fprintf(stderr, "end.\n");
if (is_full_vacuum) { if (is_full_vacuum)
{
fprintf(stderr, "starting full vacuum..."); fprintf(stderr, "starting full vacuum...");
res = PQexec(con, "vacuum analyze accounts"); res = PQexec(con, "vacuum analyze accounts");
if (PQresultStatus(res) != PGRES_COMMAND_OK) { if (PQresultStatus(res) != PGRES_COMMAND_OK)
{
fprintf(stderr, "%s", PQerrorMessage(con)); fprintf(stderr, "%s", PQerrorMessage(con));
exit(1); exit(1);
} }
@ -657,9 +729,11 @@ int main(int argc, char **argv) {
gettimeofday(&tv1, 0); gettimeofday(&tv1, 0);
/* make connections to the database */ /* make connections to the database */
for (i=0;i<nclients;i++) { for (i = 0; i < nclients; i++)
{
state[i].con = PQsetdb(pghost, pgport, NULL, NULL, dbName); state[i].con = PQsetdb(pghost, pgport, NULL, NULL, dbName);
if (PQstatus(state[i].con) == CONNECTION_BAD) { if (PQstatus(state[i].con) == CONNECTION_BAD)
{
fprintf(stderr, "Connection to database '%s' failed.\n", dbName); fprintf(stderr, "Connection to database '%s' failed.\n", dbName);
fprintf(stderr, "%s", PQerrorMessage(state[i].con)); fprintf(stderr, "%s", PQerrorMessage(state[i].con));
exit(1); exit(1);
@ -670,16 +744,18 @@ int main(int argc, char **argv) {
gettimeofday(&tv2, 0); gettimeofday(&tv2, 0);
/* send start up quries in async manner */ /* send start up quries in async manner */
for (i=0;i<nclients;i++) { for (i = 0; i < nclients; i++)
if (ttype == 0) { {
if (ttype == 0)
doOne(state, i, debug); doOne(state, i, debug);
} else if (ttype == 1) { else if (ttype == 1)
doSelectOnly(state, i, debug); doSelectOnly(state, i, debug);
} }
}
for (;;) { for (;;)
if (remains <= 0) { /* all done ? */ {
if (remains <= 0)
{ /* all done ? */
disconnect_all(state); disconnect_all(state);
/* get end time */ /* get end time */
gettimeofday(&tv3, 0); gettimeofday(&tv3, 0);
@ -690,33 +766,39 @@ int main(int argc, char **argv) {
FD_ZERO(&input_mask); FD_ZERO(&input_mask);
maxsock = 0; maxsock = 0;
for (i=0;i<nclients;i++) { for (i = 0; i < nclients; i++)
if (state[i].con) { {
if (state[i].con)
{
int sock = PQsocket(state[i].con); int sock = PQsocket(state[i].con);
if (sock < 0) {
if (sock < 0)
{
fprintf(stderr, "Client %d: PQsock failed\n", i); fprintf(stderr, "Client %d: PQsock failed\n", i);
disconnect_all(state); disconnect_all(state);
exit(1); exit(1);
} }
FD_SET(sock, &input_mask); FD_SET(sock, &input_mask);
if (maxsock < sock) { if (maxsock < sock)
maxsock = sock; maxsock = sock;
} }
} }
}
if ((nsocks = select(maxsock + 1, &input_mask, (fd_set *) NULL, if ((nsocks = select(maxsock + 1, &input_mask, (fd_set *) NULL,
(fd_set *)NULL, (struct timeval *)NULL)) < 0) { (fd_set *) NULL, (struct timeval *) NULL)) < 0)
if (errno == EINTR) { {
if (errno == EINTR)
continue; continue;
}
/* must be something wrong */ /* must be something wrong */
disconnect_all(state); disconnect_all(state);
fprintf(stderr, "select failed: %s\n", strerror(errno)); fprintf(stderr, "select failed: %s\n", strerror(errno));
exit(1); exit(1);
} else if (nsocks == 0) { /* timeout */ }
else if (nsocks == 0)
{ /* timeout */
fprintf(stderr, "select timeout\n"); fprintf(stderr, "select timeout\n");
for (i=0;i<nclients;i++) { for (i = 0; i < nclients; i++)
{
fprintf(stderr, "client %d:state %d cnt %d ecnt %d listen %d\n", fprintf(stderr, "client %d:state %d cnt %d ecnt %d listen %d\n",
i, state[i].state, state[i].cnt, state[i].ecnt, state[i].listen); i, state[i].state, state[i].cnt, state[i].ecnt, state[i].listen);
} }
@ -724,14 +806,15 @@ int main(int argc, char **argv) {
} }
/* ok, backend returns reply */ /* ok, backend returns reply */
for (i=0;i<nclients;i++) { for (i = 0; i < nclients; i++)
if (state[i].con && FD_ISSET(PQsocket(state[i].con), &input_mask)) { {
if (ttype == 0) { if (state[i].con && FD_ISSET(PQsocket(state[i].con), &input_mask))
{
if (ttype == 0)
doOne(state, i, debug); doOne(state, i, debug);
} else if (ttype == 1) { else if (ttype == 1)
doSelectOnly(state, i, debug); doSelectOnly(state, i, debug);
} }
} }
} }
} }
}

View File

@ -89,9 +89,8 @@ string_output(unsigned char *data, int size)
break; break;
case '{': case '{':
/* Escape beginning of string, to distinguish from arrays */ /* Escape beginning of string, to distinguish from arrays */
if (p == data) { if (p == data)
len++; len++;
}
break; break;
default: default:
if (NOTPRINTABLE(*p)) if (NOTPRINTABLE(*p))
@ -137,9 +136,8 @@ string_output(unsigned char *data, int size)
break; break;
case '{': case '{':
/* Escape beginning of string, to distinguish from arrays */ /* Escape beginning of string, to distinguish from arrays */
if (p == data) { if (p == data)
*r++ = '\\'; *r++ = '\\';
}
*r++ = c; *r++ = c;
break; break;
default: default:
@ -361,6 +359,7 @@ c_charin(unsigned char *str)
{ {
return (string_input(str, 1, 0, NULL)); return (string_input(str, 1, 0, NULL));
} }
#endif #endif
/* end of file */ /* end of file */

View File

@ -10,7 +10,8 @@ unsigned char* c_varcharout(unsigned char *s);
#if 0 #if 0
struct varlena *c_textin(unsigned char *str); struct varlena *c_textin(unsigned char *str);
int32* c_charin(unsigned char *str) int32 *
c_charin(unsigned char *str)
#endif #endif
#endif #endif

View File

@ -9,7 +9,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/access/common/heaptuple.c,v 1.61 2000/01/26 05:55:53 momjian Exp $ * $Header: /cvsroot/pgsql/src/backend/access/common/heaptuple.c,v 1.62 2000/04/12 17:14:36 momjian Exp $
* *
* NOTES * NOTES
* The old interface functions have been converted to macros * The old interface functions have been converted to macros
@ -808,9 +808,7 @@ heap_freetuple(HeapTuple htup)
if (htup->t_data != NULL) if (htup->t_data != NULL)
if (htup->t_datamcxt != NULL && (char *) (htup->t_data) != if (htup->t_datamcxt != NULL && (char *) (htup->t_data) !=
((char *) htup + HEAPTUPLESIZE)) ((char *) htup + HEAPTUPLESIZE))
{
elog(NOTICE, "TELL Jan Wieck: heap_freetuple() found separate t_data"); elog(NOTICE, "TELL Jan Wieck: heap_freetuple() found separate t_data");
}
pfree(htup); pfree(htup);
} }

View File

@ -9,7 +9,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/access/common/indextuple.c,v 1.42 2000/01/26 05:55:53 momjian Exp $ * $Header: /cvsroot/pgsql/src/backend/access/common/indextuple.c,v 1.43 2000/04/12 17:14:37 momjian Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */

View File

@ -8,7 +8,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/access/common/tupdesc.c,v 1.61 2000/01/31 04:35:48 tgl Exp $ * $Header: /cvsroot/pgsql/src/backend/access/common/tupdesc.c,v 1.62 2000/04/12 17:14:37 momjian Exp $
* *
* NOTES * NOTES
* some of the executor utility code such as "ExecTypeFromTL" should be * some of the executor utility code such as "ExecTypeFromTL" should be
@ -238,8 +238,10 @@ equalTupleDescs(TupleDesc tupdesc1, TupleDesc tupdesc2)
Form_pg_attribute attr1 = tupdesc1->attrs[i]; Form_pg_attribute attr1 = tupdesc1->attrs[i];
Form_pg_attribute attr2 = tupdesc2->attrs[i]; Form_pg_attribute attr2 = tupdesc2->attrs[i];
/* We do not need to check every single field here, and in fact /*
* some fields such as attdisbursion probably shouldn't be compared. * We do not need to check every single field here, and in fact
* some fields such as attdisbursion probably shouldn't be
* compared.
*/ */
if (strcmp(NameStr(attr1->attname), NameStr(attr2->attname)) != 0) if (strcmp(NameStr(attr1->attname), NameStr(attr2->attname)) != 0)
return false; return false;
@ -585,8 +587,9 @@ BuildDescForRelation(List *schema, char *relname)
constr->has_not_null = true; constr->has_not_null = true;
desc->attrs[attnum - 1]->attnotnull = entry->is_not_null; desc->attrs[attnum - 1]->attnotnull = entry->is_not_null;
/* Note we copy only pre-cooked default expressions. /*
* Digestion of raw ones is someone else's problem. * Note we copy only pre-cooked default expressions. Digestion of
* raw ones is someone else's problem.
*/ */
if (entry->cooked_default != NULL) if (entry->cooked_default != NULL)
{ {

View File

@ -6,7 +6,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/access/gist/gist.c,v 1.52 2000/03/17 02:36:00 tgl Exp $ * $Header: /cvsroot/pgsql/src/backend/access/gist/gist.c,v 1.53 2000/04/12 17:14:39 momjian Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
@ -52,8 +52,10 @@ void gistdelete(Relation r, ItemPointer tid);
static IndexTuple gist_tuple_replacekey(Relation r, GISTENTRY entry, IndexTuple t); static IndexTuple gist_tuple_replacekey(Relation r, GISTENTRY entry, IndexTuple t);
static void gistcentryinit(GISTSTATE *giststate, GISTENTRY *e, char *pr, static void gistcentryinit(GISTSTATE *giststate, GISTENTRY *e, char *pr,
Relation r, Page pg, OffsetNumber o, int b, bool l); Relation r, Page pg, OffsetNumber o, int b, bool l);
#ifdef GISTDEBUG #ifdef GISTDEBUG
static char *int_range_out(INTRANGE *r); static char *int_range_out(INTRANGE *r);
#endif #endif
/* /*
@ -272,13 +274,13 @@ gistbuild(Relation heap,
/* /*
* Since we just counted the tuples in the heap, we update its stats * 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 * in pg_class to guarantee that the planner takes advantage of the
* index we just created. But, only update statistics during * index we just created. But, only update statistics during normal
* normal index definitions, not for indices on system catalogs * index definitions, not for indices on system catalogs created
* created during bootstrap processing. We must close the relations * during bootstrap processing. We must close the relations before
* before updating statistics to guarantee that the relcache entries * updating statistics to guarantee that the relcache entries are
* are flushed when we increment the command counter in UpdateStats(). * flushed when we increment the command counter in UpdateStats(). But
* But we do not release any locks on the relations; those will be * we do not release any locks on the relations; those will be held
* held until end of transaction. * until end of transaction.
*/ */
if (IsNormalProcessingMode()) if (IsNormalProcessingMode())
{ {

View File

@ -8,7 +8,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/access/hash/hash.c,v 1.36 2000/03/01 05:39:22 inoue Exp $ * $Header: /cvsroot/pgsql/src/backend/access/hash/hash.c,v 1.37 2000/04/12 17:14:43 momjian Exp $
* *
* NOTES * NOTES
* This file contains only the public interface routines. * This file contains only the public interface routines.
@ -230,13 +230,13 @@ hashbuild(Relation heap,
/* /*
* Since we just counted the tuples in the heap, we update its stats * 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 * in pg_class to guarantee that the planner takes advantage of the
* index we just created. But, only update statistics during * index we just created. But, only update statistics during normal
* normal index definitions, not for indices on system catalogs * index definitions, not for indices on system catalogs created
* created during bootstrap processing. We must close the relations * during bootstrap processing. We must close the relations before
* before updating statistics to guarantee that the relcache entries * updating statistics to guarantee that the relcache entries are
* are flushed when we increment the command counter in UpdateStats(). * flushed when we increment the command counter in UpdateStats(). But
* But we do not release any locks on the relations; those will be * we do not release any locks on the relations; those will be held
* held until end of transaction. * until end of transaction.
*/ */
if (IsNormalProcessingMode()) if (IsNormalProcessingMode())
{ {

View File

@ -8,7 +8,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/access/hash/hashfunc.c,v 1.24 2000/02/21 03:36:46 tgl Exp $ * $Header: /cvsroot/pgsql/src/backend/access/hash/hashfunc.c,v 1.25 2000/04/12 17:14:44 momjian Exp $
* *
* NOTES * NOTES
* These functions are stored in pg_amproc. For each operator class * These functions are stored in pg_amproc. For each operator class

View File

@ -8,7 +8,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/access/hash/hashscan.c,v 1.22 2000/01/26 05:55:55 momjian Exp $ * $Header: /cvsroot/pgsql/src/backend/access/hash/hashscan.c,v 1.23 2000/04/12 17:14:44 momjian Exp $
* *
* NOTES * NOTES
* Because we can be doing an index scan on a relation while we * Because we can be doing an index scan on a relation while we

View File

@ -8,7 +8,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/access/hash/hashsearch.c,v 1.23 2000/03/17 02:36:02 tgl Exp $ * $Header: /cvsroot/pgsql/src/backend/access/hash/hashsearch.c,v 1.24 2000/04/12 17:14:44 momjian Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */

View File

@ -8,7 +8,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/access/heap/heapam.c,v 1.66 2000/02/09 03:49:47 inoue Exp $ * $Header: /cvsroot/pgsql/src/backend/access/heap/heapam.c,v 1.67 2000/04/12 17:14:45 momjian Exp $
* *
* *
* INTERFACE ROUTINES * INTERFACE ROUTINES
@ -188,8 +188,9 @@ unpinscan(HeapScanDesc scan)
if (BufferIsValid(scan->rs_nbuf)) if (BufferIsValid(scan->rs_nbuf))
ReleaseBuffer(scan->rs_nbuf); ReleaseBuffer(scan->rs_nbuf);
/* we don't bother to clear rs_pbuf etc --- caller must /*
* reinitialize them if scan descriptor is not being deleted. * we don't bother to clear rs_pbuf etc --- caller must reinitialize
* them if scan descriptor is not being deleted.
*/ */
} }
@ -681,6 +682,7 @@ heap_beginscan(Relation relation,
scan->rs_nkeys = (short) nkeys; scan->rs_nkeys = (short) nkeys;
if (nkeys) if (nkeys)
/* /*
* we do this here instead of in initscan() because heap_rescan * we do this here instead of in initscan() because heap_rescan
* also calls initscan() and we don't want to allocate memory * also calls initscan() and we don't want to allocate memory
@ -847,9 +849,7 @@ heap_getnext(HeapScanDesc scandesc, int backw)
if (scan->rs_ptup.t_data == scan->rs_ctup.t_data && if (scan->rs_ptup.t_data == scan->rs_ctup.t_data &&
BufferIsInvalid(scan->rs_pbuf)) BufferIsInvalid(scan->rs_pbuf))
{
return NULL; return NULL;
}
/* /*
* Copy the "current" tuple/buffer to "next". Pin/unpin the * Copy the "current" tuple/buffer to "next". Pin/unpin the
@ -1095,8 +1095,10 @@ heap_fetch(Relation relation,
} }
else else
{ {
/* All checks passed, so return the tuple as valid.
* Caller is now responsible for releasing the buffer. /*
* All checks passed, so return the tuple as valid. Caller is now
* responsible for releasing the buffer.
*/ */
*userbuf = buffer; *userbuf = buffer;
} }
@ -1119,7 +1121,8 @@ heap_get_latest_tid(Relation relation,
HeapTupleData tp; HeapTupleData tp;
HeapTupleHeader t_data; HeapTupleHeader t_data;
ItemPointerData ctid; ItemPointerData ctid;
bool invalidBlock,linkend; bool invalidBlock,
linkend;
/* ---------------- /* ----------------
* get the buffer from the relation descriptor * get the buffer from the relation descriptor
@ -1300,10 +1303,11 @@ l1:
LockBuffer(buffer, BUFFER_LOCK_EXCLUSIVE); LockBuffer(buffer, BUFFER_LOCK_EXCLUSIVE);
if (TransactionIdDidAbort(xwait)) if (TransactionIdDidAbort(xwait))
goto l1; goto l1;
/* /*
* xwait is committed but if xwait had just marked * xwait is committed but if xwait had just marked the tuple for
* the tuple for update then some other xaction could * update then some other xaction could update this tuple before
* update this tuple before we got to this point. * we got to this point.
*/ */
if (tp.t_data->t_xmax != xwait) if (tp.t_data->t_xmax != xwait)
goto l1; goto l1;
@ -1396,10 +1400,11 @@ l2:
LockBuffer(buffer, BUFFER_LOCK_EXCLUSIVE); LockBuffer(buffer, BUFFER_LOCK_EXCLUSIVE);
if (TransactionIdDidAbort(xwait)) if (TransactionIdDidAbort(xwait))
goto l2; goto l2;
/* /*
* xwait is committed but if xwait had just marked * xwait is committed but if xwait had just marked the tuple for
* the tuple for update then some other xaction could * update then some other xaction could update this tuple before
* update this tuple before we got to this point. * we got to this point.
*/ */
if (oldtup.t_data->t_xmax != xwait) if (oldtup.t_data->t_xmax != xwait)
goto l2; goto l2;
@ -1521,10 +1526,11 @@ l3:
LockBuffer(*buffer, BUFFER_LOCK_EXCLUSIVE); LockBuffer(*buffer, BUFFER_LOCK_EXCLUSIVE);
if (TransactionIdDidAbort(xwait)) if (TransactionIdDidAbort(xwait))
goto l3; goto l3;
/* /*
* xwait is committed but if xwait had just marked * xwait is committed but if xwait had just marked the tuple for
* the tuple for update then some other xaction could * update then some other xaction could update this tuple before
* update this tuple before we got to this point. * we got to this point.
*/ */
if (tuple->t_data->t_xmax != xwait) if (tuple->t_data->t_xmax != xwait)
goto l3; goto l3;

View File

@ -8,7 +8,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $Id: hio.c,v 1.30 2000/03/17 02:36:02 tgl Exp $ * $Id: hio.c,v 1.31 2000/04/12 17:14:45 momjian Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
@ -111,8 +111,8 @@ RelationPutHeapTupleAtEnd(Relation relation, HeapTuple tuple)
len = MAXALIGN(tuple->t_len); /* be conservative */ len = MAXALIGN(tuple->t_len); /* be conservative */
/* /*
* If we're gonna fail for oversize tuple, do it right away... * If we're gonna fail for oversize tuple, do it right away... this
* this code should go away eventually. * code should go away eventually.
*/ */
if (len > MaxTupleSize) if (len > MaxTupleSize)
elog(ERROR, "Tuple is too big: size %u, max size %ld", elog(ERROR, "Tuple is too big: size %u, max size %ld",
@ -136,8 +136,8 @@ RelationPutHeapTupleAtEnd(Relation relation, HeapTuple tuple)
lastblock = RelationGetNumberOfBlocks(relation); lastblock = RelationGetNumberOfBlocks(relation);
/* /*
* Get the last existing page --- may need to create the first one * Get the last existing page --- may need to create the first one if
* if this is a virgin relation. * this is a virgin relation.
*/ */
if (lastblock == 0) if (lastblock == 0)
{ {
@ -168,12 +168,14 @@ RelationPutHeapTupleAtEnd(Relation relation, HeapTuple tuple)
if (len > PageGetFreeSpace(pageHeader)) if (len > PageGetFreeSpace(pageHeader))
{ {
/* /*
* BUG: by elog'ing here, we leave the new buffer locked and not * BUG: by elog'ing here, we leave the new buffer locked and
* marked dirty, which may result in an invalid page header * not marked dirty, which may result in an invalid page
* being left on disk. But we should not get here given the * header being left on disk. But we should not get here
* test at the top of the routine, and the whole deal should * given the test at the top of the routine, and the whole
* go away when we implement tuple splitting anyway... * deal should go away when we implement tuple splitting
* anyway...
*/ */
elog(ERROR, "Tuple is too big: size %u", len); elog(ERROR, "Tuple is too big: size %u", len);
} }

View File

@ -8,7 +8,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/access/heap/tuptoaster.c,v 1.2 2000/01/20 21:50:59 petere Exp $ * $Header: /cvsroot/pgsql/src/backend/access/heap/tuptoaster.c,v 1.3 2000/04/12 17:14:45 momjian Exp $
* *
* *
* INTERFACE ROUTINES * INTERFACE ROUTINES

View File

@ -8,7 +8,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/access/index/genam.c,v 1.24 2000/03/14 23:52:01 tgl Exp $ * $Header: /cvsroot/pgsql/src/backend/access/index/genam.c,v 1.25 2000/04/12 17:14:47 momjian Exp $
* *
* NOTES * NOTES
* many of the old access method routines have been turned into * many of the old access method routines have been turned into
@ -114,7 +114,10 @@ RelationGetIndexScan(Relation relation,
ItemPointerSetInvalid(&scan->currentMarkData); ItemPointerSetInvalid(&scan->currentMarkData);
ItemPointerSetInvalid(&scan->nextMarkData); ItemPointerSetInvalid(&scan->nextMarkData);
/* mark cached function lookup data invalid; it will be set on first use */ /*
* mark cached function lookup data invalid; it will be set on first
* use
*/
scan->fn_getnext.fn_oid = InvalidOid; scan->fn_getnext.fn_oid = InvalidOid;
if (numberOfKeys > 0) if (numberOfKeys > 0)

View File

@ -8,7 +8,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/access/index/indexam.c,v 1.41 2000/03/14 23:52:01 tgl Exp $ * $Header: /cvsroot/pgsql/src/backend/access/index/indexam.c,v 1.42 2000/04/12 17:14:47 momjian Exp $
* *
* INTERFACE ROUTINES * INTERFACE ROUTINES
* index_open - open an index relation by relationId * index_open - open an index relation by relationId

View File

@ -9,7 +9,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/access/index/Attic/istrat.c,v 1.41 2000/02/18 09:29:16 inoue Exp $ * $Header: /cvsroot/pgsql/src/backend/access/index/Attic/istrat.c,v 1.42 2000/04/12 17:14:47 momjian Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */

View File

@ -8,7 +8,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/access/nbtree/nbtcompare.c,v 1.33 2000/02/10 19:51:38 momjian Exp $ * $Header: /cvsroot/pgsql/src/backend/access/nbtree/nbtcompare.c,v 1.34 2000/04/12 17:14:49 momjian Exp $
* *
* NOTES * NOTES
* These functions are stored in pg_amproc. For each operator class * These functions are stored in pg_amproc. For each operator class

View File

@ -8,7 +8,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/access/nbtree/nbtinsert.c,v 1.56 2000/03/17 02:36:03 tgl Exp $ * $Header: /cvsroot/pgsql/src/backend/access/nbtree/nbtinsert.c,v 1.57 2000/04/12 17:14:49 momjian Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
@ -267,16 +267,15 @@ _bt_insertonpg(Relation rel,
itemsz = IndexTupleDSize(btitem->bti_itup) itemsz = IndexTupleDSize(btitem->bti_itup)
+ (sizeof(BTItemData) - sizeof(IndexTupleData)); + (sizeof(BTItemData) - sizeof(IndexTupleData));
itemsz = MAXALIGN(itemsz); /* be safe, PageAddItem will do itemsz = MAXALIGN(itemsz); /* be safe, PageAddItem will do this but
* this but we need to be * we need to be consistent */
* consistent */
/* /*
* Check whether the item can fit on a btree page at all. * Check whether the item can fit on a btree page at all. (Eventually,
* (Eventually, we ought to try to apply TOAST methods if not.) * we ought to try to apply TOAST methods if not.) We actually need to
* We actually need to be able to fit three items on every page, * be able to fit three items on every page, so restrict any one item
* so restrict any one item to 1/3 the per-page available space. * to 1/3 the per-page available space. Note that at this point,
* Note that at this point, itemsz doesn't include the ItemId. * itemsz doesn't include the ItemId.
*/ */
if (itemsz > (PageGetPageSize(page) - sizeof(PageHeaderData) - MAXALIGN(sizeof(BTPageOpaqueData))) / 3 - sizeof(ItemIdData)) if (itemsz > (PageGetPageSize(page) - sizeof(PageHeaderData) - MAXALIGN(sizeof(BTPageOpaqueData))) / 3 - sizeof(ItemIdData))
elog(ERROR, "btree: index item size %u exceeds maximum %lu", elog(ERROR, "btree: index item size %u exceeds maximum %lu",
@ -415,8 +414,8 @@ _bt_insertonpg(Relation rel,
bool is_root = lpageop->btpo_flags & BTP_ROOT; bool is_root = lpageop->btpo_flags & BTP_ROOT;
/* /*
* Instead of splitting leaf page in the chain of duplicates * Instead of splitting leaf page in the chain of duplicates by
* by new duplicate, insert it into some right page. * new duplicate, insert it into some right page.
*/ */
if ((lpageop->btpo_flags & BTP_CHAIN) && if ((lpageop->btpo_flags & BTP_CHAIN) &&
(lpageop->btpo_flags & BTP_LEAF) && keys_equal) (lpageop->btpo_flags & BTP_LEAF) && keys_equal)
@ -424,6 +423,7 @@ _bt_insertonpg(Relation rel,
rbuf = _bt_getbuf(rel, lpageop->btpo_next, BT_WRITE); rbuf = _bt_getbuf(rel, lpageop->btpo_next, BT_WRITE);
rpage = BufferGetPage(rbuf); rpage = BufferGetPage(rbuf);
rpageop = (BTPageOpaque) PageGetSpecialPointer(rpage); rpageop = (BTPageOpaque) PageGetSpecialPointer(rpage);
/* /*
* some checks * some checks
*/ */
@ -442,6 +442,7 @@ _bt_insertonpg(Relation rel,
BTGreaterStrategyNumber)) BTGreaterStrategyNumber))
elog(FATAL, "btree: hikey is out of order"); elog(FATAL, "btree: hikey is out of order");
else if (rpageop->btpo_flags & BTP_CHAIN) else if (rpageop->btpo_flags & BTP_CHAIN)
/* /*
* If hikey > scankey then it's last page in chain and * If hikey > scankey then it's last page in chain and
* BTP_CHAIN must be OFF * BTP_CHAIN must be OFF
@ -450,9 +451,7 @@ _bt_insertonpg(Relation rel,
} }
else else
/* rightmost page */ /* rightmost page */
{
Assert(!(rpageop->btpo_flags & BTP_CHAIN)); Assert(!(rpageop->btpo_flags & BTP_CHAIN));
}
_bt_relbuf(rel, buf, BT_WRITE); _bt_relbuf(rel, buf, BT_WRITE);
return (_bt_insertonpg(rel, rbuf, stack, keysz, return (_bt_insertonpg(rel, rbuf, stack, keysz,
scankey, btitem, afteritem)); scankey, btitem, afteritem));

View File

@ -9,7 +9,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/access/nbtree/nbtpage.c,v 1.35 2000/01/26 05:55:58 momjian Exp $ * $Header: /cvsroot/pgsql/src/backend/access/nbtree/nbtpage.c,v 1.36 2000/04/12 17:14:49 momjian Exp $
* *
* NOTES * NOTES
* Postgres btree pages look like ordinary relation pages. The opaque * Postgres btree pages look like ordinary relation pages. The opaque

View File

@ -12,7 +12,7 @@
* Portions Copyright (c) 1994, Regents of the University of California * Portions Copyright (c) 1994, Regents of the University of California
* *
* IDENTIFICATION * IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/access/nbtree/nbtree.c,v 1.53 2000/02/18 09:29:54 inoue Exp $ * $Header: /cvsroot/pgsql/src/backend/access/nbtree/nbtree.c,v 1.54 2000/04/12 17:14:49 momjian Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
@ -276,9 +276,9 @@ btbuild(Relation heap,
} }
/* /*
* if we are doing bottom-up btree build, finish the build by * if we are doing bottom-up btree build, finish the build by (1)
* (1) completing the sort of the spool file, (2) inserting the * completing the sort of the spool file, (2) inserting the sorted
* sorted tuples into btree pages and (3) building the upper levels. * tuples into btree pages and (3) building the upper levels.
*/ */
if (usefast) if (usefast)
{ {
@ -298,13 +298,13 @@ btbuild(Relation heap,
/* /*
* Since we just counted the tuples in the heap, we update its stats * 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 * in pg_class to guarantee that the planner takes advantage of the
* index we just created. But, only update statistics during * index we just created. But, only update statistics during normal
* normal index definitions, not for indices on system catalogs * index definitions, not for indices on system catalogs created
* created during bootstrap processing. We must close the relations * during bootstrap processing. We must close the relations before
* before updating statistics to guarantee that the relcache entries * updating statistics to guarantee that the relcache entries are
* are flushed when we increment the command counter in UpdateStats(). * flushed when we increment the command counter in UpdateStats(). But
* But we do not release any locks on the relations; those will be * we do not release any locks on the relations; those will be held
* held until end of transaction. * until end of transaction.
*/ */
if (IsNormalProcessingMode()) if (IsNormalProcessingMode())
{ {
@ -314,9 +314,10 @@ btbuild(Relation heap,
heap_close(heap, NoLock); heap_close(heap, NoLock);
index_close(index); index_close(index);
/* /*
UpdateStats(hrelid, nhtups, true); * UpdateStats(hrelid, nhtups, true); UpdateStats(irelid, nitups,
UpdateStats(irelid, nitups, false); * false);
*/ */
UpdateStats(hrelid, nhtups, inplace); UpdateStats(hrelid, nhtups, inplace);
UpdateStats(irelid, nitups, inplace); UpdateStats(irelid, nitups, inplace);

View File

@ -8,7 +8,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/access/nbtree/Attic/nbtscan.c,v 1.30 2000/01/26 05:55:58 momjian Exp $ * $Header: /cvsroot/pgsql/src/backend/access/nbtree/Attic/nbtscan.c,v 1.31 2000/04/12 17:14:49 momjian Exp $
* *
* *
* NOTES * NOTES
@ -52,13 +52,16 @@ static void _bt_scandel(IndexScanDesc scan, BlockNumber blkno, OffsetNumber offn
void void
AtEOXact_nbtree(void) AtEOXact_nbtree(void)
{ {
/* Note: these actions should only be necessary during xact abort;
* but they can't hurt during a commit. /*
* Note: these actions should only be necessary during xact abort; but
* they can't hurt during a commit.
*/ */
/* Reset the active-scans list to empty. /*
* We do not need to free the list elements, because they're all * Reset the active-scans list to empty. We do not need to free the
* palloc()'d, so they'll go away at end of transaction anyway. * list elements, because they're all palloc()'d, so they'll go away
* at end of transaction anyway.
*/ */
BTScans = NULL; BTScans = NULL;

View File

@ -8,7 +8,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/access/nbtree/nbtsearch.c,v 1.58 2000/03/17 02:36:04 tgl Exp $ * $Header: /cvsroot/pgsql/src/backend/access/nbtree/nbtsearch.c,v 1.59 2000/04/12 17:14:49 momjian Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
@ -299,9 +299,7 @@ _bt_skeycmp(Relation rel,
compare = -1; /* not-NULL key "<" NULL datum */ compare = -1; /* not-NULL key "<" NULL datum */
} }
else else
{
compare = (int32) FMGR_PTR2(&entry->sk_func, keyDatum, attrDatum); compare = (int32) FMGR_PTR2(&entry->sk_func, keyDatum, attrDatum);
}
if (compare != 0) if (compare != 0)
break; /* done when we find unequal attributes */ break; /* done when we find unequal attributes */
@ -368,19 +366,18 @@ _bt_binsrch(Relation rel,
/* /*
* If there are no keys on the page, return the first available slot. * If there are no keys on the page, return the first available slot.
* Note this covers two cases: the page is really empty (no keys), * Note this covers two cases: the page is really empty (no keys), or
* or it contains only a high key. The latter case is possible after * it contains only a high key. The latter case is possible after
* vacuuming. * vacuuming.
*/ */
if (high < low) if (high < low)
return low; return low;
/* /*
* Binary search to find the first key on the page >= scan key. * Binary search to find the first key on the page >= scan key. Loop
* Loop invariant: all slots before 'low' are < scan key, all slots * invariant: all slots before 'low' are < scan key, all slots at or
* at or after 'high' are >= scan key. Also, haveEq is true if the * after 'high' are >= scan key. Also, haveEq is true if the tuple at
* tuple at 'high' is == scan key. * 'high' is == scan key. We can fall out when high == low.
* We can fall out when high == low.
*/ */
high++; /* establish the loop invariant for high */ high++; /* establish the loop invariant for high */
haveEq = false; haveEq = false;
@ -388,6 +385,7 @@ _bt_binsrch(Relation rel,
while (high > low) while (high > low)
{ {
OffsetNumber mid = low + ((high - low) / 2); OffsetNumber mid = low + ((high - low) / 2);
/* We have low <= mid < high, so mid points at a real slot */ /* We have low <= mid < high, so mid points at a real slot */
result = _bt_compare(rel, itupdesc, page, keysz, scankey, mid); result = _bt_compare(rel, itupdesc, page, keysz, scankey, mid);
@ -443,18 +441,20 @@ _bt_binsrch(Relation rel,
if (haveEq) if (haveEq)
{ {
/* /*
* There is an equal key. We return either the first equal key * There is an equal key. We return either the first equal key
* (which we just found), or the last lesser key. * (which we just found), or the last lesser key.
* *
* We need not check srchtype != BT_DESCENT here, since if that * We need not check srchtype != BT_DESCENT here, since if that is
* is true then natts == keysz by assumption. * true then natts == keysz by assumption.
*/ */
if (natts == keysz) if (natts == keysz)
return low; /* return first equal key */ return low; /* return first equal key */
} }
else else
{ {
/* /*
* There is no equal key. We return either the first greater key * There is no equal key. We return either the first greater key
* (which we just found), or the last lesser key. * (which we just found), or the last lesser key.
@ -524,6 +524,7 @@ _bt_compare(Relation rel,
&& P_LEFTMOST(opaque) && P_LEFTMOST(opaque)
&& offnum == P_HIKEY) && offnum == P_HIKEY)
{ {
/* /*
* we just have to believe that this will only be called with * we just have to believe that this will only be called with
* offnum == P_HIKEY when P_HIKEY is the OffsetNumber of the first * offnum == P_HIKEY when P_HIKEY is the OffsetNumber of the first
@ -704,7 +705,8 @@ _bt_first(IndexScanDesc scan, ScanDirection dir)
ScanKey scankeys = 0; ScanKey scankeys = 0;
int keysCount = 0; int keysCount = 0;
int *nKeyIs = 0; int *nKeyIs = 0;
int i, j; int i,
j;
StrategyNumber strat_total; StrategyNumber strat_total;
rel = scan->relation; rel = scan->relation;
@ -809,7 +811,8 @@ _bt_first(IndexScanDesc scan, ScanDirection dir)
ScanKeyEntryInitialize(scankeys + i, so->keyData[j].sk_flags, ScanKeyEntryInitialize(scankeys + i, so->keyData[j].sk_flags,
i + 1, proc, so->keyData[j].sk_argument); i + 1, proc, so->keyData[j].sk_argument);
} }
if (nKeyIs) pfree(nKeyIs); if (nKeyIs)
pfree(nKeyIs);
stack = _bt_search(rel, keysCount, scankeys, &buf); stack = _bt_search(rel, keysCount, scankeys, &buf);
_bt_freestack(stack); _bt_freestack(stack);

View File

@ -28,7 +28,7 @@
* Portions Copyright (c) 1994, Regents of the University of California * Portions Copyright (c) 1994, Regents of the University of California
* *
* IDENTIFICATION * IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/access/nbtree/nbtsort.c,v 1.51 2000/02/18 06:32:39 tgl Exp $ * $Header: /cvsroot/pgsql/src/backend/access/nbtree/nbtsort.c,v 1.52 2000/04/12 17:14:49 momjian Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
@ -99,9 +99,9 @@ _bt_spoolinit(Relation index, bool isunique)
btspool->sortstate = tuplesort_begin_index(index, isunique, false); btspool->sortstate = tuplesort_begin_index(index, isunique, false);
/* /*
* Currently, tuplesort provides sort functions on IndexTuples. * Currently, tuplesort provides sort functions on IndexTuples. If we
* If we kept anything in a BTItem other than a regular IndexTuple, * kept anything in a BTItem other than a regular IndexTuple, we'd
* we'd need to modify tuplesort to understand BTItems as such. * need to modify tuplesort to understand BTItems as such.
*/ */
Assert(sizeof(BTItemData) == sizeof(IndexTupleData)); Assert(sizeof(BTItemData) == sizeof(IndexTupleData));
@ -306,15 +306,15 @@ _bt_buildadd(Relation index, Size keysz, ScanKey scankey,
btisz = MAXALIGN(btisz); btisz = MAXALIGN(btisz);
/* /*
* Check whether the item can fit on a btree page at all. * Check whether the item can fit on a btree page at all. (Eventually,
* (Eventually, we ought to try to apply TOAST methods if not.) * we ought to try to apply TOAST methods if not.) We actually need to
* We actually need to be able to fit three items on every page, * be able to fit three items on every page, so restrict any one item
* so restrict any one item to 1/3 the per-page available space. * to 1/3 the per-page available space. Note that at this point, btisz
* Note that at this point, btisz doesn't include the ItemId. * doesn't include the ItemId.
* *
* NOTE: similar code appears in _bt_insertonpg() to defend against * NOTE: similar code appears in _bt_insertonpg() to defend against
* oversize items being inserted into an already-existing index. * oversize items being inserted into an already-existing index. But
* But during creation of an index, we don't go through there. * during creation of an index, we don't go through there.
*/ */
if (btisz > (PageGetPageSize(npage) - sizeof(PageHeaderData) - MAXALIGN(sizeof(BTPageOpaqueData))) / 3 - sizeof(ItemIdData)) if (btisz > (PageGetPageSize(npage) - sizeof(PageHeaderData) - MAXALIGN(sizeof(BTPageOpaqueData))) / 3 - sizeof(ItemIdData))
elog(ERROR, "btree: index item size %d exceeds maximum %ld", elog(ERROR, "btree: index item size %d exceeds maximum %ld",

View File

@ -8,7 +8,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/access/nbtree/nbtutils.c,v 1.35 2000/02/18 06:32:39 tgl Exp $ * $Header: /cvsroot/pgsql/src/backend/access/nbtree/nbtutils.c,v 1.36 2000/04/12 17:14:50 momjian Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
@ -141,7 +141,8 @@ _bt_orderkeys(Relation relation, BTScanOpaque so)
uint16 numberOfKeys = so->numberOfKeys; uint16 numberOfKeys = so->numberOfKeys;
uint16 new_numberOfKeys = 0; uint16 new_numberOfKeys = 0;
AttrNumber attno = 1; AttrNumber attno = 1;
bool equalStrategyEnd, underEqualStrategy; bool equalStrategyEnd,
underEqualStrategy;
if (numberOfKeys < 1) if (numberOfKeys < 1)
return; return;
@ -194,6 +195,7 @@ _bt_orderkeys(Relation relation, BTScanOpaque so)
elog(ERROR, "_bt_orderkeys: key(s) for attribute %d missed", attno + 1); elog(ERROR, "_bt_orderkeys: key(s) for attribute %d missed", attno + 1);
underEqualStrategy = (!equalStrategyEnd); underEqualStrategy = (!equalStrategyEnd);
/* /*
* If = has been specified, no other key will be used. In case * 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 * of key < 2 && key == 1 and so on we have to set qual_ok to

View File

@ -8,7 +8,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/access/rtree/Attic/rtree.c,v 1.44 2000/03/01 05:39:23 inoue Exp $ * $Header: /cvsroot/pgsql/src/backend/access/rtree/Attic/rtree.c,v 1.45 2000/04/12 17:14:51 momjian Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
@ -249,13 +249,13 @@ rtbuild(Relation heap,
/* /*
* Since we just counted the tuples in the heap, we update its stats * 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 * in pg_class to guarantee that the planner takes advantage of the
* index we just created. But, only update statistics during * index we just created. But, only update statistics during normal
* normal index definitions, not for indices on system catalogs * index definitions, not for indices on system catalogs created
* created during bootstrap processing. We must close the relations * during bootstrap processing. We must close the relations before
* before updating statistics to guarantee that the relcache entries * updating statistics to guarantee that the relcache entries are
* are flushed when we increment the command counter in UpdateStats(). * flushed when we increment the command counter in UpdateStats(). But
* But we do not release any locks on the relations; those will be * we do not release any locks on the relations; those will be held
* held until end of transaction. * until end of transaction.
*/ */
if (IsNormalProcessingMode()) if (IsNormalProcessingMode())
{ {

View File

@ -8,7 +8,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/access/rtree/Attic/rtscan.c,v 1.31 2000/01/26 05:56:00 momjian Exp $ * $Header: /cvsroot/pgsql/src/backend/access/rtree/Attic/rtscan.c,v 1.32 2000/04/12 17:14:51 momjian Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */

View File

@ -8,7 +8,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/access/transam/transam.c,v 1.33 2000/01/26 05:56:03 momjian Exp $ * $Header: /cvsroot/pgsql/src/backend/access/transam/transam.c,v 1.34 2000/04/12 17:14:52 momjian Exp $
* *
* NOTES * NOTES
* This file contains the high level access-method interface to the * This file contains the high level access-method interface to the
@ -162,6 +162,7 @@ TransactionLogTest(TransactionId transactionId, /* transaction id to test */
if (!fail) if (!fail)
{ {
/* /*
* DO NOT cache status for transactions in unknown state !!! * DO NOT cache status for transactions in unknown state !!!
*/ */

View File

@ -8,7 +8,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/access/transam/varsup.c,v 1.27 2000/03/31 02:43:31 tgl Exp $ * $Header: /cvsroot/pgsql/src/backend/access/transam/varsup.c,v 1.28 2000/04/12 17:14:53 momjian Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
@ -331,8 +331,8 @@ ReadNewTransactionId(TransactionId *xid)
SpinAcquire(OidGenLockId); /* not good for concurrency... */ SpinAcquire(OidGenLockId); /* not good for concurrency... */
/* /*
* Note that we don't check is ShmemVariableCache->xid_count equal * Note that we don't check is ShmemVariableCache->xid_count equal to
* to 0 or not. This will work as long as we don't call * 0 or not. This will work as long as we don't call
* ReadNewTransactionId() before GetNewTransactionId(). * ReadNewTransactionId() before GetNewTransactionId().
*/ */
if (ShmemVariableCache->nextXid == 0) if (ShmemVariableCache->nextXid == 0)

View File

@ -8,7 +8,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/access/transam/xact.c,v 1.63 2000/04/09 04:43:16 tgl Exp $ * $Header: /cvsroot/pgsql/src/backend/access/transam/xact.c,v 1.64 2000/04/12 17:14:53 momjian Exp $
* *
* NOTES * NOTES
* Transaction aborts can now occur two ways: * Transaction aborts can now occur two ways:
@ -517,8 +517,8 @@ CommandCounterIncrement()
CurrentTransactionStateData.scanCommandId = CurrentTransactionStateData.commandId; CurrentTransactionStateData.scanCommandId = CurrentTransactionStateData.commandId;
/* /*
* make cache changes visible to me. AtCommit_LocalCache() * make cache changes visible to me. AtCommit_LocalCache() instead of
* instead of AtCommit_Cache() is called here. * AtCommit_Cache() is called here.
*/ */
AtCommit_LocalCache(); AtCommit_LocalCache();
AtStart_Cache(); AtStart_Cache();
@ -628,15 +628,14 @@ RecordTransactionCommit()
xid = GetCurrentTransactionId(); xid = GetCurrentTransactionId();
/* /*
* flush the buffer manager pages. Note: if we have stable * flush the buffer manager pages. Note: if we have stable main
* main memory, dirty shared buffers are not flushed * memory, dirty shared buffers are not flushed plai 8/7/90
* plai 8/7/90
*/ */
leak = BufferPoolCheckLeak(); leak = BufferPoolCheckLeak();
/* /*
* If no one shared buffer was changed by this transaction then * If no one shared buffer was changed by this transaction then we
* we don't flush shared buffers and don't record commit status. * don't flush shared buffers and don't record commit status.
*/ */
if (SharedBufferChanged) if (SharedBufferChanged)
{ {
@ -645,8 +644,8 @@ RecordTransactionCommit()
ResetBufferPool(true); ResetBufferPool(true);
/* /*
* have the transaction access methods record the status * have the transaction access methods record the status of this
* of this transaction id in the pg_log relation. * transaction id in the pg_log relation.
*/ */
TransactionIdCommit(xid); TransactionIdCommit(xid);
@ -752,9 +751,9 @@ RecordTransactionAbort()
xid = GetCurrentTransactionId(); xid = GetCurrentTransactionId();
/* /*
* Have the transaction access methods record the status of * Have the transaction access methods record the status of this
* this transaction id in the pg_log relation. We skip it * transaction id in the pg_log relation. We skip it if no one shared
* if no one shared buffer was changed by this transaction. * buffer was changed by this transaction.
*/ */
if (SharedBufferChanged && !TransactionIdDidCommit(xid)) if (SharedBufferChanged && !TransactionIdDidCommit(xid))
TransactionIdAbort(xid); TransactionIdAbort(xid);
@ -965,13 +964,13 @@ CommitTransaction()
RecordTransactionCommit(); RecordTransactionCommit();
/* /*
* Let others know about no transaction in progress by me. * Let others know about no transaction in progress by me. Note that
* Note that this must be done _before_ releasing locks we hold * this must be done _before_ releasing locks we hold and
* and SpinAcquire(SInvalLock) is required: UPDATE with xid 0 is * SpinAcquire(SInvalLock) is required: UPDATE with xid 0 is blocked
* blocked by xid 1' UPDATE, xid 1 is doing commit while xid 2 * by xid 1' UPDATE, xid 1 is doing commit while xid 2 gets snapshot -
* gets snapshot - if xid 2' GetSnapshotData sees xid 1 as running * if xid 2' GetSnapshotData sees xid 1 as running then it must see
* then it must see xid 0 as running as well or it will see two * xid 0 as running as well or it will see two tuple versions - one
* tuple versions - one deleted by xid 1 and one inserted by xid 0. * deleted by xid 1 and one inserted by xid 0.
*/ */
if (MyProc != (PROC *) NULL) if (MyProc != (PROC *) NULL)
{ {

View File

@ -6,7 +6,7 @@
* Portions Copyright (c) 1996-2000, PostgreSQL, Inc * Portions Copyright (c) 1996-2000, PostgreSQL, Inc
* Portions Copyright (c) 1994, Regents of the University of California * Portions Copyright (c) 1994, Regents of the University of California
* *
* $Header: /cvsroot/pgsql/src/backend/access/transam/xlog.c,v 1.12 2000/03/20 07:25:39 vadim Exp $ * $Header: /cvsroot/pgsql/src/backend/access/transam/xlog.c,v 1.13 2000/04/12 17:14:53 momjian Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
@ -121,16 +121,16 @@ typedef struct ControlFileData
DBState state; /* */ DBState state; /* */
/* /*
* this data is used to make sure that configuration of this DB * this data is used to make sure that configuration of this DB is
* is compatible with the current backend * compatible with the current backend
*/ */
uint32 blcksz; /* block size for this DB */ uint32 blcksz; /* block size for this DB */
uint32 relseg_size; /* blocks per segment of large relation */ uint32 relseg_size; /* blocks per segment of large relation */
uint32 catalog_version_no; /* internal version number */ uint32 catalog_version_no; /* internal version number */
/* /*
* MORE DATA FOLLOWS AT THE END OF THIS STRUCTURE * MORE DATA FOLLOWS AT THE END OF THIS STRUCTURE - locations of data
* - locations of data dirs * dirs
*/ */
} ControlFileData; } ControlFileData;
@ -250,6 +250,7 @@ XLogInsert(RmgrId rmid, char *hdr, uint32 hdrlen, char *buf, uint32 buflen)
LgwrRqst = XLogCtl->LgwrRqst; LgwrRqst = XLogCtl->LgwrRqst;
LgwrResult = XLogCtl->LgwrResult; LgwrResult = XLogCtl->LgwrResult;
S_UNLOCK(&(XLogCtl->info_lck)); S_UNLOCK(&(XLogCtl->info_lck));
/* /*
* If cache is half filled then try to acquire lgwr lock * If cache is half filled then try to acquire lgwr lock
* and do LGWR work, but only once. * and do LGWR work, but only once.
@ -404,11 +405,13 @@ nbuf:
DOUBLEALIGN(Insert->currpos - ((char *) Insert->currpage)); DOUBLEALIGN(Insert->currpos - ((char *) Insert->currpage));
} }
freespace = ((char *) Insert->currpage) + BLCKSZ - Insert->currpos; freespace = ((char *) Insert->currpage) + BLCKSZ - Insert->currpos;
/* /*
* All done! Update global LgwrRqst if some block was filled up. * All done! Update global LgwrRqst if some block was filled up.
*/ */
if (freespace < SizeOfXLogRecord) if (freespace < SizeOfXLogRecord)
updrqst = true; /* curridx is filled and available for writing out */ updrqst = true; /* curridx is filled and available for
* writing out */
else else
curridx = PrevBufIdx(curridx); curridx = PrevBufIdx(curridx);
LgwrRqst.Write = XLogCtl->xlblocks[curridx]; LgwrRqst.Write = XLogCtl->xlblocks[curridx];
@ -581,6 +584,7 @@ GetFreeXLBuffer()
return; return;
} }
} }
/* /*
* LgwrResult lock is busy or un-updated. Try to acquire lgwr lock * LgwrResult lock is busy or un-updated. Try to acquire lgwr lock
* and write full blocks. * and write full blocks.
@ -595,9 +599,10 @@ GetFreeXLBuffer()
InitXLBuffer(curridx); InitXLBuffer(curridx);
return; return;
} }
/* /*
* Have to write buffers while holding insert lock - * Have to write buffers while holding insert lock - not
* not good... * good...
*/ */
XLogWrite(NULL); XLogWrite(NULL);
S_UNLOCK(&(XLogCtl->lgwr_lck)); S_UNLOCK(&(XLogCtl->lgwr_lck));
@ -985,9 +990,7 @@ got_record:;
} }
if (BLCKSZ - SizeOfXLogRecord >= if (BLCKSZ - SizeOfXLogRecord >=
record->xl_len + RecPtr->xrecoff % BLCKSZ + SizeOfXLogRecord) record->xl_len + RecPtr->xrecoff % BLCKSZ + SizeOfXLogRecord)
{
nextRecord = (XLogRecord *) ((char *) record + record->xl_len + SizeOfXLogRecord); nextRecord = (XLogRecord *) ((char *) record + record->xl_len + SizeOfXLogRecord);
}
EndRecPtr.xlogid = RecPtr->xlogid; EndRecPtr.xlogid = RecPtr->xlogid;
EndRecPtr.xrecoff = RecPtr->xrecoff + record->xl_len + SizeOfXLogRecord; EndRecPtr.xrecoff = RecPtr->xrecoff + record->xl_len + SizeOfXLogRecord;
ReadRecPtr = *RecPtr; ReadRecPtr = *RecPtr;
@ -1000,6 +1003,7 @@ next_record_is_invalid:;
nextRecord = NULL; nextRecord = NULL;
memset(buffer, 0, SizeOfXLogRecord); memset(buffer, 0, SizeOfXLogRecord);
record = (XLogRecord *) buffer; record = (XLogRecord *) buffer;
/* /*
* If we assumed that next record began on the same page where * If we assumed that next record began on the same page where
* previous one ended - zero end of page. * previous one ended - zero end of page.
@ -1166,6 +1170,7 @@ BootStrapXLOG()
#ifdef NOT_USED #ifdef NOT_USED
XLogPageHeader page = (XLogPageHeader) buffer; XLogPageHeader page = (XLogPageHeader) buffer;
XLogRecord *record; XLogRecord *record;
#endif #endif
#ifndef __CYGWIN__ #ifndef __CYGWIN__
@ -1189,7 +1194,8 @@ BootStrapXLOG()
page->xlp_magic = XLOG_PAGE_MAGIC; page->xlp_magic = XLOG_PAGE_MAGIC;
page->xlp_info = 0; page->xlp_info = 0;
record = (XLogRecord *) ((char *) page + SizeOfXLogPHD); record = (XLogRecord *) ((char *) page + SizeOfXLogPHD);
record->xl_prev.xlogid = 0; record->xl_prev.xrecoff = 0; record->xl_prev.xlogid = 0;
record->xl_prev.xrecoff = 0;
record->xl_xact_prev = record->xl_prev; record->xl_xact_prev = record->xl_prev;
record->xl_xid = InvalidTransactionId; record->xl_xid = InvalidTransactionId;
record->xl_len = sizeof(checkPoint); record->xl_len = sizeof(checkPoint);
@ -1257,6 +1263,7 @@ StartupXLOG()
char buffer[MAXLOGRECSZ + SizeOfXLogRecord]; char buffer[MAXLOGRECSZ + SizeOfXLogRecord];
int recovery = 0; int recovery = 0;
bool sie_saved = false; bool sie_saved = false;
#endif #endif
int fd; int fd;
@ -1400,7 +1407,8 @@ tryAgain:
/* Is REDO required ? */ /* Is REDO required ? */
if (XLByteLT(checkPoint.redo, RecPtr)) if (XLByteLT(checkPoint.redo, RecPtr))
record = ReadRecord(&(checkPoint.redo), buffer); record = ReadRecord(&(checkPoint.redo), buffer);
else /* read past CheckPoint record */ else
/* read past CheckPoint record */
record = ReadRecord(NULL, buffer); record = ReadRecord(NULL, buffer);
/* REDO */ /* REDO */

View File

@ -8,7 +8,7 @@
* Portions Copyright (c) 1994, Regents of the University of California * Portions Copyright (c) 1994, Regents of the University of California
* *
* IDENTIFICATION * IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/bootstrap/bootstrap.c,v 1.80 2000/02/18 09:28:39 inoue Exp $ * $Header: /cvsroot/pgsql/src/backend/bootstrap/bootstrap.c,v 1.81 2000/04/12 17:14:54 momjian Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
@ -325,8 +325,8 @@ BootstrapMain(int argc, char *argv[])
} }
/* /*
* Bootstrap under Postmaster means two things: * Bootstrap under Postmaster means two things: (xloginit) ?
* (xloginit) ? StartupXLOG : ShutdownXLOG * StartupXLOG : ShutdownXLOG
* *
* If !under Postmaster and xloginit then BootStrapXLOG. * If !under Postmaster and xloginit then BootStrapXLOG.
*/ */
@ -345,9 +345,7 @@ BootstrapMain(int argc, char *argv[])
} }
if (!IsUnderPostmaster && xloginit) if (!IsUnderPostmaster && xloginit)
{
BootStrapXLOG(); BootStrapXLOG();
}
/* /*
* backend initialization * backend initialization
@ -1153,8 +1151,10 @@ build_indices()
index_build(heap, ind, ILHead->il_natts, ILHead->il_attnos, index_build(heap, ind, ILHead->il_natts, ILHead->il_attnos,
ILHead->il_nparams, ILHead->il_params, ILHead->il_finfo, ILHead->il_nparams, ILHead->il_params, ILHead->il_finfo,
ILHead->il_predInfo); ILHead->il_predInfo);
/* In normal processing mode, index_build would close the heap
* and index, but in bootstrap mode it will not. /*
* In normal processing mode, index_build would close the heap and
* index, but in bootstrap mode it will not.
*/ */
/* /*

View File

@ -8,7 +8,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/catalog/aclchk.c,v 1.37 2000/01/26 05:56:09 momjian Exp $ * $Header: /cvsroot/pgsql/src/backend/catalog/aclchk.c,v 1.38 2000/04/12 17:14:55 momjian Exp $
* *
* NOTES * NOTES
* See acl.h. * See acl.h.

View File

@ -8,7 +8,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/catalog/catalog.c,v 1.31 2000/04/09 04:43:15 tgl Exp $ * $Header: /cvsroot/pgsql/src/backend/catalog/catalog.c,v 1.32 2000/04/12 17:14:55 momjian Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
@ -44,6 +44,7 @@ relpath(const char *relname)
snprintf(path, bufsize, "%s%c%s", DataDir, SEP_CHAR, relname); snprintf(path, bufsize, "%s%c%s", DataDir, SEP_CHAR, relname);
return path; return path;
} }
/* /*
* If it is in the current database, assume it is in current working * If it is in the current database, assume it is in current working
* directory. NB: this does not work during bootstrap! * directory. NB: this does not work during bootstrap!

View File

@ -8,7 +8,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/catalog/heap.c,v 1.124 2000/03/17 02:36:05 tgl Exp $ * $Header: /cvsroot/pgsql/src/backend/catalog/heap.c,v 1.125 2000/04/12 17:14:55 momjian Exp $
* *
* *
* INTERFACE ROUTINES * INTERFACE ROUTINES
@ -273,6 +273,7 @@ heap_create(char *relname,
MemSet((char *) rel, 0, len); MemSet((char *) rel, 0, len);
rel->rd_fd = -1; /* table is not open */ rel->rd_fd = -1; /* table is not open */
rel->rd_unlinked = TRUE; /* table is not created yet */ rel->rd_unlinked = TRUE; /* table is not created yet */
/* /*
* create a new tuple descriptor from the one passed in * create a new tuple descriptor from the one passed in
*/ */
@ -715,6 +716,7 @@ AddNewRelationTuple(Relation pg_class_desc,
if (!IsIgnoringSystemIndexes()) if (!IsIgnoringSystemIndexes())
{ {
/* /*
* First, open the catalog indices and insert index tuples for the * First, open the catalog indices and insert index tuples for the
* new relation. * new relation.
@ -1096,18 +1098,26 @@ DeleteRelationTuple(Relation rel)
static void static void
RelationTruncateIndexes(Relation heapRelation) RelationTruncateIndexes(Relation heapRelation)
{ {
Relation indexRelation, currentIndex; Relation indexRelation,
currentIndex;
ScanKeyData entry; ScanKeyData entry;
HeapScanDesc scan; HeapScanDesc scan;
HeapTuple indexTuple, procTuple, classTuple; HeapTuple indexTuple,
procTuple,
classTuple;
Form_pg_index index; Form_pg_index index;
Oid heapId, indexId, procId, accessMethodId; Oid heapId,
indexId,
procId,
accessMethodId;
Node *oldPred = NULL; Node *oldPred = NULL;
PredInfo *predInfo; PredInfo *predInfo;
List *cnfPred = NULL; List *cnfPred = NULL;
AttrNumber *attributeNumberA; AttrNumber *attributeNumberA;
FuncIndexInfo fInfo, *funcInfo = NULL; FuncIndexInfo fInfo,
int i, numberOfAttributes; *funcInfo = NULL;
int i,
numberOfAttributes;
char *predString; char *predString;
heapId = RelationGetRelid(heapRelation); heapId = RelationGetRelid(heapRelation);
@ -1120,8 +1130,10 @@ RelationTruncateIndexes(Relation heapRelation)
scan = heap_beginscan(indexRelation, false, SnapshotNow, 1, &entry); scan = heap_beginscan(indexRelation, false, SnapshotNow, 1, &entry);
while (HeapTupleIsValid(indexTuple = heap_getnext(scan, 0))) while (HeapTupleIsValid(indexTuple = heap_getnext(scan, 0)))
{ {
/* /*
* For each index, fetch index attributes so we can apply index_build * For each index, fetch index attributes so we can apply
* index_build
*/ */
index = (Form_pg_index) GETSTRUCT(indexTuple); index = (Form_pg_index) GETSTRUCT(indexTuple);
indexId = index->indexrelid; indexId = index->indexrelid;
@ -1181,8 +1193,8 @@ RelationTruncateIndexes(Relation heapRelation)
LockRelation(currentIndex, AccessExclusiveLock); LockRelation(currentIndex, AccessExclusiveLock);
/* /*
* Release any buffers associated with this index. If they're dirty, * Release any buffers associated with this index. If they're
* they're just dropped without bothering to flush to disk. * dirty, they're just dropped without bothering to flush to disk.
*/ */
ReleaseRelationBuffers(currentIndex); ReleaseRelationBuffers(currentIndex);
if (FlushRelationBuffers(currentIndex, (BlockNumber) 0, false) < 0) if (FlushRelationBuffers(currentIndex, (BlockNumber) 0, false) < 0)
@ -1198,11 +1210,11 @@ RelationTruncateIndexes(Relation heapRelation)
attributeNumberA, 0, NULL, funcInfo, predInfo); attributeNumberA, 0, NULL, funcInfo, predInfo);
/* /*
* index_build will close both the heap and index relations * index_build will close both the heap and index relations (but
* (but not give up the locks we hold on them). That's fine * not give up the locks we hold on them). That's fine for the
* for the index, but we need to open the heap again. We need * index, but we need to open the heap again. We need no new
* no new lock, since this backend still has the exclusive lock * lock, since this backend still has the exclusive lock grabbed
* grabbed by heap_truncate. * by heap_truncate.
*/ */
heapRelation = heap_open(heapId, NoLock); heapRelation = heap_open(heapId, NoLock);
Assert(heapRelation != NULL); Assert(heapRelation != NULL);
@ -1249,8 +1261,8 @@ heap_truncate(char *relname)
elog(NOTICE, "Caution: TRUNCATE TABLE cannot be rolled back, so don't abort now"); elog(NOTICE, "Caution: TRUNCATE TABLE cannot be rolled back, so don't abort now");
/* /*
* Release any buffers associated with this relation. If they're dirty, * Release any buffers associated with this relation. If they're
* they're just dropped without bothering to flush to disk. * dirty, they're just dropped without bothering to flush to disk.
*/ */
ReleaseRelationBuffers(rel); ReleaseRelationBuffers(rel);
@ -1547,8 +1559,8 @@ heap_drop_with_catalog(const char *relname)
/* /*
* Close relcache entry, but *keep* AccessExclusiveLock on the * Close relcache entry, but *keep* AccessExclusiveLock on the
* relation until transaction commit. This ensures no one else * relation until transaction commit. This ensures no one else will
* will try to do something with the doomed relation. * try to do something with the doomed relation.
*/ */
heap_close(rel, NoLock); heap_close(rel, NoLock);
@ -1714,6 +1726,7 @@ StoreAttrDefault(Relation rel, AttrNumber attnum, char *adbin,
* Need to construct source equivalent of given node-string. * Need to construct source equivalent of given node-string.
*/ */
expr = stringToNode(adbin); expr = stringToNode(adbin);
/* /*
* deparse_expression needs a RangeTblEntry list, so make one * deparse_expression needs a RangeTblEntry list, so make one
*/ */
@ -1796,6 +1809,7 @@ StoreRelCheck(Relation rel, char *ccname, char *ccbin)
*/ */
expr = stringToNode(ccbin); expr = stringToNode(ccbin);
expr = (Node *) make_ands_explicit((List *) expr); expr = (Node *) make_ands_explicit((List *) expr);
/* /*
* deparse_expression needs a RangeTblEntry list, so make one * deparse_expression needs a RangeTblEntry list, so make one
*/ */
@ -1850,9 +1864,10 @@ StoreConstraints(Relation rel)
if (!constr) if (!constr)
return; return;
/* deparsing of constraint expressions will fail unless the just-created /*
* pg_attribute tuples for this relation are made visible. So, bump * deparsing of constraint expressions will fail unless the
* the command counter. * just-created pg_attribute tuples for this relation are made
* visible. So, bump the command counter.
*/ */
CommandCounterIncrement(); CommandCounterIncrement();
@ -1921,8 +1936,8 @@ AddRelationRawConstraints(Relation rel,
} }
/* /*
* Create a dummy ParseState and insert the target relation as * Create a dummy ParseState and insert the target relation as its
* its sole rangetable entry. We need a ParseState for transformExpr. * sole rangetable entry. We need a ParseState for transformExpr.
*/ */
pstate = make_parsestate(NULL); pstate = make_parsestate(NULL);
makeRangeTable(pstate, NULL); makeRangeTable(pstate, NULL);
@ -1938,25 +1953,28 @@ AddRelationRawConstraints(Relation rel,
Oid type_id; Oid type_id;
Assert(colDef->raw_default != NULL); Assert(colDef->raw_default != NULL);
/* /*
* Transform raw parsetree to executable expression. * Transform raw parsetree to executable expression.
*/ */
expr = transformExpr(pstate, colDef->raw_default, EXPR_COLUMN_FIRST); expr = transformExpr(pstate, colDef->raw_default, EXPR_COLUMN_FIRST);
/* /*
* Make sure default expr does not refer to any vars. * Make sure default expr does not refer to any vars.
*/ */
if (contain_var_clause(expr)) if (contain_var_clause(expr))
elog(ERROR, "Cannot use attribute(s) in DEFAULT clause"); elog(ERROR, "Cannot use attribute(s) in DEFAULT clause");
/* /*
* Check that it will be possible to coerce the expression * Check that it will be possible to coerce the expression to the
* to the column's type. We store the expression without * column's type. We store the expression without coercion,
* coercion, however, to avoid premature coercion in cases like * however, to avoid premature coercion in cases like
* *
* CREATE TABLE tbl (fld datetime DEFAULT 'now'); * CREATE TABLE tbl (fld datetime DEFAULT 'now');
* *
* NB: this should match the code in updateTargetListEntry() * NB: this should match the code in updateTargetListEntry() that
* that will actually do the coercion, to ensure we don't accept * will actually do the coercion, to ensure we don't accept an
* an unusable default expression. * unusable default expression.
*/ */
type_id = exprType(expr); type_id = exprType(expr);
if (type_id != InvalidOid) if (type_id != InvalidOid)
@ -1975,14 +1993,17 @@ AddRelationRawConstraints(Relation rel,
typeidTypeName(type_id)); typeidTypeName(type_id));
} }
} }
/* /*
* Might as well try to reduce any constant expressions. * Might as well try to reduce any constant expressions.
*/ */
expr = eval_const_expressions(expr); expr = eval_const_expressions(expr);
/* /*
* Must fix opids, in case any operators remain... * Must fix opids, in case any operators remain...
*/ */
fix_opids(expr); fix_opids(expr);
/* /*
* OK, store it. * OK, store it.
*/ */
@ -2037,26 +2058,31 @@ AddRelationRawConstraints(Relation rel,
ccname = (char *) palloc(NAMEDATALEN); ccname = (char *) palloc(NAMEDATALEN);
snprintf(ccname, NAMEDATALEN, "$%d", numchecks + 1); snprintf(ccname, NAMEDATALEN, "$%d", numchecks + 1);
} }
/* /*
* Transform raw parsetree to executable expression. * Transform raw parsetree to executable expression.
*/ */
expr = transformExpr(pstate, cdef->raw_expr, EXPR_COLUMN_FIRST); expr = transformExpr(pstate, cdef->raw_expr, EXPR_COLUMN_FIRST);
/* /*
* Make sure it yields a boolean result. * Make sure it yields a boolean result.
*/ */
if (exprType(expr) != BOOLOID) if (exprType(expr) != BOOLOID)
elog(ERROR, "CHECK '%s' does not yield boolean result", elog(ERROR, "CHECK '%s' does not yield boolean result",
ccname); ccname);
/* /*
* Make sure no outside relations are referred to. * Make sure no outside relations are referred to.
*/ */
if (length(pstate->p_rtable) != 1) if (length(pstate->p_rtable) != 1)
elog(ERROR, "Only relation '%s' can be referenced in CHECK", elog(ERROR, "Only relation '%s' can be referenced in CHECK",
relname); relname);
/* /*
* Might as well try to reduce any constant expressions. * Might as well try to reduce any constant expressions.
*/ */
expr = eval_const_expressions(expr); expr = eval_const_expressions(expr);
/* /*
* Constraints are evaluated with execQual, which expects an * Constraints are evaluated with execQual, which expects an
* implicit-AND list, so convert expression to implicit-AND form. * implicit-AND list, so convert expression to implicit-AND form.
@ -2064,10 +2090,12 @@ AddRelationRawConstraints(Relation rel,
* overkill...) * overkill...)
*/ */
expr = (Node *) make_ands_implicit((Expr *) expr); expr = (Node *) make_ands_implicit((Expr *) expr);
/* /*
* Must fix opids in operator clauses. * Must fix opids in operator clauses.
*/ */
fix_opids(expr); fix_opids(expr);
/* /*
* OK, store it. * OK, store it.
*/ */
@ -2081,8 +2109,8 @@ AddRelationRawConstraints(Relation rel,
* We do this even if there was no change, in order to ensure that an * We do this even if there was no change, in order to ensure that an
* SI update message is sent out for the pg_class tuple, which will * SI update message is sent out for the pg_class tuple, which will
* force other backends to rebuild their relcache entries for the rel. * force other backends to rebuild their relcache entries for the rel.
* (Of course, for a newly created rel there is no need for an SI message, * (Of course, for a newly created rel there is no need for an SI
* but for ALTER TABLE ADD ATTRIBUTE this'd be important.) * message, but for ALTER TABLE ADD ATTRIBUTE this'd be important.)
*/ */
relrel = heap_openr(RelationRelationName, RowExclusiveLock); relrel = heap_openr(RelationRelationName, RowExclusiveLock);
reltup = SearchSysCacheTupleCopy(RELOID, reltup = SearchSysCacheTupleCopy(RELOID,

View File

@ -8,7 +8,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/catalog/index.c,v 1.107 2000/03/01 05:39:24 inoue Exp $ * $Header: /cvsroot/pgsql/src/backend/catalog/index.c,v 1.108 2000/04/12 17:14:55 momjian Exp $
* *
* *
* INTERFACE ROUTINES * INTERFACE ROUTINES
@ -77,16 +77,20 @@ static void DefaultBuild(Relation heapRelation, Relation indexRelation,
static Oid IndexGetRelation(Oid indexId); static Oid IndexGetRelation(Oid indexId);
static bool reindexing = false; static bool reindexing = false;
extern bool SetReindexProcessing(bool reindexmode) extern bool
SetReindexProcessing(bool reindexmode)
{ {
bool old = reindexing; bool old = reindexing;
reindexing = reindexmode; reindexing = reindexmode;
return old; return old;
} }
extern bool IsReindexProcessing(void) extern bool
IsReindexProcessing(void)
{ {
return reindexing; return reindexing;
} }
/* ---------------------------------------------------------------- /* ----------------------------------------------------------------
* sysatts is a structure containing attribute tuple forms * sysatts is a structure containing attribute tuple forms
* for system attributes (numbered -1, -2, ...). This really * for system attributes (numbered -1, -2, ...). This really
@ -1075,9 +1079,9 @@ index_create(char *heapRelationName,
* bootstrapping. Otherwise, we call the routine that constructs the * bootstrapping. Otherwise, we call the routine that constructs the
* index. * index.
* *
* In normal processing mode, the heap and index relations are closed * In normal processing mode, the heap and index relations are closed by
* by index_build() --- but we continue to hold the ShareLock on the * index_build() --- but we continue to hold the ShareLock on the heap
* heap that we acquired above, until end of transaction. * that we acquired above, until end of transaction.
*/ */
if (IsBootstrapProcessingMode()) if (IsBootstrapProcessingMode())
{ {
@ -1267,7 +1271,8 @@ FormIndexDatum(int numberOfAttributes,
* -------------------------------------------- * --------------------------------------------
*/ */
static static
bool LockClassinfoForUpdate(Oid relid, HeapTuple rtup, Buffer *buffer, bool confirmCommitted) bool
LockClassinfoForUpdate(Oid relid, HeapTuple rtup, Buffer *buffer, bool confirmCommitted)
{ {
HeapTuple classTuple; HeapTuple classTuple;
Form_pg_class pgcform; Form_pg_class pgcform;
@ -1295,6 +1300,7 @@ bool LockClassinfoForUpdate(Oid relid, HeapTuple rtup, Buffer *buffer, bool conf
if (confirmCommitted) if (confirmCommitted)
{ {
HeapTupleHeader th = rtup->t_data; HeapTupleHeader th = rtup->t_data;
if (!(th->t_infomask & HEAP_XMIN_COMMITTED)) if (!(th->t_infomask & HEAP_XMIN_COMMITTED))
elog(ERROR, "The tuple isn't committed"); elog(ERROR, "The tuple isn't committed");
if (th->t_infomask & HEAP_XMAX_COMMITTED) if (th->t_infomask & HEAP_XMAX_COMMITTED)
@ -1309,7 +1315,8 @@ bool LockClassinfoForUpdate(Oid relid, HeapTuple rtup, Buffer *buffer, bool conf
* Indexes of the relation active ? * Indexes of the relation active ?
* --------------------------------------------- * ---------------------------------------------
*/ */
bool IndexesAreActive(Oid relid, bool confirmCommitted) bool
IndexesAreActive(Oid relid, bool confirmCommitted)
{ {
HeapTupleData tuple; HeapTupleData tuple;
Relation indexRelation; Relation indexRelation;
@ -1406,13 +1413,15 @@ setRelhasindexInplace(Oid relid, bool hasindex, bool immediate)
heap_close(pg_class, RowExclusiveLock); heap_close(pg_class, RowExclusiveLock);
elog(ERROR, "setRelhasindexInplace: cannot scan RELATION relation"); elog(ERROR, "setRelhasindexInplace: cannot scan RELATION relation");
} }
/* /*
* Confirm that target tuple is locked by this transaction * Confirm that target tuple is locked by this transaction in case of
* in case of immedaite updation. * immedaite updation.
*/ */
if (immediate) if (immediate)
{ {
HeapTupleHeader th = tuple->t_data; HeapTupleHeader th = tuple->t_data;
if (!(th->t_infomask & HEAP_XMIN_COMMITTED)) if (!(th->t_infomask & HEAP_XMIN_COMMITTED))
elog(ERROR, "Immediate hasindex updation can be done only for committed tuples %x", th->t_infomask); elog(ERROR, "Immediate hasindex updation can be done only for committed tuples %x", th->t_infomask);
if (th->t_infomask & HEAP_XMAX_INVALID) if (th->t_infomask & HEAP_XMAX_INVALID)
@ -1697,10 +1706,12 @@ DefaultBuild(Relation heapRelation,
char *nullv; char *nullv;
long reltuples, long reltuples,
indtuples; indtuples;
#ifndef OMIT_PARTIAL_INDEX #ifndef OMIT_PARTIAL_INDEX
ExprContext *econtext; ExprContext *econtext;
TupleTable tupleTable; TupleTable tupleTable;
TupleTableSlot *slot; TupleTableSlot *slot;
#endif #endif
Node *predicate; Node *predicate;
Node *oldPred; Node *oldPred;
@ -1781,6 +1792,7 @@ DefaultBuild(Relation heapRelation,
reltuples++; reltuples++;
#ifndef OMIT_PARTIAL_INDEX #ifndef OMIT_PARTIAL_INDEX
/* /*
* If oldPred != NULL, this is an EXTEND INDEX command, so skip * If oldPred != NULL, this is an EXTEND INDEX command, so skip
* this tuple if it was already in the existing partial index * this tuple if it was already in the existing partial index
@ -1854,13 +1866,13 @@ DefaultBuild(Relation heapRelation,
/* /*
* Since we just counted the tuples in the heap, we update its stats * 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 * in pg_class to guarantee that the planner takes advantage of the
* index we just created. But, only update statistics during * index we just created. But, only update statistics during normal
* normal index definitions, not for indices on system catalogs * index definitions, not for indices on system catalogs created
* created during bootstrap processing. We must close the relations * during bootstrap processing. We must close the relations before
* before updating statistics to guarantee that the relcache entries * updating statistics to guarantee that the relcache entries are
* are flushed when we increment the command counter in UpdateStats(). * flushed when we increment the command counter in UpdateStats(). But
* But we do not release any locks on the relations; those will be * we do not release any locks on the relations; those will be held
* held until end of transaction. * until end of transaction.
*/ */
if (IsNormalProcessingMode()) if (IsNormalProcessingMode())
{ {
@ -2049,17 +2061,25 @@ activate_index(Oid indexId, bool activate)
bool bool
reindex_index(Oid indexId, bool force) reindex_index(Oid indexId, bool force)
{ {
Relation iRel, indexRelation, heapRelation; Relation iRel,
indexRelation,
heapRelation;
ScanKeyData entry; ScanKeyData entry;
HeapScanDesc scan; HeapScanDesc scan;
HeapTuple indexTuple, procTuple, classTuple; HeapTuple indexTuple,
procTuple,
classTuple;
Form_pg_index index; Form_pg_index index;
Oid heapId, procId, accessMethodId; Oid heapId,
procId,
accessMethodId;
Node *oldPred = NULL; Node *oldPred = NULL;
PredInfo *predInfo; PredInfo *predInfo;
AttrNumber *attributeNumberA; AttrNumber *attributeNumberA;
FuncIndexInfo fInfo, *funcInfo = NULL; FuncIndexInfo fInfo,
int i, numberOfAttributes; *funcInfo = NULL;
int i,
numberOfAttributes;
char *predString; char *predString;
bool old; bool old;
@ -2152,11 +2172,10 @@ reindex_index(Oid indexId, bool force)
attributeNumberA, 0, NULL, funcInfo, predInfo); attributeNumberA, 0, NULL, funcInfo, predInfo);
/* /*
* index_build will close both the heap and index relations * index_build will close both the heap and index relations (but not
* (but not give up the locks we hold on them). That's fine * give up the locks we hold on them). That's fine for the index, but
* for the index, but we need to open the heap again. We need * we need to open the heap again. We need no new lock, since this
* no new lock, since this backend still has the exclusive lock * backend still has the exclusive lock grabbed by heap_truncate.
* grabbed by heap_truncate.
*/ */
iRel = index_open(indexId); iRel = index_open(indexId);
Assert(iRel != NULL); Assert(iRel != NULL);
@ -2182,21 +2201,18 @@ activate_indexes_of_a_table(Oid relid, bool activate)
if (!activate) if (!activate)
setRelhasindexInplace(relid, false, true); setRelhasindexInplace(relid, false, true);
else else
{
return false; return false;
} }
}
else else
{ {
if (activate) if (activate)
reindex_relation(relid, false); reindex_relation(relid, false);
else else
{
return false; return false;
} }
}
return true; return true;
} }
/* -------------------------------- /* --------------------------------
* reindex_relation - This routine is used to recreate indexes * reindex_relation - This routine is used to recreate indexes
* of a relation. * of a relation.
@ -2209,7 +2225,8 @@ reindex_relation(Oid relid, bool force)
ScanKeyData entry; ScanKeyData entry;
HeapScanDesc scan; HeapScanDesc scan;
HeapTuple indexTuple; HeapTuple indexTuple;
bool old, reindexed; bool old,
reindexed;
old = SetReindexProcessing(true); old = SetReindexProcessing(true);
if (IndexesAreActive(relid, true)) if (IndexesAreActive(relid, true))
@ -2231,6 +2248,7 @@ reindex_relation(Oid relid, bool force)
while (HeapTupleIsValid(indexTuple = heap_getnext(scan, 0))) while (HeapTupleIsValid(indexTuple = heap_getnext(scan, 0)))
{ {
Form_pg_index index = (Form_pg_index) GETSTRUCT(indexTuple); Form_pg_index index = (Form_pg_index) GETSTRUCT(indexTuple);
if (activate_index(index->indexrelid, true)) if (activate_index(index->indexrelid, true))
reindexed = true; reindexed = true;
else else
@ -2242,9 +2260,7 @@ reindex_relation(Oid relid, bool force)
heap_endscan(scan); heap_endscan(scan);
heap_close(indexRelation, AccessShareLock); heap_close(indexRelation, AccessShareLock);
if (reindexed) if (reindexed)
{
setRelhasindexInplace(relid, true, false); setRelhasindexInplace(relid, true, false);
}
SetReindexProcessing(old); SetReindexProcessing(old);
return reindexed; return reindexed;
} }

View File

@ -9,7 +9,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/catalog/indexing.c,v 1.59 2000/02/18 09:28:41 inoue Exp $ * $Header: /cvsroot/pgsql/src/backend/catalog/indexing.c,v 1.60 2000/04/12 17:14:56 momjian Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
@ -1004,4 +1004,3 @@ TypeOidIndexScan(Relation heapRelation, Oid typeId)
return tuple; return tuple;
} }

View File

@ -8,7 +8,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/catalog/pg_aggregate.c,v 1.30 2000/03/26 19:43:58 tgl Exp $ * $Header: /cvsroot/pgsql/src/backend/catalog/pg_aggregate.c,v 1.31 2000/04/12 17:14:56 momjian Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
@ -200,8 +200,10 @@ AggregateCreate(char *aggName,
} }
else else
{ {
/* If no finalfn, aggregate result type is type of the sole
* state value (we already checked there is only one) /*
* If no finalfn, aggregate result type is type of the sole state
* value (we already checked there is only one)
*/ */
if (OidIsValid(xret1)) if (OidIsValid(xret1))
fret = xret1; fret = xret1;
@ -284,9 +286,9 @@ AggNameGetInitVal(char *aggName, Oid basetype, int xfuncno, bool *isNull)
Assert(xfuncno == 1 || xfuncno == 2); Assert(xfuncno == 1 || xfuncno == 2);
/* /*
* since we will have to use fastgetattr (in case one or both init vals * since we will have to use fastgetattr (in case one or both init
* are NULL), we will need to open the relation. Do that first to * vals are NULL), we will need to open the relation. Do that first
* ensure we don't get a stale tuple from the cache. * to ensure we don't get a stale tuple from the cache.
*/ */
aggRel = heap_openr(AggregateRelationName, AccessShareLock); aggRel = heap_openr(AggregateRelationName, AccessShareLock);

View File

@ -8,7 +8,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/catalog/pg_proc.c,v 1.41 2000/04/04 21:44:37 tgl Exp $ * $Header: /cvsroot/pgsql/src/backend/catalog/pg_proc.c,v 1.42 2000/04/12 17:14:56 momjian Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */

View File

@ -8,7 +8,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/catalog/pg_type.c,v 1.49 2000/01/26 05:56:11 momjian Exp $ * $Header: /cvsroot/pgsql/src/backend/catalog/pg_type.c,v 1.50 2000/04/12 17:14:56 momjian Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */

View File

@ -8,7 +8,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/commands/_deadcode/Attic/recipe.c,v 1.10 2000/01/26 05:56:17 momjian Exp $ * $Header: /cvsroot/pgsql/src/backend/commands/_deadcode/Attic/recipe.c,v 1.11 2000/04/12 17:15:06 momjian Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */

View File

@ -7,7 +7,7 @@
* Portions Copyright (c) 1994, Regents of the University of California * Portions Copyright (c) 1994, Regents of the University of California
* *
* IDENTIFICATION * IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/commands/async.c,v 1.58 2000/01/26 05:56:12 momjian Exp $ * $Header: /cvsroot/pgsql/src/backend/commands/async.c,v 1.59 2000/04/12 17:14:57 momjian Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
@ -155,12 +155,13 @@ Async_Notify(char *relname)
/* no point in making duplicate entries in the list ... */ /* no point in making duplicate entries in the list ... */
if (!AsyncExistsPendingNotify(relname)) if (!AsyncExistsPendingNotify(relname))
{ {
/* /*
* We allocate list memory from the global malloc pool to ensure * We allocate list memory from the global malloc pool to ensure
* that it will live until we want to use it. This is probably not * that it will live until we want to use it. This is probably
* necessary any longer, since we will use it before the end of the * not necessary any longer, since we will use it before the end
* transaction. DLList only knows how to use malloc() anyway, but we * of the transaction. DLList only knows how to use malloc()
* could probably palloc() the strings... * anyway, but we could probably palloc() the strings...
*/ */
notifyName = strdup(relname); notifyName = strdup(relname);
DLAddHead(pendingNotifies, DLNewElem(notifyName)); DLAddHead(pendingNotifies, DLNewElem(notifyName));
@ -466,6 +467,7 @@ AtCommit_Notify()
if (listenerPID == MyProcPid) if (listenerPID == MyProcPid)
{ {
/* /*
* Self-notify: no need to bother with table update. * Self-notify: no need to bother with table update.
* Indeed, we *must not* clear the notification field in * Indeed, we *must not* clear the notification field in
@ -491,6 +493,7 @@ AtCommit_Notify()
*/ */
if (kill(listenerPID, SIGUSR2) < 0) if (kill(listenerPID, SIGUSR2) < 0)
{ {
/* /*
* Get rid of pg_listener entry if it refers to a PID * Get rid of pg_listener entry if it refers to a PID
* that no longer exists. Presumably, that backend * that no longer exists. Presumably, that backend

View File

@ -15,7 +15,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/commands/cluster.c,v 1.50 2000/01/26 05:56:13 momjian Exp $ * $Header: /cvsroot/pgsql/src/backend/commands/cluster.c,v 1.51 2000/04/12 17:14:57 momjian Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
@ -104,8 +104,8 @@ cluster(char *oldrelname, char *oldindexname)
* Like vacuum, cluster spans transactions, so I'm going to handle it * Like vacuum, cluster spans transactions, so I'm going to handle it
* in the same way: commit and restart transactions where needed. * in the same way: commit and restart transactions where needed.
* *
* We grab exclusive access to the target rel and index for the * We grab exclusive access to the target rel and index for the duration
* duration of the initial transaction. * of the initial transaction.
*/ */
OldHeap = heap_openr(oldrelname, AccessExclusiveLock); OldHeap = heap_openr(oldrelname, AccessExclusiveLock);

View File

@ -8,7 +8,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/commands/Attic/command.c,v 1.70 2000/03/09 05:00:23 inoue Exp $ * $Header: /cvsroot/pgsql/src/backend/commands/Attic/command.c,v 1.71 2000/04/12 17:14:57 momjian Exp $
* *
* NOTES * NOTES
* The PortalExecutorHeapMemory crap needs to be eliminated * The PortalExecutorHeapMemory crap needs to be eliminated
@ -327,8 +327,8 @@ AlterTableAddColumn(const char *relationName,
#endif #endif
/* /*
* Grab an exclusive lock on the target table, which we will NOT release * Grab an exclusive lock on the target table, which we will NOT
* until end of transaction. * release until end of transaction.
*/ */
rel = heap_openr(relationName, AccessExclusiveLock); rel = heap_openr(relationName, AccessExclusiveLock);
myrelid = RelationGetRelid(rel); myrelid = RelationGetRelid(rel);
@ -547,8 +547,8 @@ AlterTableAlterColumn(const char *relationName,
/* /*
* find_all_inheritors does the recursive search of the * find_all_inheritors does the recursive search of the
* inheritance hierarchy, so all we have to do is process all * inheritance hierarchy, so all we have to do is process all of
* of the relids in the list that it returns. * the relids in the list that it returns.
*/ */
foreach(child, children) foreach(child, children)
{ {
@ -599,13 +599,14 @@ AlterTableAlterColumn(const char *relationName,
rawDefaults = lappend(rawDefaults, rawEnt); rawDefaults = lappend(rawDefaults, rawEnt);
/* /*
* This function is intended for CREATE TABLE, * This function is intended for CREATE TABLE, so it processes a
* so it processes a _list_ of defaults, but we just do one. * _list_ of defaults, but we just do one.
*/ */
AddRelationRawConstraints(rel, rawDefaults, NIL); AddRelationRawConstraints(rel, rawDefaults, NIL);
} }
else /* DROP DEFAULT */ else
/* DROP DEFAULT */
{ {
Relation attr_rel; Relation attr_rel;
ScanKeyData scankeys[3]; ScanKeyData scankeys[3];
@ -775,6 +776,7 @@ find_attribute_walker(Node *node, int attnum)
if (IsA(node, Var)) if (IsA(node, Var))
{ {
Var *var = (Var *) node; Var *var = (Var *) node;
if (var->varlevelsup == 0 && var->varno == 1 && if (var->varlevelsup == 0 && var->varno == 1 &&
var->varattno == attnum) var->varattno == attnum)
return true; return true;
@ -786,17 +788,20 @@ find_attribute_in_node(Node *node, int attnum)
{ {
return expression_tree_walker(node, find_attribute_walker, (void *) attnum); return expression_tree_walker(node, find_attribute_walker, (void *) attnum);
} }
/* /*
* Remove/check references for the column * Remove/check references for the column
*/ */
static bool static bool
RemoveColumnReferences(Oid reloid, int attnum, bool checkonly, HeapTuple reltup) RemoveColumnReferences(Oid reloid, int attnum, bool checkonly, HeapTuple reltup)
{ {
Relation indexRelation, rcrel; Relation indexRelation,
rcrel;
ScanKeyData entry; ScanKeyData entry;
HeapScanDesc scan; HeapScanDesc scan;
void *sysscan; void *sysscan;
HeapTuple htup, indexTuple; HeapTuple htup,
indexTuple;
Form_pg_index index; Form_pg_index index;
Form_pg_relcheck relcheck; Form_pg_relcheck relcheck;
Form_pg_class pgcform = (Form_pg_class) NULL; Form_pg_class pgcform = (Form_pg_class) NULL;
@ -806,6 +811,7 @@ RemoveColumnReferences(Oid reloid, int attnum, bool checkonly, HeapTuple reltup)
if (!checkonly) if (!checkonly)
pgcform = (Form_pg_class) GETSTRUCT(reltup); pgcform = (Form_pg_class) GETSTRUCT(reltup);
/* /*
* Remove/check constraints here * Remove/check constraints here
*/ */
@ -883,6 +889,7 @@ RemoveColumnReferences(Oid reloid, int attnum, bool checkonly, HeapTuple reltup)
return checkok; return checkok;
} }
#endif /* _DROP_COLUMN_HACK__ */ #endif /* _DROP_COLUMN_HACK__ */
/* /*
@ -894,8 +901,11 @@ AlterTableDropColumn(const char *relationName,
int behavior) int behavior)
{ {
#ifdef _DROP_COLUMN_HACK__ #ifdef _DROP_COLUMN_HACK__
Relation rel, attrdesc, adrel; Relation rel,
Oid myrelid, attoid; attrdesc,
adrel;
Oid myrelid,
attoid;
HeapTuple reltup; HeapTuple reltup;
HeapTupleData classtuple; HeapTupleData classtuple;
Buffer buffer; Buffer buffer;
@ -910,6 +920,7 @@ AlterTableDropColumn(const char *relationName,
if (inh) if (inh)
elog(ERROR, "ALTER TABLE / DROP COLUMN with inherit option is not supported yet"); elog(ERROR, "ALTER TABLE / DROP COLUMN with inherit option is not supported yet");
/* /*
* permissions checking. this would normally be done in utility.c, * permissions checking. this would normally be done in utility.c,
* but this particular routine is recursive. * but this particular routine is recursive.
@ -925,8 +936,8 @@ AlterTableDropColumn(const char *relationName,
#endif #endif
/* /*
* Grab an exclusive lock on the target table, which we will NOT release * Grab an exclusive lock on the target table, which we will NOT
* until end of transaction. * release until end of transaction.
*/ */
rel = heap_openr(relationName, AccessExclusiveLock); rel = heap_openr(relationName, AccessExclusiveLock);
myrelid = RelationGetRelid(rel); myrelid = RelationGetRelid(rel);
@ -987,6 +998,7 @@ AlterTableDropColumn(const char *relationName,
elog(ERROR, "ALTER TABLE: column name \"%s\" was already dropped", colName); elog(ERROR, "ALTER TABLE: column name \"%s\" was already dropped", colName);
attnum = attribute->attnum; attnum = attribute->attnum;
attoid = tup->t_data->t_oid; attoid = tup->t_data->t_oid;
/* /*
* Check constraints/indices etc here * Check constraints/indices etc here
*/ */
@ -1021,10 +1033,12 @@ AlterTableDropColumn(const char *relationName,
adrel = heap_openr(AttrDefaultRelationName, RowExclusiveLock); adrel = heap_openr(AttrDefaultRelationName, RowExclusiveLock);
ScanKeyEntryInitialize(&scankeys[0], 0x0, Anum_pg_attrdef_adrelid, ScanKeyEntryInitialize(&scankeys[0], 0x0, Anum_pg_attrdef_adrelid,
F_OIDEQ, ObjectIdGetDatum(myrelid)); F_OIDEQ, ObjectIdGetDatum(myrelid));
/* Oops pg_attrdef doesn't have (adrelid,adnum) index
ScanKeyEntryInitialize(&scankeys[1], 0x0, Anum_pg_attrdef_adnum, /*
F_INT2EQ, Int16GetDatum(attnum)); * Oops pg_attrdef doesn't have (adrelid,adnum) index
sysscan = systable_beginscan(adrel, AttrDefaultIndex, 2, scankeys); * ScanKeyEntryInitialize(&scankeys[1], 0x0, Anum_pg_attrdef_adnum,
* F_INT2EQ, Int16GetDatum(attnum)); sysscan =
* systable_beginscan(adrel, AttrDefaultIndex, 2, scankeys);
*/ */
sysscan = systable_beginscan(adrel, AttrDefaultIndex, 1, scankeys); sysscan = systable_beginscan(adrel, AttrDefaultIndex, 1, scankeys);
while (HeapTupleIsValid(tup = systable_getnext(sysscan))) while (HeapTupleIsValid(tup = systable_getnext(sysscan)))
@ -1037,6 +1051,7 @@ AlterTableDropColumn(const char *relationName,
} }
systable_endscan(sysscan); systable_endscan(sysscan);
heap_close(adrel, NoLock); heap_close(adrel, NoLock);
/* /*
* Remove objects which reference this column * Remove objects which reference this column
*/ */
@ -1094,10 +1109,11 @@ AlterTableAddConstraint(const char *relationName,
heap_close(rel, NoLock); heap_close(rel, NoLock);
/* /*
* Grab an exclusive lock on the fk table, and then scan through * Grab an exclusive lock on the fk table, and then scan
* each tuple, calling the RI_FKey_Match_Ins (insert trigger) * through each tuple, calling the RI_FKey_Match_Ins
* as if that tuple had just been inserted. If any of those * (insert trigger) as if that tuple had just been
* fail, it should elog(ERROR) and that's that. * inserted. If any of those fail, it should elog(ERROR)
* and that's that.
*/ */
rel = heap_openr(relationName, AccessExclusiveLock); rel = heap_openr(relationName, AccessExclusiveLock);
trig.tgoid = 0; trig.tgoid = 0;
@ -1121,11 +1137,13 @@ AlterTableAddConstraint(const char *relationName,
foreach(list, fkconstraint->fk_attrs) foreach(list, fkconstraint->fk_attrs)
{ {
Ident *fk_at = lfirst(list); Ident *fk_at = lfirst(list);
trig.tgargs[count++] = fk_at->name; trig.tgargs[count++] = fk_at->name;
} }
foreach(list, fkconstraint->pk_attrs) foreach(list, fkconstraint->pk_attrs)
{ {
Ident *pk_at = lfirst(list); Ident *pk_at = lfirst(list);
trig.tgargs[count++] = pk_at->name; trig.tgargs[count++] = pk_at->name;
} }
trig.tgnargs = count; trig.tgnargs = count;
@ -1136,6 +1154,7 @@ AlterTableAddConstraint(const char *relationName,
while (HeapTupleIsValid(tuple = heap_getnext(scan, 0))) while (HeapTupleIsValid(tuple = heap_getnext(scan, 0)))
{ {
TriggerData newtrigdata; TriggerData newtrigdata;
newtrigdata.tg_event = TRIGGER_EVENT_INSERT | TRIGGER_EVENT_ROW; newtrigdata.tg_event = TRIGGER_EVENT_INSERT | TRIGGER_EVENT_ROW;
newtrigdata.tg_relation = rel; newtrigdata.tg_relation = rel;
newtrigdata.tg_trigtuple = tuple; newtrigdata.tg_trigtuple = tuple;
@ -1149,7 +1168,8 @@ AlterTableAddConstraint(const char *relationName,
/* Make a call to the check function */ /* Make a call to the check function */
} }
heap_endscan(scan); heap_endscan(scan);
heap_close(rel, NoLock); /* close rel but keep lock! */ heap_close(rel, NoLock); /* close rel but keep
* lock! */
pfree(trig.tgargs); pfree(trig.tgargs);
} }

View File

@ -67,10 +67,13 @@ static void CommentTrigger(char *trigger, char *relation, char *comments);
*------------------------------------------------------------------ *------------------------------------------------------------------
*/ */
void CommentObject(int objtype, char *objname, char *objproperty, void
List *objlist, char *comment) { CommentObject(int objtype, char *objname, char *objproperty,
List *objlist, char *comment)
{
switch (objtype) { switch (objtype)
{
case (INDEX): case (INDEX):
case (SEQUENCE): case (SEQUENCE):
case (TABLE): case (TABLE):
@ -120,13 +123,16 @@ void CommentObject(int objtype, char *objname, char *objproperty,
*------------------------------------------------------------------ *------------------------------------------------------------------
*/ */
void CreateComments(Oid oid, char *comment) { void
CreateComments(Oid oid, char *comment)
{
Relation description; Relation description;
TupleDesc tupDesc; TupleDesc tupDesc;
HeapScanDesc scan; HeapScanDesc scan;
ScanKeyData entry; ScanKeyData entry;
HeapTuple desctuple = NULL, searchtuple; HeapTuple desctuple = NULL,
searchtuple;
Datum values[Natts_pg_description]; Datum values[Natts_pg_description];
char nulls[Natts_pg_description]; char nulls[Natts_pg_description];
char replaces[Natts_pg_description]; char replaces[Natts_pg_description];
@ -137,8 +143,10 @@ void CreateComments(Oid oid, char *comment) {
description = heap_openr(DescriptionRelationName, RowExclusiveLock); description = heap_openr(DescriptionRelationName, RowExclusiveLock);
tupDesc = description->rd_att; tupDesc = description->rd_att;
if ((comment != NULL) && (strlen(comment) > 0)) { if ((comment != NULL) && (strlen(comment) > 0))
for (i = 0; i < Natts_pg_description; i++) { {
for (i = 0; i < Natts_pg_description; i++)
{
nulls[i] = ' '; nulls[i] = ' ';
replaces[i] = 'r'; replaces[i] = 'r';
values[i] = (Datum) NULL; values[i] = (Datum) NULL;
@ -157,24 +165,29 @@ void CreateComments(Oid oid, char *comment) {
/*** If a previous tuple exists, either delete or prep replacement ***/ /*** If a previous tuple exists, either delete or prep replacement ***/
if (HeapTupleIsValid(searchtuple)) { if (HeapTupleIsValid(searchtuple))
{
/*** If the comment is blank, call heap_delete, else heap_update ***/ /*** If the comment is blank, call heap_delete, else heap_update ***/
if ((comment == NULL) || (strlen(comment) == 0)) { if ((comment == NULL) || (strlen(comment) == 0))
heap_delete(description, &searchtuple->t_self, NULL); heap_delete(description, &searchtuple->t_self, NULL);
} else { else
{
desctuple = heap_modifytuple(searchtuple, description, values, desctuple = heap_modifytuple(searchtuple, description, values,
nulls, replaces); nulls, replaces);
heap_update(description, &searchtuple->t_self, desctuple, NULL); heap_update(description, &searchtuple->t_self, desctuple, NULL);
modified = TRUE; modified = TRUE;
} }
} else { }
else
{
/*** Only if comment is non-blank do we form a new tuple ***/ /*** Only if comment is non-blank do we form a new tuple ***/
if ((comment != NULL) && (strlen(comment) > 0)) { if ((comment != NULL) && (strlen(comment) > 0))
{
desctuple = heap_formtuple(tupDesc, values, nulls); desctuple = heap_formtuple(tupDesc, values, nulls);
heap_insert(description, desctuple); heap_insert(description, desctuple);
modified = TRUE; modified = TRUE;
@ -186,8 +199,10 @@ void CreateComments(Oid oid, char *comment) {
heap_endscan(scan); heap_endscan(scan);
if (modified) { if (modified)
if (RelationGetForm(description)->relhasindex) { {
if (RelationGetForm(description)->relhasindex)
{
Relation idescs[Num_pg_description_indices]; Relation idescs[Num_pg_description_indices];
CatalogOpenIndices(Num_pg_description_indices, CatalogOpenIndices(Num_pg_description_indices,
@ -214,7 +229,9 @@ void CreateComments(Oid oid, char *comment) {
*------------------------------------------------------------------ *------------------------------------------------------------------
*/ */
void DeleteComments(Oid oid) { void
DeleteComments(Oid oid)
{
Relation description; Relation description;
TupleDesc tupDesc; TupleDesc tupDesc;
@ -234,9 +251,8 @@ void DeleteComments(Oid oid) {
/*** If a previous tuple exists, delete it ***/ /*** If a previous tuple exists, delete it ***/
if (HeapTupleIsValid(searchtuple)) { if (HeapTupleIsValid(searchtuple))
heap_delete(description, &searchtuple->t_self, NULL); heap_delete(description, &searchtuple->t_self, NULL);
}
/*** Complete the scan, update indices, if necessary ***/ /*** Complete the scan, update indices, if necessary ***/
@ -256,7 +272,9 @@ void DeleteComments(Oid oid) {
*------------------------------------------------------------------ *------------------------------------------------------------------
*/ */
static void CommentRelation(int reltype, char *relname, char *comment) { static void
CommentRelation(int reltype, char *relname, char *comment)
{
HeapTuple reltuple; HeapTuple reltuple;
Oid oid; Oid oid;
@ -265,18 +283,16 @@ static void CommentRelation(int reltype, char *relname, char *comment) {
/*** First, check object security ***/ /*** First, check object security ***/
#ifndef NO_SECURITY #ifndef NO_SECURITY
if (!pg_ownercheck(GetPgUserName(), relname, RELNAME)) { if (!pg_ownercheck(GetPgUserName(), relname, RELNAME))
elog(ERROR, "you are not permitted to comment on class '%s'", relname); elog(ERROR, "you are not permitted to comment on class '%s'", relname);
}
#endif #endif
/*** Now, attempt to find the oid in the cached version of pg_class ***/ /*** Now, attempt to find the oid in the cached version of pg_class ***/
reltuple = SearchSysCacheTuple(RELNAME, PointerGetDatum(relname), reltuple = SearchSysCacheTuple(RELNAME, PointerGetDatum(relname),
0, 0, 0); 0, 0, 0);
if (!HeapTupleIsValid(reltuple)) { if (!HeapTupleIsValid(reltuple))
elog(ERROR, "relation '%s' does not exist", relname); elog(ERROR, "relation '%s' does not exist", relname);
}
oid = reltuple->t_data->t_oid; oid = reltuple->t_data->t_oid;
@ -284,26 +300,23 @@ static void CommentRelation(int reltype, char *relname, char *comment) {
relkind = ((Form_pg_class) GETSTRUCT(reltuple))->relkind; relkind = ((Form_pg_class) GETSTRUCT(reltuple))->relkind;
switch (reltype) { switch (reltype)
{
case (INDEX): case (INDEX):
if (relkind != 'i') { if (relkind != 'i')
elog(ERROR, "relation '%s' is not an index", relname); elog(ERROR, "relation '%s' is not an index", relname);
}
break; break;
case (TABLE): case (TABLE):
if (relkind != 'r') { if (relkind != 'r')
elog(ERROR, "relation '%s' is not a table", relname); elog(ERROR, "relation '%s' is not a table", relname);
}
break; break;
case (VIEW): case (VIEW):
if (relkind != 'r') { if (relkind != 'r')
elog(ERROR, "relation '%s' is not a view", relname); elog(ERROR, "relation '%s' is not a view", relname);
}
break; break;
case (SEQUENCE): case (SEQUENCE):
if (relkind != 'S') { if (relkind != 'S')
elog(ERROR, "relation '%s' is not a sequence", relname); elog(ERROR, "relation '%s' is not a sequence", relname);
}
break; break;
} }
@ -325,7 +338,9 @@ static void CommentRelation(int reltype, char *relname, char *comment) {
*------------------------------------------------------------------ *------------------------------------------------------------------
*/ */
static void CommentAttribute(char *relname, char *attrname, char *comment) { static void
CommentAttribute(char *relname, char *attrname, char *comment)
{
Relation relation; Relation relation;
HeapTuple attrtuple; HeapTuple attrtuple;
@ -334,9 +349,8 @@ static void CommentAttribute(char *relname, char *attrname, char *comment) {
/*** First, check object security ***/ /*** First, check object security ***/
#ifndef NO_SECURITY #ifndef NO_SECURITY
if (!pg_ownercheck(GetPgUserName(), relname, RELNAME)) { if (!pg_ownercheck(GetPgUserName(), relname, RELNAME))
elog(ERROR, "you are not permitted to comment on class '%s\'", relname); elog(ERROR, "you are not permitted to comment on class '%s\'", relname);
}
#endif #endif
/*** Now, fetch the attribute oid from the system cache ***/ /*** Now, fetch the attribute oid from the system cache ***/
@ -344,7 +358,8 @@ static void CommentAttribute(char *relname, char *attrname, char *comment) {
relation = heap_openr(relname, AccessShareLock); relation = heap_openr(relname, AccessShareLock);
attrtuple = SearchSysCacheTuple(ATTNAME, ObjectIdGetDatum(relation->rd_id), attrtuple = SearchSysCacheTuple(ATTNAME, ObjectIdGetDatum(relation->rd_id),
PointerGetDatum(attrname), 0, 0); PointerGetDatum(attrname), 0, 0);
if (!HeapTupleIsValid(attrtuple)) { if (!HeapTupleIsValid(attrtuple))
{
elog(ERROR, "'%s' is not an attribute of class '%s'", elog(ERROR, "'%s' is not an attribute of class '%s'",
attrname, relname); attrname, relname);
} }
@ -371,15 +386,19 @@ static void CommentAttribute(char *relname, char *attrname, char *comment) {
*------------------------------------------------------------------ *------------------------------------------------------------------
*/ */
static void CommentDatabase(char *database, char *comment) { static void
CommentDatabase(char *database, char *comment)
{
Relation pg_database; Relation pg_database;
HeapTuple dbtuple, usertuple; HeapTuple dbtuple,
usertuple;
ScanKeyData entry; ScanKeyData entry;
HeapScanDesc scan; HeapScanDesc scan;
Oid oid; Oid oid;
bool superuser; bool superuser;
int4 dba, userid; int4 dba,
userid;
char *username; char *username;
/*** First find the tuple in pg_database for the database ***/ /*** First find the tuple in pg_database for the database ***/
@ -392,9 +411,8 @@ static void CommentDatabase(char *database, char *comment) {
/*** Validate database exists, and fetch the dba id and oid ***/ /*** Validate database exists, and fetch the dba id and oid ***/
if (!HeapTupleIsValid(dbtuple)) { if (!HeapTupleIsValid(dbtuple))
elog(ERROR, "database '%s' does not exist", database); elog(ERROR, "database '%s' does not exist", database);
}
dba = ((Form_pg_database) GETSTRUCT(dbtuple))->datdba; dba = ((Form_pg_database) GETSTRUCT(dbtuple))->datdba;
oid = dbtuple->t_data->t_oid; oid = dbtuple->t_data->t_oid;
@ -403,16 +421,16 @@ static void CommentDatabase(char *database, char *comment) {
username = GetPgUserName(); username = GetPgUserName();
usertuple = SearchSysCacheTuple(SHADOWNAME, PointerGetDatum(username), usertuple = SearchSysCacheTuple(SHADOWNAME, PointerGetDatum(username),
0, 0, 0); 0, 0, 0);
if (!HeapTupleIsValid(usertuple)) { if (!HeapTupleIsValid(usertuple))
elog(ERROR, "current user '%s' does not exist", username); elog(ERROR, "current user '%s' does not exist", username);
}
userid = ((Form_pg_shadow) GETSTRUCT(usertuple))->usesysid; userid = ((Form_pg_shadow) GETSTRUCT(usertuple))->usesysid;
superuser = ((Form_pg_shadow) GETSTRUCT(usertuple))->usesuper; superuser = ((Form_pg_shadow) GETSTRUCT(usertuple))->usesuper;
/*** Allow if the userid matches the database dba or is a superuser ***/ /*** Allow if the userid matches the database dba or is a superuser ***/
#ifndef NO_SECURITY #ifndef NO_SECURITY
if (!(superuser || (userid == dba))) { if (!(superuser || (userid == dba)))
{
elog(ERROR, "you are not permitted to comment on database '%s'", elog(ERROR, "you are not permitted to comment on database '%s'",
database); database);
} }
@ -439,11 +457,14 @@ static void CommentDatabase(char *database, char *comment) {
*------------------------------------------------------------------ *------------------------------------------------------------------
*/ */
static void CommentRewrite(char *rule, char *comment) { static void
CommentRewrite(char *rule, char *comment)
{
HeapTuple rewritetuple; HeapTuple rewritetuple;
Oid oid; Oid oid;
char *user, *relation; char *user,
*relation;
int aclcheck; int aclcheck;
/*** First, validate user ***/ /*** First, validate user ***/
@ -452,7 +473,8 @@ static void CommentRewrite(char *rule, char *comment) {
user = GetPgUserName(); user = GetPgUserName();
relation = RewriteGetRuleEventRel(rule); relation = RewriteGetRuleEventRel(rule);
aclcheck = pg_aclcheck(relation, user, ACL_RU); aclcheck = pg_aclcheck(relation, user, ACL_RU);
if (aclcheck != ACLCHECK_OK) { if (aclcheck != ACLCHECK_OK)
{
elog(ERROR, "you are not permitted to comment on rule '%s'", elog(ERROR, "you are not permitted to comment on rule '%s'",
rule); rule);
} }
@ -462,9 +484,8 @@ static void CommentRewrite(char *rule, char *comment) {
rewritetuple = SearchSysCacheTuple(RULENAME, PointerGetDatum(rule), rewritetuple = SearchSysCacheTuple(RULENAME, PointerGetDatum(rule),
0, 0, 0); 0, 0, 0);
if (!HeapTupleIsValid(rewritetuple)) { if (!HeapTupleIsValid(rewritetuple))
elog(ERROR, "rule '%s' does not exist", rule); elog(ERROR, "rule '%s' does not exist", rule);
}
oid = rewritetuple->t_data->t_oid; oid = rewritetuple->t_data->t_oid;
@ -485,7 +506,9 @@ static void CommentRewrite(char *rule, char *comment) {
*------------------------------------------------------------------ *------------------------------------------------------------------
*/ */
static void CommentType(char *type, char *comment) { static void
CommentType(char *type, char *comment)
{
HeapTuple typetuple; HeapTuple typetuple;
Oid oid; Oid oid;
@ -495,7 +518,8 @@ static void CommentType(char *type, char *comment) {
#ifndef NO_SECURITY #ifndef NO_SECURITY
user = GetPgUserName(); user = GetPgUserName();
if (!pg_ownercheck(user, type, TYPENAME)) { if (!pg_ownercheck(user, type, TYPENAME))
{
elog(ERROR, "you are not permitted to comment on type '%s'", elog(ERROR, "you are not permitted to comment on type '%s'",
type); type);
} }
@ -505,9 +529,8 @@ static void CommentType(char *type, char *comment) {
typetuple = SearchSysCacheTuple(TYPENAME, PointerGetDatum(type), typetuple = SearchSysCacheTuple(TYPENAME, PointerGetDatum(type),
0, 0, 0); 0, 0, 0);
if (!HeapTupleIsValid(typetuple)) { if (!HeapTupleIsValid(typetuple))
elog(ERROR, "type '%s' does not exist", type); elog(ERROR, "type '%s' does not exist", type);
}
oid = typetuple->t_data->t_oid; oid = typetuple->t_data->t_oid;
@ -527,33 +550,40 @@ static void CommentType(char *type, char *comment) {
*------------------------------------------------------------------ *------------------------------------------------------------------
*/ */
static void CommentAggregate(char *aggregate, char *argument, char *comment) { static void
CommentAggregate(char *aggregate, char *argument, char *comment)
{
HeapTuple aggtuple; HeapTuple aggtuple;
Oid baseoid, oid; Oid baseoid,
oid;
bool defined; bool defined;
char *user; char *user;
/*** First, attempt to determine the base aggregate oid ***/ /*** First, attempt to determine the base aggregate oid ***/
if (argument) { if (argument)
{
baseoid = TypeGet(argument, &defined); baseoid = TypeGet(argument, &defined);
if (!OidIsValid(baseoid)) { if (!OidIsValid(baseoid))
elog(ERROR, "aggregate type '%s' does not exist", argument); elog(ERROR, "aggregate type '%s' does not exist", argument);
} }
} else { else
baseoid = 0; baseoid = 0;
}
/*** Next, validate the user's attempt to comment ***/ /*** Next, validate the user's attempt to comment ***/
#ifndef NO_SECURITY #ifndef NO_SECURITY
user = GetPgUserName(); user = GetPgUserName();
if (!pg_aggr_ownercheck(user, aggregate, baseoid)) { if (!pg_aggr_ownercheck(user, aggregate, baseoid))
if (argument) { {
if (argument)
{
elog(ERROR, "you are not permitted to comment on aggregate '%s' %s '%s'", elog(ERROR, "you are not permitted to comment on aggregate '%s' %s '%s'",
aggregate, "with type", argument); aggregate, "with type", argument);
} else { }
else
{
elog(ERROR, "you are not permitted to comment on aggregate '%s'", elog(ERROR, "you are not permitted to comment on aggregate '%s'",
aggregate); aggregate);
} }
@ -564,13 +594,15 @@ static void CommentAggregate(char *aggregate, char *argument, char *comment) {
aggtuple = SearchSysCacheTuple(AGGNAME, PointerGetDatum(aggregate), aggtuple = SearchSysCacheTuple(AGGNAME, PointerGetDatum(aggregate),
ObjectIdGetDatum(baseoid), 0, 0); ObjectIdGetDatum(baseoid), 0, 0);
if (!HeapTupleIsValid(aggtuple)) { if (!HeapTupleIsValid(aggtuple))
if (argument) { {
if (argument)
{
elog(ERROR, "aggregate type '%s' does not exist for aggregate '%s'", elog(ERROR, "aggregate type '%s' does not exist for aggregate '%s'",
argument, aggregate); argument, aggregate);
} else {
elog(ERROR, "aggregate '%s' does not exist", aggregate);
} }
else
elog(ERROR, "aggregate '%s' does not exist", aggregate);
} }
oid = aggtuple->t_data->t_oid; oid = aggtuple->t_data->t_oid;
@ -592,12 +624,17 @@ static void CommentAggregate(char *aggregate, char *argument, char *comment) {
*------------------------------------------------------------------ *------------------------------------------------------------------
*/ */
static void CommentProc(char *function, List *arguments, char *comment) static void
CommentProc(char *function, List *arguments, char *comment)
{ {
HeapTuple argtuple, functuple; HeapTuple argtuple,
Oid oid, argoids[FUNC_MAX_ARGS]; functuple;
char *user, *argument; Oid oid,
int i, argcount; argoids[FUNC_MAX_ARGS];
char *user,
*argument;
int i,
argcount;
/*** First, initialize function's argument list with their type oids ***/ /*** First, initialize function's argument list with their type oids ***/
@ -606,13 +643,12 @@ static void CommentProc(char *function, List *arguments, char *comment)
if (argcount > FUNC_MAX_ARGS) if (argcount > FUNC_MAX_ARGS)
elog(ERROR, "functions cannot have more than %d arguments", elog(ERROR, "functions cannot have more than %d arguments",
FUNC_MAX_ARGS); FUNC_MAX_ARGS);
for (i = 0; i < argcount; i++) { for (i = 0; i < argcount; i++)
{
argument = strVal(lfirst(arguments)); argument = strVal(lfirst(arguments));
arguments = lnext(arguments); arguments = lnext(arguments);
if (strcmp(argument, "opaque") == 0) if (strcmp(argument, "opaque") == 0)
{
argoids[i] = 0; argoids[i] = 0;
}
else else
{ {
argtuple = SearchSysCacheTuple(TYPENAME, argtuple = SearchSysCacheTuple(TYPENAME,
@ -663,47 +699,56 @@ static void CommentProc(char *function, List *arguments, char *comment)
*------------------------------------------------------------------ *------------------------------------------------------------------
*/ */
static void CommentOperator(char *opername, List *arguments, char *comment) { static void
CommentOperator(char *opername, List *arguments, char *comment)
{
Form_pg_operator data; Form_pg_operator data;
HeapTuple optuple; HeapTuple optuple;
Oid oid, leftoid = InvalidOid, rightoid = InvalidOid; Oid oid,
leftoid = InvalidOid,
rightoid = InvalidOid;
bool defined; bool defined;
char oprtype = 0, *user, *lefttype = NULL, *righttype = NULL; char oprtype = 0,
*user,
*lefttype = NULL,
*righttype = NULL;
/*** Initialize our left and right argument types ***/ /*** Initialize our left and right argument types ***/
if (lfirst(arguments) != NULL) { if (lfirst(arguments) != NULL)
lefttype = strVal(lfirst(arguments)); lefttype = strVal(lfirst(arguments));
} if (lsecond(arguments) != NULL)
if (lsecond(arguments) != NULL) {
righttype = strVal(lsecond(arguments)); righttype = strVal(lsecond(arguments));
}
/*** Attempt to fetch the left oid, if specified ***/ /*** Attempt to fetch the left oid, if specified ***/
if (lefttype != NULL) { if (lefttype != NULL)
{
leftoid = TypeGet(lefttype, &defined); leftoid = TypeGet(lefttype, &defined);
if (!OidIsValid(leftoid)) { if (!OidIsValid(leftoid))
elog(ERROR, "left type '%s' does not exist", lefttype); elog(ERROR, "left type '%s' does not exist", lefttype);
} }
}
/*** Attempt to fetch the right oid, if specified ***/ /*** Attempt to fetch the right oid, if specified ***/
if (righttype != NULL) { if (righttype != NULL)
{
rightoid = TypeGet(righttype, &defined); rightoid = TypeGet(righttype, &defined);
if (!OidIsValid(rightoid)) { if (!OidIsValid(rightoid))
elog(ERROR, "right type '%s' does not exist", righttype); elog(ERROR, "right type '%s' does not exist", righttype);
} }
}
/*** Determine operator type ***/ /*** Determine operator type ***/
if (OidIsValid(leftoid) && (OidIsValid(rightoid))) oprtype = 'b'; if (OidIsValid(leftoid) && (OidIsValid(rightoid)))
else if (OidIsValid(leftoid)) oprtype = 'l'; oprtype = 'b';
else if (OidIsValid(rightoid)) oprtype = 'r'; else if (OidIsValid(leftoid))
else elog(ERROR, "operator '%s' is of an illegal type'", opername); oprtype = 'l';
else if (OidIsValid(rightoid))
oprtype = 'r';
else
elog(ERROR, "operator '%s' is of an illegal type'", opername);
/*** Attempt to fetch the operator oid ***/ /*** Attempt to fetch the operator oid ***/
@ -711,9 +756,8 @@ static void CommentOperator(char *opername, List *arguments, char *comment) {
ObjectIdGetDatum(leftoid), ObjectIdGetDatum(leftoid),
ObjectIdGetDatum(rightoid), ObjectIdGetDatum(rightoid),
CharGetDatum(oprtype)); CharGetDatum(oprtype));
if (!HeapTupleIsValid(optuple)) { if (!HeapTupleIsValid(optuple))
elog(ERROR, "operator '%s' does not exist", opername); elog(ERROR, "operator '%s' does not exist", opername);
}
oid = optuple->t_data->t_oid; oid = optuple->t_data->t_oid;
@ -721,7 +765,8 @@ static void CommentOperator(char *opername, List *arguments, char *comment) {
#ifndef NO_SECURITY #ifndef NO_SECURITY
user = GetPgUserName(); user = GetPgUserName();
if (!pg_ownercheck(user, (char *) ObjectIdGetDatum(oid), OPEROID)) { if (!pg_ownercheck(user, (char *) ObjectIdGetDatum(oid), OPEROID))
{
elog(ERROR, "you are not permitted to comment on operator '%s'", elog(ERROR, "you are not permitted to comment on operator '%s'",
opername); opername);
} }
@ -731,9 +776,8 @@ static void CommentOperator(char *opername, List *arguments, char *comment) {
data = (Form_pg_operator) GETSTRUCT(optuple); data = (Form_pg_operator) GETSTRUCT(optuple);
oid = regproctooid(data->oprcode); oid = regproctooid(data->oprcode);
if (oid == InvalidOid) { if (oid == InvalidOid)
elog(ERROR, "operator '%s' does not have an underlying function", opername); elog(ERROR, "operator '%s' does not have an underlying function", opername);
}
/*** Call CreateComments() to create/drop the comments ***/ /*** Call CreateComments() to create/drop the comments ***/
@ -752,10 +796,13 @@ static void CommentOperator(char *opername, List *arguments, char *comment) {
*------------------------------------------------------------------ *------------------------------------------------------------------
*/ */
static void CommentTrigger(char *trigger, char *relname, char *comment) { static void
CommentTrigger(char *trigger, char *relname, char *comment)
{
Form_pg_trigger data; Form_pg_trigger data;
Relation pg_trigger, relation; Relation pg_trigger,
relation;
HeapTuple triggertuple; HeapTuple triggertuple;
HeapScanDesc scan; HeapScanDesc scan;
ScanKeyData entry; ScanKeyData entry;
@ -766,7 +813,8 @@ static void CommentTrigger(char *trigger, char *relname, char *comment) {
#ifndef NO_SECURITY #ifndef NO_SECURITY
user = GetPgUserName(); user = GetPgUserName();
if (!pg_ownercheck(user, relname, RELNAME)) { if (!pg_ownercheck(user, relname, RELNAME))
{
elog(ERROR, "you are not permitted to comment on trigger '%s' %s '%s'", elog(ERROR, "you are not permitted to comment on trigger '%s' %s '%s'",
trigger, "defined for relation", relname); trigger, "defined for relation", relname);
} }
@ -780,9 +828,11 @@ static void CommentTrigger(char *trigger, char *relname, char *comment) {
F_OIDEQ, RelationGetRelid(relation)); F_OIDEQ, RelationGetRelid(relation));
scan = heap_beginscan(pg_trigger, 0, SnapshotNow, 1, &entry); scan = heap_beginscan(pg_trigger, 0, SnapshotNow, 1, &entry);
triggertuple = heap_getnext(scan, 0); triggertuple = heap_getnext(scan, 0);
while (HeapTupleIsValid(triggertuple)) { while (HeapTupleIsValid(triggertuple))
{
data = (Form_pg_trigger) GETSTRUCT(triggertuple); data = (Form_pg_trigger) GETSTRUCT(triggertuple);
if (namestrcmp(&(data->tgname), trigger) == 0) { if (namestrcmp(&(data->tgname), trigger) == 0)
{
oid = triggertuple->t_data->t_oid; oid = triggertuple->t_data->t_oid;
break; break;
} }
@ -791,7 +841,8 @@ static void CommentTrigger(char *trigger, char *relname, char *comment) {
/*** If no trigger exists for the relation specified, notify user ***/ /*** If no trigger exists for the relation specified, notify user ***/
if (oid == InvalidOid) { if (oid == InvalidOid)
{
elog(ERROR, "trigger '%s' defined for relation '%s' does not exist", elog(ERROR, "trigger '%s' defined for relation '%s' does not exist",
trigger, relname); trigger, relname);
} }

View File

@ -7,7 +7,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/commands/copy.c,v 1.103 2000/03/23 21:38:58 momjian Exp $ * $Header: /cvsroot/pgsql/src/backend/commands/copy.c,v 1.104 2000/04/12 17:14:58 momjian Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
@ -77,8 +77,10 @@ static bool fe_eof;
* encoding, if needed, can be set once at the start of the copy operation. * encoding, if needed, can be set once at the start of the copy operation.
*/ */
static StringInfoData attribute_buf; static StringInfoData attribute_buf;
#ifdef MULTIBYTE #ifdef MULTIBYTE
static int encoding; static int encoding;
#endif #endif
@ -195,6 +197,7 @@ CopyPeekChar(FILE *fp)
if (!fp) if (!fp)
{ {
int ch = pq_peekbyte(); int ch = pq_peekbyte();
if (ch == EOF) if (ch == EOF)
fe_eof = true; fe_eof = true;
return ch; return ch;
@ -280,8 +283,8 @@ DoCopy(char *relname, bool binary, bool oids, bool from, bool pipe,
* Open and lock the relation, using the appropriate lock type. * Open and lock the relation, using the appropriate lock type.
* *
* Note: AccessExclusive is probably overkill for copying to a relation, * Note: AccessExclusive is probably overkill for copying to a relation,
* but that's what the code grabs on the rel's indices. If this lock is * but that's what the code grabs on the rel's indices. If this lock
* relaxed then I think the index locks need relaxed also. * is relaxed then I think the index locks need relaxed also.
*/ */
rel = heap_openr(relname, (from ? AccessExclusiveLock : AccessShareLock)); rel = heap_openr(relname, (from ? AccessExclusiveLock : AccessShareLock));
@ -369,9 +372,7 @@ DoCopy(char *relname, bool binary, bool oids, bool from, bool pipe,
} }
if (!pipe) if (!pipe)
{
FreeFile(fp); FreeFile(fp);
}
else if (!from) else if (!from)
{ {
if (!binary) if (!binary)
@ -383,8 +384,9 @@ DoCopy(char *relname, bool binary, bool oids, bool from, bool pipe,
/* /*
* Close the relation. If reading, we can release the AccessShareLock * Close the relation. If reading, we can release the AccessShareLock
* we got; if writing, we should hold the lock until end of transaction * we got; if writing, we should hold the lock until end of
* to ensure that updates will be committed before lock is released. * transaction to ensure that updates will be committed before lock is
* released.
*/ */
heap_close(rel, (from ? NoLock : AccessShareLock)); heap_close(rel, (from ? NoLock : AccessShareLock));
} }
@ -399,8 +401,10 @@ CopyTo(Relation rel, bool binary, bool oids, FILE *fp, char *delim, char *null_p
int32 attr_count, int32 attr_count,
i; i;
#ifdef _DROP_COLUMN_HACK__ #ifdef _DROP_COLUMN_HACK__
bool *valid; bool *valid;
#endif /* _DROP_COLUMN_HACK__ */ #endif /* _DROP_COLUMN_HACK__ */
Form_pg_attribute *attr; Form_pg_attribute *attr;
FmgrInfo *out_functions; FmgrInfo *out_functions;
@ -765,7 +769,8 @@ CopyFrom(Relation rel, bool binary, bool oids, FILE *fp, char *delim, char *null
while (!done) while (!done)
{ {
if (QueryCancel) { if (QueryCancel)
{
lineno = 0; lineno = 0;
CancelQuery(); CancelQuery();
} }
@ -1189,6 +1194,7 @@ static char *
CopyReadAttribute(FILE *fp, bool *isnull, char *delim, int *newline, char *null_print) CopyReadAttribute(FILE *fp, bool *isnull, char *delim, int *newline, char *null_print)
{ {
int c; int c;
#ifdef MULTIBYTE #ifdef MULTIBYTE
int mblen; int mblen;
unsigned char s[2]; unsigned char s[2];
@ -1222,9 +1228,7 @@ CopyReadAttribute(FILE *fp, bool *isnull, char *delim, int *newline, char *null_
break; break;
} }
if (strchr(delim, c)) if (strchr(delim, c))
{
break; break;
}
if (c == '\\') if (c == '\\')
{ {
c = CopyGetChar(fp); c = CopyGetChar(fp);
@ -1272,9 +1276,12 @@ CopyReadAttribute(FILE *fp, bool *isnull, char *delim, int *newline, char *null_
c = val & 0377; c = val & 0377;
} }
break; break;
/* This is a special hack to parse `\N' as <backslash-N>
rather then just 'N' to provide compatibility with /*
the default NULL output. -- pe */ * This is a special hack to parse `\N' as
* <backslash-N> rather then just 'N' to provide
* compatibility with the default NULL output. -- pe
*/
case 'N': case 'N':
appendStringInfoCharMacro(&attribute_buf, '\\'); appendStringInfoCharMacro(&attribute_buf, '\\');
c = 'N'; c = 'N';
@ -1346,10 +1353,12 @@ CopyAttributeOut(FILE *fp, char *server_string, char *delim)
{ {
char *string; char *string;
char c; char c;
#ifdef MULTIBYTE #ifdef MULTIBYTE
char *string_start; char *string_start;
int mblen; int mblen;
int i; int i;
#endif #endif
#ifdef MULTIBYTE #ifdef MULTIBYTE

View File

@ -8,7 +8,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/commands/Attic/creatinh.c,v 1.56 2000/01/29 16:58:34 petere Exp $ * $Header: /cvsroot/pgsql/src/backend/commands/Attic/creatinh.c,v 1.57 2000/04/12 17:14:58 momjian Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
@ -145,14 +145,14 @@ DefineRelation(CreateStmt *stmt, char relkind)
StoreCatalogInheritance(relationId, inheritList); StoreCatalogInheritance(relationId, inheritList);
/* /*
* Now add any newly specified column default values * Now add any newly specified column default values and CHECK
* and CHECK constraints to the new relation. These are passed * constraints to the new relation. These are passed to us in the
* to us in the form of raw parsetrees; we need to transform * form of raw parsetrees; we need to transform them to executable
* them to executable expression trees before they can be added. * expression trees before they can be added. The most convenient way
* The most convenient way to do that is to apply the parser's * to do that is to apply the parser's transformExpr routine, but
* transformExpr routine, but transformExpr doesn't work unless * transformExpr doesn't work unless we have a pre-existing relation.
* we have a pre-existing relation. So, the transformation has * So, the transformation has to be postponed to this final step of
* to be postponed to this final step of CREATE TABLE. * CREATE TABLE.
* *
* First, scan schema to find new column defaults. * First, scan schema to find new column defaults.
*/ */
@ -181,21 +181,24 @@ DefineRelation(CreateStmt *stmt, char relkind)
return; return;
/* /*
* We must bump the command counter to make the newly-created * We must bump the command counter to make the newly-created relation
* relation tuple visible for opening. * tuple visible for opening.
*/ */
CommandCounterIncrement(); CommandCounterIncrement();
/* /*
* Open the new relation. * Open the new relation.
*/ */
rel = heap_openr(relname, AccessExclusiveLock); rel = heap_openr(relname, AccessExclusiveLock);
/* /*
* Parse and add the defaults/constraints. * Parse and add the defaults/constraints.
*/ */
AddRelationRawConstraints(rel, rawDefaults, stmt->constraints); AddRelationRawConstraints(rel, rawDefaults, stmt->constraints);
/* /*
* Clean up. We keep lock on new relation (although it shouldn't * Clean up. We keep lock on new relation (although it shouldn't be
* be visible to anyone else anyway, until commit). * visible to anyone else anyway, until commit).
*/ */
heap_close(rel, NoLock); heap_close(rel, NoLock);
} }
@ -284,6 +287,7 @@ MergeAttributes(List *schema, List *supers, List **supconstr)
foreach(rest, lnext(entry)) foreach(rest, lnext(entry))
{ {
/* /*
* check for duplicated names within the new relation * check for duplicated names within the new relation
*/ */
@ -357,6 +361,7 @@ MergeAttributes(List *schema, List *supers, List **supconstr)
attributeName); attributeName);
if (checkAttrExists(attributeName, attributeType, inhSchema)) if (checkAttrExists(attributeName, attributeType, inhSchema))
/* /*
* this entry already exists * this entry already exists
*/ */
@ -644,6 +649,7 @@ checkAttrExists(const char *attributeName, const char *attributeType, List *sche
if (strcmp(attributeName, def->colname) == 0) if (strcmp(attributeName, def->colname) == 0)
{ {
/* /*
* attribute exists. Make sure the types are the same. * attribute exists. Make sure the types are the same.
*/ */

View File

@ -8,7 +8,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/commands/dbcommands.c,v 1.52 2000/03/26 18:32:28 petere Exp $ * $Header: /cvsroot/pgsql/src/backend/commands/dbcommands.c,v 1.53 2000/04/12 17:14:58 momjian Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
@ -63,7 +63,8 @@ createdb(const char *dbname, const char *dbpath, int encoding)
char *loc; char *loc;
char locbuf[512]; char locbuf[512];
int4 user_id; int4 user_id;
bool use_super, use_createdb; bool use_super,
use_createdb;
Relation pg_database_rel; Relation pg_database_rel;
HeapTuple tuple; HeapTuple tuple;
TupleDesc pg_database_dsc; TupleDesc pg_database_dsc;
@ -97,8 +98,10 @@ createdb(const char *dbname, const char *dbpath, int encoding)
"This may be due to a character that is not allowed or because the chosen " "This may be due to a character that is not allowed or because the chosen "
"path isn't permitted for databases", dbpath); "path isn't permitted for databases", dbpath);
/* close virtual file descriptors so the kernel has more available for /*
the system() calls */ * close virtual file descriptors so the kernel has more available for
* the system() calls
*/
closeAllVfds(); closeAllVfds();
/* /*
@ -124,7 +127,8 @@ createdb(const char *dbname, const char *dbpath, int encoding)
* Update indexes (there aren't any currently) * Update indexes (there aren't any currently)
*/ */
#ifdef Num_pg_database_indices #ifdef Num_pg_database_indices
if (RelationGetForm(pg_database_rel)->relhasindex) { if (RelationGetForm(pg_database_rel)->relhasindex)
{
Relation idescs[Num_pg_database_indices]; Relation idescs[Num_pg_database_indices];
CatalogOpenIndices(Num_pg_database_indices, CatalogOpenIndices(Num_pg_database_indices,
@ -139,14 +143,15 @@ createdb(const char *dbname, const char *dbpath, int encoding)
/* Copy the template database to the new location */ /* Copy the template database to the new location */
if (mkdir(loc, S_IRWXU) != 0) { if (mkdir(loc, S_IRWXU) != 0)
elog(ERROR, "CREATE DATABASE: unable to create database directory '%s': %s", loc, strerror(errno)); elog(ERROR, "CREATE DATABASE: unable to create database directory '%s': %s", loc, strerror(errno));
}
snprintf(buf, sizeof(buf), "cp %s%cbase%ctemplate1%c* '%s'", snprintf(buf, sizeof(buf), "cp %s%cbase%ctemplate1%c* '%s'",
DataDir, SEP_CHAR, SEP_CHAR, SEP_CHAR, loc); DataDir, SEP_CHAR, SEP_CHAR, SEP_CHAR, loc);
if (system(buf) != 0) { if (system(buf) != 0)
{
int ret; int ret;
snprintf(buf, sizeof(buf), "rm -rf '%s'", loc); snprintf(buf, sizeof(buf), "rm -rf '%s'", loc);
ret = system(buf); ret = system(buf);
if (ret == 0) if (ret == 0)
@ -165,7 +170,8 @@ createdb(const char *dbname, const char *dbpath, int encoding)
void void
dropdb(const char *dbname) dropdb(const char *dbname)
{ {
int4 user_id, db_owner; int4 user_id,
db_owner;
bool use_super; bool use_super;
Oid db_id; Oid db_id;
char *path, char *path,
@ -203,25 +209,28 @@ dropdb(const char *dbname)
"This may be due to a character that is not allowed or because the chosen " "This may be due to a character that is not allowed or because the chosen "
"path isn't permitted for databases", path); "path isn't permitted for databases", path);
/* close virtual file descriptors so the kernel has more available for /*
the system() calls */ * close virtual file descriptors so the kernel has more available for
* the system() calls
*/
closeAllVfds(); closeAllVfds();
/* /*
* Obtain exclusive lock on pg_database. We need this to ensure * Obtain exclusive lock on pg_database. We need this to ensure that
* that no new backend starts up in the target database while we * no new backend starts up in the target database while we are
* are deleting it. (Actually, a new backend might still manage to * deleting it. (Actually, a new backend might still manage to start
* start up, because it will read pg_database without any locking * up, because it will read pg_database without any locking to
* to discover the database's OID. But it will detect its error * discover the database's OID. But it will detect its error in
* in ReverifyMyDatabase and shut down before any serious damage * ReverifyMyDatabase and shut down before any serious damage is done.
* is done. See postinit.c.) * See postinit.c.)
*/ */
pgdbrel = heap_openr(DatabaseRelationName, AccessExclusiveLock); pgdbrel = heap_openr(DatabaseRelationName, AccessExclusiveLock);
/* /*
* Check for active backends in the target database. * Check for active backends in the target database.
*/ */
if (DatabaseHasActiveBackends(db_id)) { if (DatabaseHasActiveBackends(db_id))
{
heap_close(pgdbrel, AccessExclusiveLock); heap_close(pgdbrel, AccessExclusiveLock);
elog(ERROR, "DROP DATABASE: Database \"%s\" is being accessed by other users", dbname); elog(ERROR, "DROP DATABASE: Database \"%s\" is being accessed by other users", dbname);
} }
@ -238,8 +247,11 @@ dropdb(const char *dbname)
if (!HeapTupleIsValid(tup)) if (!HeapTupleIsValid(tup))
{ {
heap_close(pgdbrel, AccessExclusiveLock); heap_close(pgdbrel, AccessExclusiveLock);
/* This error should never come up since the existence of the
database is checked earlier */ /*
* This error should never come up since the existence of the
* database is checked earlier
*/
elog(ERROR, "DROP DATABASE: Database \"%s\" doesn't exist despite earlier reports to the contrary", elog(ERROR, "DROP DATABASE: Database \"%s\" doesn't exist despite earlier reports to the contrary",
dbname); dbname);
} }

View File

@ -10,7 +10,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/commands/define.c,v 1.39 2000/04/07 13:39:24 thomas Exp $ * $Header: /cvsroot/pgsql/src/backend/commands/define.c,v 1.40 2000/04/12 17:14:58 momjian Exp $
* *
* DESCRIPTION * DESCRIPTION
* The "DefineFoo" routines take the parse tree and pick out the * The "DefineFoo" routines take the parse tree and pick out the
@ -143,6 +143,7 @@ compute_full_attributes(List *parameters, int32 *byte_pct_p,
*canCache_p = true; *canCache_p = true;
else if (strcasecmp(param->defname, "trusted") == 0) else if (strcasecmp(param->defname, "trusted") == 0)
{ {
/* /*
* we don't have untrusted functions any more. The 4.2 * 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
@ -233,12 +234,14 @@ CreateFunction(ProcedureStmt *stmt, CommandDest dest)
*/ */
bool returnsSet; bool returnsSet;
/* The function returns a set of values, as opposed to a singleton. */ /* The function returns a set of values, as opposed to a singleton. */
bool lanisPL = false; bool lanisPL = false;
/* /*
* The following are optional user-supplied attributes of the function. * The following are optional user-supplied attributes of the
* function.
*/ */
int32 byte_pct, int32 byte_pct,
perbyte_cpu, perbyte_cpu,
@ -316,8 +319,8 @@ CreateFunction(ProcedureStmt *stmt, CommandDest dest)
interpret_AS_clause(languageName, stmt->as, &prosrc_str, &probin_str); interpret_AS_clause(languageName, stmt->as, &prosrc_str, &probin_str);
/* /*
* And now that we have all the parameters, and know we're * And now that we have all the parameters, and know we're permitted
* permitted to do so, go ahead and create the function. * to do so, go ahead and create the function.
*/ */
ProcedureCreate(stmt->funcname, ProcedureCreate(stmt->funcname,
returnsSet, returnsSet,

View File

@ -5,7 +5,7 @@
* Portions Copyright (c) 1996-2000, PostgreSQL, Inc * Portions Copyright (c) 1996-2000, PostgreSQL, Inc
* Portions Copyright (c) 1994-5, Regents of the University of California * Portions Copyright (c) 1994-5, Regents of the University of California
* *
* $Header: /cvsroot/pgsql/src/backend/commands/explain.c,v 1.55 2000/03/14 23:06:12 thomas Exp $ * $Header: /cvsroot/pgsql/src/backend/commands/explain.c,v 1.56 2000/04/12 17:14:58 momjian Exp $
* *
*/ */

View File

@ -8,7 +8,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/commands/indexcmds.c,v 1.22 2000/02/25 02:58:48 tgl Exp $ * $Header: /cvsroot/pgsql/src/backend/commands/indexcmds.c,v 1.23 2000/04/12 17:14:58 momjian Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
@ -671,17 +671,24 @@ extern Oid MyDatabaseId;
void void
ReindexDatabase(const char *dbname, bool force, bool all) ReindexDatabase(const char *dbname, bool force, bool all)
{ {
Relation relation, relationRelation; Relation relation,
HeapTuple usertuple, dbtuple, tuple; relationRelation;
HeapTuple usertuple,
dbtuple,
tuple;
HeapScanDesc scan; HeapScanDesc scan;
int4 user_id, db_owner; int4 user_id,
db_owner;
bool superuser; bool superuser;
Oid db_id; Oid db_id;
char *username; char *username;
ScanKeyData scankey; ScanKeyData scankey;
PortalVariableMemory pmem; PortalVariableMemory pmem;
MemoryContext old; MemoryContext old;
int relcnt, relalc, i, oncealc = 200; int relcnt,
relalc,
i,
oncealc = 200;
Oid *relids = (Oid *) NULL; Oid *relids = (Oid *) NULL;
AssertArg(dbname); AssertArg(dbname);

View File

@ -8,7 +8,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/commands/Attic/remove.c,v 1.45 2000/01/26 05:56:13 momjian Exp $ * $Header: /cvsroot/pgsql/src/backend/commands/Attic/remove.c,v 1.46 2000/04/12 17:14:59 momjian Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
@ -156,7 +156,8 @@ SingleOpOperatorRemove(Oid typeOid)
{ {
key[0].sk_attno = attnums[i]; key[0].sk_attno = attnums[i];
scan = heap_beginscan(rel, 0, SnapshotNow, 1, key); scan = heap_beginscan(rel, 0, SnapshotNow, 1, key);
while (HeapTupleIsValid(tup = heap_getnext(scan, 0))) { while (HeapTupleIsValid(tup = heap_getnext(scan, 0)))
{
/*** This is apparently a routine not in use, but remove ***/ /*** This is apparently a routine not in use, but remove ***/
/*** any comments anyways ***/ /*** any comments anyways ***/

View File

@ -8,7 +8,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/commands/Attic/rename.c,v 1.41 2000/01/26 05:56:13 momjian Exp $ * $Header: /cvsroot/pgsql/src/backend/commands/Attic/rename.c,v 1.42 2000/04/12 17:14:59 momjian Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
@ -76,8 +76,8 @@ renameatt(char *relname,
#endif #endif
/* /*
* Grab an exclusive lock on the target table, which we will NOT release * Grab an exclusive lock on the target table, which we will NOT
* until end of transaction. * release until end of transaction.
*/ */
targetrelation = heap_openr(relname, AccessExclusiveLock); targetrelation = heap_openr(relname, AccessExclusiveLock);
relid = RelationGetRelid(targetrelation); relid = RelationGetRelid(targetrelation);
@ -160,6 +160,7 @@ renameatt(char *relname,
/* keep system catalog indices current */ /* keep system catalog indices current */
{ {
Relation irelations[Num_pg_attr_indices]; Relation irelations[Num_pg_attr_indices];
CatalogOpenIndices(Num_pg_attr_indices, Name_pg_attr_indices, irelations); CatalogOpenIndices(Num_pg_attr_indices, Name_pg_attr_indices, irelations);
CatalogIndexInsert(irelations, Num_pg_attr_indices, attrelation, oldatttup); CatalogIndexInsert(irelations, Num_pg_attr_indices, attrelation, oldatttup);
CatalogCloseIndices(Num_pg_attr_indices, irelations); CatalogCloseIndices(Num_pg_attr_indices, irelations);
@ -194,8 +195,8 @@ renamerel(const char *oldrelname, const char *newrelname)
newrelname); newrelname);
/* /*
* Grab an exclusive lock on the target table, which we will NOT release * Grab an exclusive lock on the target table, which we will NOT
* until end of transaction. * release until end of transaction.
*/ */
targetrelation = heap_openr(oldrelname, AccessExclusiveLock); targetrelation = heap_openr(oldrelname, AccessExclusiveLock);
@ -215,10 +216,11 @@ renamerel(const char *oldrelname, const char *newrelname)
elog(NOTICE, "Caution: RENAME TABLE cannot be rolled back, so don't abort now"); elog(NOTICE, "Caution: RENAME TABLE cannot be rolled back, so don't abort now");
/* /*
* Flush all blocks of the relation out of the buffer pool. We need this * Flush all blocks of the relation out of the buffer pool. We need
* because the blocks are marked with the relation's name as well as OID. * this because the blocks are marked with the relation's name as well
* If some backend tries to write a dirty buffer with mdblindwrt after * as OID. If some backend tries to write a dirty buffer with
* we've renamed the physical file, we'll be in big trouble. * mdblindwrt after we've renamed the physical file, we'll be in big
* trouble.
* *
* Since we hold the exclusive lock on the relation, we don't have to * Since we hold the exclusive lock on the relation, we don't have to
* worry about more blocks being read in while we finish the rename. * worry about more blocks being read in while we finish the rename.
@ -227,8 +229,8 @@ renamerel(const char *oldrelname, const char *newrelname)
elog(ERROR, "renamerel: unable to flush relation from buffer pool"); elog(ERROR, "renamerel: unable to flush relation from buffer pool");
/* /*
* Make sure smgr and lower levels close the relation's files. * Make sure smgr and lower levels close the relation's files. (Next
* (Next access to rel will reopen them.) * access to rel will reopen them.)
* *
* Note: we rely on shared cache invalidation message to make other * Note: we rely on shared cache invalidation message to make other
* backends close and re-open the files. * backends close and re-open the files.
@ -238,14 +240,15 @@ renamerel(const char *oldrelname, const char *newrelname)
/* /*
* Close rel, but keep exclusive lock! * Close rel, but keep exclusive lock!
* *
* Note: we don't do anything about updating the relcache entry; * Note: we don't do anything about updating the relcache entry; we
* we assume it will be flushed by shared cache invalidate. * assume it will be flushed by shared cache invalidate. XXX is this
* XXX is this good enough? What if relation is myxactonly? * good enough? What if relation is myxactonly?
*/ */
heap_close(targetrelation, NoLock); heap_close(targetrelation, NoLock);
/* /*
* Find relation's pg_class tuple, and make sure newrelname isn't in use. * Find relation's pg_class tuple, and make sure newrelname isn't in
* use.
*/ */
relrelation = heap_openr(RelationRelationName, RowExclusiveLock); relrelation = heap_openr(RelationRelationName, RowExclusiveLock);
@ -262,8 +265,8 @@ renamerel(const char *oldrelname, const char *newrelname)
* Perform physical rename of files. If this fails, we haven't yet * Perform physical rename of files. If this fails, we haven't yet
* done anything irreversible. * done anything irreversible.
* *
* XXX smgr.c ought to provide an interface for this; doing it * XXX smgr.c ought to provide an interface for this; doing it directly
* directly is bletcherous. * is bletcherous.
*/ */
strcpy(oldpath, relpath(oldrelname)); strcpy(oldpath, relpath(oldrelname));
strcpy(newpath, relpath(newrelname)); strcpy(newpath, relpath(newrelname));

View File

@ -410,7 +410,9 @@ init_sequence(char *caller, char *name)
if (elm != (SeqTable) NULL) if (elm != (SeqTable) NULL)
{ {
/* We are using a seqtable entry left over from a previous xact;
/*
* We are using a seqtable entry left over from a previous xact;
* must check for relid change. * must check for relid change.
*/ */
elm->rel = seqrel; elm->rel = seqrel;
@ -424,7 +426,9 @@ init_sequence(char *caller, char *name)
} }
else else
{ {
/* Time to make a new seqtable entry. These entries live as long
/*
* Time to make a new seqtable entry. These entries live as long
* as the backend does, so we use plain malloc for them. * as the backend does, so we use plain malloc for them.
*/ */
elm = (SeqTable) malloc(sizeof(SeqTableData)); elm = (SeqTable) malloc(sizeof(SeqTableData));

View File

@ -7,7 +7,7 @@
* Portions Copyright (c) 1994, Regents of the University of California * Portions Copyright (c) 1994, Regents of the University of California
* *
* IDENTIFICATION * IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/commands/trigger.c,v 1.62 2000/02/29 12:28:24 wieck Exp $ * $Header: /cvsroot/pgsql/src/backend/commands/trigger.c,v 1.63 2000/04/12 17:14:59 momjian Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
@ -261,10 +261,11 @@ CreateTrigger(CreateTrigStmt *stmt)
CatalogCloseIndices(Num_pg_class_indices, ridescs); CatalogCloseIndices(Num_pg_class_indices, ridescs);
heap_freetuple(tuple); heap_freetuple(tuple);
heap_close(pgrel, RowExclusiveLock); heap_close(pgrel, RowExclusiveLock);
/* /*
* We used to try to update the rel's relcache entry here, but that's * We used to try to update the rel's relcache entry here, but that's
* fairly pointless since it will happen as a byproduct of the upcoming * fairly pointless since it will happen as a byproduct of the
* CommandCounterIncrement... * upcoming CommandCounterIncrement...
*/ */
/* Keep lock on target rel until end of xact */ /* Keep lock on target rel until end of xact */
heap_close(rel, NoLock); heap_close(rel, NoLock);
@ -337,10 +338,11 @@ DropTrigger(DropTrigStmt *stmt)
CatalogCloseIndices(Num_pg_class_indices, ridescs); CatalogCloseIndices(Num_pg_class_indices, ridescs);
heap_freetuple(tuple); heap_freetuple(tuple);
heap_close(pgrel, RowExclusiveLock); heap_close(pgrel, RowExclusiveLock);
/* /*
* We used to try to update the rel's relcache entry here, but that's * We used to try to update the rel's relcache entry here, but that's
* fairly pointless since it will happen as a byproduct of the upcoming * fairly pointless since it will happen as a byproduct of the
* CommandCounterIncrement... * upcoming CommandCounterIncrement...
*/ */
/* Keep lock on target rel until end of xact */ /* Keep lock on target rel until end of xact */
heap_close(rel, NoLock); heap_close(rel, NoLock);
@ -360,7 +362,8 @@ RelationRemoveTriggers(Relation rel)
tgscan = heap_beginscan(tgrel, 0, SnapshotNow, 1, &key); tgscan = heap_beginscan(tgrel, 0, SnapshotNow, 1, &key);
while (HeapTupleIsValid(tup = heap_getnext(tgscan, 0))) { while (HeapTupleIsValid(tup = heap_getnext(tgscan, 0)))
{
/*** Delete any comments associated with this trigger ***/ /*** Delete any comments associated with this trigger ***/
@ -688,9 +691,9 @@ equalTriggerDescs(TriggerDesc *trigdesc1, TriggerDesc *trigdesc2)
j; j;
/* /*
* We need not examine the "index" data, just the trigger array itself; * We need not examine the "index" data, just the trigger array
* if we have the same triggers with the same types, the derived index * itself; if we have the same triggers with the same types, the
* data should match. * derived index data should match.
* *
* XXX It seems possible that the same triggers could appear in different * XXX It seems possible that the same triggers could appear in different
* orders in the two trigger arrays; do we need to handle that? * orders in the two trigger arrays; do we need to handle that?
@ -1499,7 +1502,8 @@ DeferredTriggerSetState(ConstraintsSetStmt *stmt)
* Handle SET CONSTRAINTS ALL ... * Handle SET CONSTRAINTS ALL ...
* ---------- * ----------
*/ */
if (stmt->constraints == NIL) { if (stmt->constraints == NIL)
{
if (!IsTransactionBlock()) if (!IsTransactionBlock())
{ {
/* ---------- /* ----------
@ -1533,7 +1537,9 @@ DeferredTriggerSetState(ConstraintsSetStmt *stmt)
MemoryContextSwitchTo(oldcxt); MemoryContextSwitchTo(oldcxt);
return; return;
} else { }
else
{
/* ---------- /* ----------
* ... inside of a transaction block * ... inside of a transaction block
* ---------- * ----------
@ -1629,9 +1635,7 @@ DeferredTriggerSetState(ConstraintsSetStmt *stmt)
heap_fetch(tgrel, SnapshotNow, &tuple, &buffer); heap_fetch(tgrel, SnapshotNow, &tuple, &buffer);
pfree(indexRes); pfree(indexRes);
if (!tuple.t_data) if (!tuple.t_data)
{
continue; continue;
}
htup = &tuple; htup = &tuple;
} }
else else
@ -1716,7 +1720,9 @@ DeferredTriggerSetState(ConstraintsSetStmt *stmt)
MemoryContextSwitchTo(oldcxt); MemoryContextSwitchTo(oldcxt);
return; return;
} else { }
else
{
/* ---------- /* ----------
* Inside of a transaction block set the trigger * Inside of a transaction block set the trigger
* states of individual triggers on transaction level. * states of individual triggers on transaction level.
@ -2012,5 +2018,3 @@ DeferredTriggerSaveEvent(Relation rel, int event,
return; return;
} }

View File

@ -6,7 +6,7 @@
* Portions Copyright (c) 1996-2000, PostgreSQL, Inc * Portions Copyright (c) 1996-2000, PostgreSQL, Inc
* Portions Copyright (c) 1994, Regents of the University of California * Portions Copyright (c) 1994, Regents of the University of California
* *
* $Id: user.c,v 1.51 2000/03/15 07:02:56 tgl Exp $ * $Id: user.c,v 1.52 2000/04/12 17:14:59 momjian Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
@ -81,24 +81,33 @@ write_password_file(Relation rel)
scan = heap_beginscan(rel, false, SnapshotSelf, 0, NULL); scan = heap_beginscan(rel, false, SnapshotSelf, 0, NULL);
while (HeapTupleIsValid(tuple = heap_getnext(scan, 0))) while (HeapTupleIsValid(tuple = heap_getnext(scan, 0)))
{ {
Datum datum_n, datum_p, datum_v; Datum datum_n,
bool null_n, null_p, null_v; datum_p,
datum_v;
bool null_n,
null_p,
null_v;
datum_n = heap_getattr(tuple, Anum_pg_shadow_usename, dsc, &null_n); datum_n = heap_getattr(tuple, Anum_pg_shadow_usename, dsc, &null_n);
if (null_n) if (null_n)
continue; /* don't allow empty users */ continue; /* don't allow empty users */
datum_p = heap_getattr(tuple, Anum_pg_shadow_passwd, dsc, &null_p); datum_p = heap_getattr(tuple, Anum_pg_shadow_passwd, dsc, &null_p);
/* It could be argued that people having a null password
shouldn't be allowed to connect, because they need /*
to have a password set up first. If you think assuming * It could be argued that people having a null password shouldn't
an empty password in that case is better, erase the following line. */ * be allowed to connect, because they need to have a password set
* up first. If you think assuming an empty password in that case
* is better, erase the following line.
*/
if (null_p) if (null_p)
continue; continue;
datum_v = heap_getattr(tuple, Anum_pg_shadow_valuntil, dsc, &null_v); datum_v = heap_getattr(tuple, Anum_pg_shadow_valuntil, dsc, &null_v);
/* These fake entries are not really necessary. To remove them, the parser /*
in backend/libpq/crypt.c would need to be adjusted. Initdb might also * These fake entries are not really necessary. To remove them,
need adjustments. */ * the parser in backend/libpq/crypt.c would need to be adjusted.
* Initdb might also need adjustments.
*/
fprintf(fp, fprintf(fp,
"%s" "%s"
CRYPT_PWD_FILE_SEPSTR CRYPT_PWD_FILE_SEPSTR
@ -117,7 +126,8 @@ write_password_file(Relation rel)
"%s\n", "%s\n",
nameout(DatumGetName(datum_n)), nameout(DatumGetName(datum_n)),
null_p ? "" : textout((text *) datum_p), null_p ? "" : textout((text *) datum_p),
null_v ? "\\N" : nabstimeout((AbsoluteTime)datum_v) /* this is how the parser wants it */ null_v ? "\\N" : nabstimeout((AbsoluteTime) datum_v) /* this is how the
* parser wants it */
); );
if (ferror(fp)) if (ferror(fp))
elog(ERROR, "%s: %s", tempname, strerror(errno)); elog(ERROR, "%s: %s", tempname, strerror(errno));
@ -127,7 +137,8 @@ write_password_file(Relation rel)
FreeFile(fp); FreeFile(fp);
/* /*
* And rename the temp file to its final name, deleting the old pg_pwd. * And rename the temp file to its final name, deleting the old
* pg_pwd.
*/ */
rename(tempname, filename); rename(tempname, filename);
@ -150,12 +161,13 @@ HeapTuple
update_pg_pwd(void) update_pg_pwd(void)
{ {
Relation rel = heap_openr(ShadowRelationName, AccessExclusiveLock); Relation rel = heap_openr(ShadowRelationName, AccessExclusiveLock);
write_password_file(rel); write_password_file(rel);
heap_close(rel, AccessExclusiveLock); heap_close(rel, AccessExclusiveLock);
/* /*
* This is a trigger, so clean out the information provided by * This is a trigger, so clean out the information provided by the
* the trigger manager. * trigger manager.
*/ */
CurrentTriggerData = NULL; CurrentTriggerData = NULL;
return NULL; return NULL;
@ -190,19 +202,20 @@ CreateUser(CreateUserStmt *stmt)
if (!superuser()) if (!superuser())
elog(ERROR, "CREATE USER: permission denied"); elog(ERROR, "CREATE USER: permission denied");
/* The reason for the following is this: /*
* If you start a transaction block, create a user, then roll back the * The reason for the following is this: If you start a transaction
* transaction, the pg_pwd won't get rolled back due to a bug in the * block, create a user, then roll back the transaction, the pg_pwd
* Unix file system ( :}). Hence this is in the interest of security. * won't get rolled back due to a bug in the Unix file system ( :}).
* Hence this is in the interest of security.
*/ */
if (IsTransactionBlock()) if (IsTransactionBlock())
elog(ERROR, "CREATE USER: may not be called in a transaction block"); elog(ERROR, "CREATE USER: may not be called in a transaction block");
/* /*
* Scan the pg_shadow relation to be certain the user or id doesn't already * Scan the pg_shadow relation to be certain the user or id doesn't
* exist. Note we secure exclusive lock, because we also need to be * already exist. Note we secure exclusive lock, because we also need
* sure of what the next usesysid should be, and we need to protect * to be sure of what the next usesysid should be, and we need to
* our update of the flat password file. * protect our update of the flat password file.
*/ */
pg_shadow_rel = heap_openr(ShadowRelationName, AccessExclusiveLock); pg_shadow_rel = heap_openr(ShadowRelationName, AccessExclusiveLock);
pg_shadow_dsc = RelationGetDescr(pg_shadow_rel); pg_shadow_dsc = RelationGetDescr(pg_shadow_rel);
@ -219,7 +232,8 @@ CreateUser(CreateUserStmt *stmt)
datum = heap_getattr(tuple, Anum_pg_shadow_usesysid, pg_shadow_dsc, &null); datum = heap_getattr(tuple, Anum_pg_shadow_usesysid, pg_shadow_dsc, &null);
if (havesysid) /* customized id wanted */ if (havesysid) /* customized id wanted */
sysid_exists = datum && !null && ((int) datum == stmt->sysid); sysid_exists = datum && !null && ((int) datum == stmt->sysid);
else /* pick 1 + max */ else
/* pick 1 + max */
{ {
if ((int) datum > max_id) if ((int) datum > max_id)
max_id = (int) datum; max_id = (int) datum;
@ -240,7 +254,8 @@ CreateUser(CreateUserStmt *stmt)
/* /*
* Build a tuple to insert * Build a tuple to insert
*/ */
new_record[Anum_pg_shadow_usename-1] = PointerGetDatum(namein(stmt->user)); /* this truncated properly */ new_record[Anum_pg_shadow_usename - 1] = PointerGetDatum(namein(stmt->user)); /* this truncated
* properly */
new_record[Anum_pg_shadow_usesysid - 1] = Int32GetDatum(havesysid ? stmt->sysid : max_id + 1); new_record[Anum_pg_shadow_usesysid - 1] = Int32GetDatum(havesysid ? stmt->sysid : max_id + 1);
AssertState(BoolIsValid(stmt->createdb)); AssertState(BoolIsValid(stmt->createdb));
@ -279,7 +294,8 @@ CreateUser(CreateUserStmt *stmt)
/* /*
* Update indexes * Update indexes
*/ */
if (RelationGetForm(pg_shadow_rel)->relhasindex) { if (RelationGetForm(pg_shadow_rel)->relhasindex)
{
Relation idescs[Num_pg_shadow_indices]; Relation idescs[Num_pg_shadow_indices];
CatalogOpenIndices(Num_pg_shadow_indices, CatalogOpenIndices(Num_pg_shadow_indices,
@ -297,7 +313,8 @@ CreateUser(CreateUserStmt *stmt)
{ {
AlterGroupStmt ags; AlterGroupStmt ags;
ags.name = strVal(lfirst(item)); /* the group name to add this in */ ags.name = strVal(lfirst(item)); /* the group name to add
* this in */
ags.action = +1; ags.action = +1;
ags.listUsers = lcons((void *) makeInteger(havesysid ? stmt->sysid : max_id + 1), NIL); ags.listUsers = lcons((void *) makeInteger(havesysid ? stmt->sysid : max_id + 1), NIL);
AlterGroup(&ags, "CREATE USER"); AlterGroup(&ags, "CREATE USER");
@ -307,6 +324,7 @@ CreateUser(CreateUserStmt *stmt)
* Write the updated pg_shadow data to the flat password file. * Write the updated pg_shadow data to the flat password file.
*/ */
write_password_file(pg_shadow_rel); write_password_file(pg_shadow_rel);
/* /*
* Now we can clean up. * Now we can clean up.
*/ */
@ -325,7 +343,8 @@ AlterUser(AlterUserStmt *stmt)
char new_record_nulls[Natts_pg_shadow]; char new_record_nulls[Natts_pg_shadow];
Relation pg_shadow_rel; Relation pg_shadow_rel;
TupleDesc pg_shadow_dsc; TupleDesc pg_shadow_dsc;
HeapTuple tuple, new_tuple; HeapTuple tuple,
new_tuple;
bool null; bool null;
if (stmt->password) if (stmt->password)
@ -342,9 +361,9 @@ AlterUser(AlterUserStmt *stmt)
elog(ERROR, "ALTER USER: may not be called in a transaction block"); elog(ERROR, "ALTER USER: may not be called in a transaction block");
/* /*
* Scan the pg_shadow relation to be certain the user exists. * Scan the pg_shadow relation to be certain the user exists. Note we
* Note we secure exclusive lock to protect our update of the * secure exclusive lock to protect our update of the flat password
* flat password file. * file.
*/ */
pg_shadow_rel = heap_openr(ShadowRelationName, AccessExclusiveLock); pg_shadow_rel = heap_openr(ShadowRelationName, AccessExclusiveLock);
pg_shadow_dsc = RelationGetDescr(pg_shadow_rel); pg_shadow_dsc = RelationGetDescr(pg_shadow_rel);
@ -548,9 +567,9 @@ DropUser(DropUserStmt *stmt)
heap_close(pg_rel, AccessExclusiveLock); heap_close(pg_rel, AccessExclusiveLock);
/* /*
* Somehow we'd have to check for tables, views, etc. owned by the user * Somehow we'd have to check for tables, views, etc. owned by the
* as well, but those could be spread out over all sorts of databases * user as well, but those could be spread out over all sorts of
* which we don't have access to (easily). * databases which we don't have access to (easily).
*/ */
/* /*
@ -572,7 +591,9 @@ DropUser(DropUserStmt *stmt)
datum = heap_getattr(tmp_tuple, Anum_pg_group_groname, pg_dsc, &null); datum = heap_getattr(tmp_tuple, Anum_pg_group_groname, pg_dsc, &null);
ags.name = nameout(DatumGetName(datum)); /* the group name from which to try to drop the user */ ags.name = nameout(DatumGetName(datum)); /* the group name from
* which to try to drop
* the user */
ags.action = -1; ags.action = -1;
ags.listUsers = lcons((void *) makeInteger(usesysid), NIL); ags.listUsers = lcons((void *) makeInteger(usesysid), NIL);
AlterGroup(&ags, "DROP USER"); AlterGroup(&ags, "DROP USER");
@ -643,7 +664,8 @@ CreateGroup(CreateGroupStmt *stmt)
int max_id = 0; int max_id = 0;
Datum new_record[Natts_pg_group]; Datum new_record[Natts_pg_group];
char new_record_nulls[Natts_pg_group]; char new_record_nulls[Natts_pg_group];
List *item, *newlist=NULL; List *item,
*newlist = NULL;
ArrayType *userarray; ArrayType *userarray;
/* /*
@ -653,8 +675,8 @@ CreateGroup(CreateGroupStmt *stmt)
elog(ERROR, "CREATE GROUP: permission denied"); elog(ERROR, "CREATE GROUP: permission denied");
/* /*
* There is not real reason for this, but it makes it consistent * There is not real reason for this, but it makes it consistent with
* with create user, and it seems like a good idea anyway. * create user, and it seems like a good idea anyway.
*/ */
if (IsTransactionBlock()) if (IsTransactionBlock())
elog(ERROR, "CREATE GROUP: may not be called in a transaction block"); elog(ERROR, "CREATE GROUP: may not be called in a transaction block");
@ -675,7 +697,8 @@ CreateGroup(CreateGroupStmt *stmt)
datum = heap_getattr(tuple, Anum_pg_group_grosysid, pg_group_dsc, &null); datum = heap_getattr(tuple, Anum_pg_group_grosysid, pg_group_dsc, &null);
if (stmt->sysid >= 0) /* customized id wanted */ if (stmt->sysid >= 0) /* customized id wanted */
sysid_exists = datum && !null && ((int) datum == stmt->sysid); sysid_exists = datum && !null && ((int) datum == stmt->sysid);
else /* pick 1 + max */ else
/* pick 1 + max */
{ {
if ((int) datum > max_id) if ((int) datum > max_id)
max_id = (int) datum; max_id = (int) datum;
@ -729,10 +752,8 @@ CreateGroup(CreateGroupStmt *stmt)
/* fill the array */ /* fill the array */
i = 0; i = 0;
foreach(item, newlist) foreach(item, newlist)
{
((int *) ARR_DATA_PTR(userarray))[i++] = intVal(lfirst(item)); ((int *) ARR_DATA_PTR(userarray))[i++] = intVal(lfirst(item));
} }
}
else else
userarray = NULL; userarray = NULL;
@ -762,7 +783,8 @@ CreateGroup(CreateGroupStmt *stmt)
/* /*
* Update indexes * Update indexes
*/ */
if (RelationGetForm(pg_group_rel)->relhasindex) { if (RelationGetForm(pg_group_rel)->relhasindex)
{
Relation idescs[Num_pg_group_indices]; Relation idescs[Num_pg_group_indices];
CatalogOpenIndices(Num_pg_group_indices, CatalogOpenIndices(Num_pg_group_indices,
@ -794,8 +816,8 @@ AlterGroup(AlterGroupStmt *stmt, const char * tag)
elog(ERROR, "%s: permission denied", tag); elog(ERROR, "%s: permission denied", tag);
/* /*
* There is not real reason for this, but it makes it consistent * There is not real reason for this, but it makes it consistent with
* with alter user, and it seems like a good idea anyway. * alter user, and it seems like a good idea anyway.
*/ */
if (IsTransactionBlock()) if (IsTransactionBlock())
elog(ERROR, "%s: may not be called in a transaction block", tag); elog(ERROR, "%s: may not be called in a transaction block", tag);
@ -805,9 +827,8 @@ AlterGroup(AlterGroupStmt *stmt, const char * tag)
pg_group_dsc = RelationGetDescr(pg_group_rel); pg_group_dsc = RelationGetDescr(pg_group_rel);
/* /*
* Verify that group exists. * Verify that group exists. If we find a tuple, will take that the
* If we find a tuple, will take that the rest of the way and make our * rest of the way and make our modifications on it.
* modifications on it.
*/ */
if (!HeapTupleIsValid(group_tuple = SearchSysCacheTupleCopy(GRONAME, PointerGetDatum(stmt->name), 0, 0, 0))) if (!HeapTupleIsValid(group_tuple = SearchSysCacheTupleCopy(GRONAME, PointerGetDatum(stmt->name), 0, 0, 0)))
{ {
@ -816,15 +837,19 @@ AlterGroup(AlterGroupStmt *stmt, const char * tag)
} }
AssertState(stmt->action == +1 || stmt->action == -1); AssertState(stmt->action == +1 || stmt->action == -1);
/* /*
* Now decide what to do. * Now decide what to do.
*/ */
if (stmt->action == +1) /* add users, might also be invoked by create user */ if (stmt->action == +1) /* add users, might also be invoked by
* create user */
{ {
Datum new_record[Natts_pg_group]; Datum new_record[Natts_pg_group];
char new_record_nulls[Natts_pg_group] = {' ', ' ', ' '}; char new_record_nulls[Natts_pg_group] = {' ', ' ', ' '};
ArrayType *newarray, *oldarray; ArrayType *newarray,
List * newlist = NULL, *item; *oldarray;
List *newlist = NULL,
*item;
HeapTuple tuple; HeapTuple tuple;
bool null = false; bool null = false;
Datum datum = heap_getattr(group_tuple, Anum_pg_group_grolist, pg_group_dsc, &null); Datum datum = heap_getattr(group_tuple, Anum_pg_group_grolist, pg_group_dsc, &null);
@ -836,9 +861,11 @@ AlterGroup(AlterGroupStmt *stmt, const char * tag)
if (!null) if (!null)
for (i = ARR_LBOUND(oldarray)[0]; i < ARR_LBOUND(oldarray)[0] + ARR_DIMS(oldarray)[0]; i++) for (i = ARR_LBOUND(oldarray)[0]; i < ARR_LBOUND(oldarray)[0] + ARR_DIMS(oldarray)[0]; i++)
{ {
int index, arrval; int index,
arrval;
Value *v; Value *v;
bool valueNull; bool valueNull;
index = i; index = i;
arrval = DatumGetInt32(array_ref(oldarray, 1, &index, true /* by value */ , arrval = DatumGetInt32(array_ref(oldarray, 1, &index, true /* by value */ ,
sizeof(int), 0, &valueNull)); sizeof(int), 0, &valueNull));
@ -849,8 +876,8 @@ AlterGroup(AlterGroupStmt *stmt, const char * tag)
} }
/* /*
* now convert the to be added usernames to sysids and add them * now convert the to be added usernames to sysids and add them to
* to the list * the list
*/ */
foreach(item, stmt->listUsers) foreach(item, stmt->listUsers)
{ {
@ -871,8 +898,11 @@ AlterGroup(AlterGroupStmt *stmt, const char * tag)
} }
else if (strcmp(tag, "CREATE USER") == 0) else if (strcmp(tag, "CREATE USER") == 0)
{ {
/* in this case we already know the uid and it wouldn't
be in the cache anyway yet */ /*
* in this case we already know the uid and it wouldn't be
* in the cache anyway yet
*/
v = lfirst(item); v = lfirst(item);
} }
else else
@ -884,8 +914,11 @@ AlterGroup(AlterGroupStmt *stmt, const char * tag)
if (!member(v, newlist)) if (!member(v, newlist))
newlist = lcons(v, newlist); newlist = lcons(v, newlist);
else else
/* we silently assume here that this error will only come up
in a ALTER GROUP statement */ /*
* we silently assume here that this error will only come
* up in a ALTER GROUP statement
*/
elog(NOTICE, "%s: user \"%s\" is already in group \"%s\"", tag, strVal(lfirst(item)), stmt->name); elog(NOTICE, "%s: user \"%s\" is already in group \"%s\"", tag, strVal(lfirst(item)), stmt->name);
} }
@ -898,9 +931,7 @@ AlterGroup(AlterGroupStmt *stmt, const char * tag)
/* fill the array */ /* fill the array */
i = 0; i = 0;
foreach(item, newlist) foreach(item, newlist)
{
((int *) ARR_DATA_PTR(newarray))[i++] = intVal(lfirst(item)); ((int *) ARR_DATA_PTR(newarray))[i++] = intVal(lfirst(item));
}
/* /*
* Form a tuple with the new array and write it back. * Form a tuple with the new array and write it back.
@ -913,7 +944,8 @@ AlterGroup(AlterGroupStmt *stmt, const char * tag)
heap_update(pg_group_rel, &group_tuple->t_self, tuple, NULL); heap_update(pg_group_rel, &group_tuple->t_self, tuple, NULL);
/* Update indexes */ /* Update indexes */
if (RelationGetForm(pg_group_rel)->relhasindex) { if (RelationGetForm(pg_group_rel)->relhasindex)
{
Relation idescs[Num_pg_group_indices]; Relation idescs[Num_pg_group_indices];
CatalogOpenIndices(Num_pg_group_indices, CatalogOpenIndices(Num_pg_group_indices,
@ -941,8 +973,10 @@ AlterGroup(AlterGroupStmt *stmt, const char * tag)
HeapTuple tuple; HeapTuple tuple;
Datum new_record[Natts_pg_group]; Datum new_record[Natts_pg_group];
char new_record_nulls[Natts_pg_group] = {' ', ' ', ' '}; char new_record_nulls[Natts_pg_group] = {' ', ' ', ' '};
ArrayType *oldarray, *newarray; ArrayType *oldarray,
List * newlist = NULL, *item; *newarray;
List *newlist = NULL,
*item;
int i; int i;
oldarray = (ArrayType *) datum; oldarray = (ArrayType *) datum;
@ -950,9 +984,11 @@ AlterGroup(AlterGroupStmt *stmt, const char * tag)
/* first add the old array to the hitherto empty list */ /* first add the old array to the hitherto empty list */
for (i = ARR_LBOUND(oldarray)[0]; i < ARR_LBOUND(oldarray)[0] + ARR_DIMS(oldarray)[0]; i++) for (i = ARR_LBOUND(oldarray)[0]; i < ARR_LBOUND(oldarray)[0] + ARR_DIMS(oldarray)[0]; i++)
{ {
int index, arrval; int index,
arrval;
Value *v; Value *v;
bool valueNull; bool valueNull;
index = i; index = i;
arrval = DatumGetInt32(array_ref(oldarray, 1, &index, true /* by value */ , arrval = DatumGetInt32(array_ref(oldarray, 1, &index, true /* by value */ ,
sizeof(int), 0, &valueNull)); sizeof(int), 0, &valueNull));
@ -963,12 +999,13 @@ AlterGroup(AlterGroupStmt *stmt, const char * tag)
} }
/* /*
* now convert the to be dropped usernames to sysids and remove * now convert the to be dropped usernames to sysids and
* them from the list * remove them from the list
*/ */
foreach(item, stmt->listUsers) foreach(item, stmt->listUsers)
{ {
Value *v; Value *v;
if (!is_dropuser) if (!is_dropuser)
{ {
/* Get the uid of the proposed user to drop. */ /* Get the uid of the proposed user to drop. */
@ -1002,9 +1039,7 @@ AlterGroup(AlterGroupStmt *stmt, const char * tag)
/* fill the array */ /* fill the array */
i = 0; i = 0;
foreach(item, newlist) foreach(item, newlist)
{
((int *) ARR_DATA_PTR(newarray))[i++] = intVal(lfirst(item)); ((int *) ARR_DATA_PTR(newarray))[i++] = intVal(lfirst(item));
}
/* /*
* Insert the new tuple with the updated user list * Insert the new tuple with the updated user list
@ -1017,7 +1052,8 @@ AlterGroup(AlterGroupStmt *stmt, const char * tag)
heap_update(pg_group_rel, &group_tuple->t_self, tuple, NULL); heap_update(pg_group_rel, &group_tuple->t_self, tuple, NULL);
/* Update indexes */ /* Update indexes */
if (RelationGetForm(pg_group_rel)->relhasindex) { if (RelationGetForm(pg_group_rel)->relhasindex)
{
Relation idescs[Num_pg_group_indices]; Relation idescs[Num_pg_group_indices];
CatalogOpenIndices(Num_pg_group_indices, CatalogOpenIndices(Num_pg_group_indices,
@ -1056,8 +1092,8 @@ DropGroup(DropGroupStmt *stmt)
elog(ERROR, "DROP GROUP: permission denied"); elog(ERROR, "DROP GROUP: permission denied");
/* /*
* There is not real reason for this, but it makes it consistent * There is not real reason for this, but it makes it consistent with
* with drop user, and it seems like a good idea anyway. * drop user, and it seems like a good idea anyway.
*/ */
if (IsTransactionBlock()) if (IsTransactionBlock())
elog(ERROR, "DROP GROUP: may not be called in a transaction block"); elog(ERROR, "DROP GROUP: may not be called in a transaction block");

View File

@ -8,7 +8,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/commands/vacuum.c,v 1.146 2000/04/06 18:12:07 momjian Exp $ * $Header: /cvsroot/pgsql/src/backend/commands/vacuum.c,v 1.147 2000/04/12 17:14:59 momjian Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
@ -104,13 +104,15 @@ static char *vc_show_rusage(struct rusage * ru0);
* This routines handle a special cross-transaction portal. * This routines handle a special cross-transaction portal.
* However it is automatically closed in case of abort. * However it is automatically closed in case of abort.
*/ */
void CommonSpecialPortalOpen(void) void
CommonSpecialPortalOpen(void)
{ {
char *pname; char *pname;
if (CommonSpecialPortalInUse) if (CommonSpecialPortalInUse)
elog(ERROR, "CommonSpecialPortal is in use"); elog(ERROR, "CommonSpecialPortal is in use");
/* /*
* Create a portal for safe memory across transactions. We need to * Create a portal for safe memory across transactions. We need to
* palloc the name space for it because our hash function expects the * palloc the name space for it because our hash function expects the
@ -130,7 +132,8 @@ void CommonSpecialPortalOpen(void)
CommonSpecialPortalInUse = true; CommonSpecialPortalInUse = true;
} }
void CommonSpecialPortalClose(void) void
CommonSpecialPortalClose(void)
{ {
/* Clear flag first, to avoid recursion if PortalDrop elog's */ /* Clear flag first, to avoid recursion if PortalDrop elog's */
CommonSpecialPortalInUse = false; CommonSpecialPortalInUse = false;
@ -141,12 +144,14 @@ void CommonSpecialPortalClose(void)
PortalDrop(&vc_portal); PortalDrop(&vc_portal);
} }
PortalVariableMemory CommonSpecialPortalGetMemory(void) PortalVariableMemory
CommonSpecialPortalGetMemory(void)
{ {
return PortalGetVariableMemory(vc_portal); return PortalGetVariableMemory(vc_portal);
} }
bool CommonSpecialPortalIsOpen(void) bool
CommonSpecialPortalIsOpen(void)
{ {
return CommonSpecialPortalInUse; return CommonSpecialPortalInUse;
} }
@ -208,9 +213,9 @@ vacuum(char *vacrel, bool verbose, bool analyze, List *va_spec)
* Start up the vacuum cleaner. * Start up the vacuum cleaner.
* *
* NOTE: since this commits the current transaction, the memory holding * NOTE: since this commits the current transaction, the memory holding
* any passed-in parameters gets freed here. We must have already copied * any passed-in parameters gets freed here. We must have already
* pass-by-reference parameters to safe storage. Don't make me fix this * copied pass-by-reference parameters to safe storage. Don't make me
* again! * fix this again!
*/ */
vc_init(); vc_init();
@ -316,6 +321,7 @@ vc_getrels(NameData *VacRelP)
if (NameStr(*VacRelP)) if (NameStr(*VacRelP))
{ {
/* /*
* we could use the cache here, but it is clearer to use scankeys * we could use the cache here, but it is clearer to use scankeys
* for both vacuum cases, bjm 2000/01/19 * for both vacuum cases, bjm 2000/01/19
@ -1456,8 +1462,8 @@ vc_repair_frag(VRelStats *vacrelstats, Relation onerel,
* we stop shrinking here. I could try to find * we stop shrinking here. I could try to find
* real parent row but want not to do it because * real parent row but want not to do it because
* of real solution will be implemented anyway, * of real solution will be implemented anyway,
* latter, and we are too close to 6.5 release. * latter, and we are too close to 6.5 release. -
* - vadim 06/11/99 * vadim 06/11/99
*/ */
if (Ptp.t_data->t_xmax != tp.t_data->t_xmin) if (Ptp.t_data->t_xmax != tp.t_data->t_xmin)
{ {
@ -1539,6 +1545,7 @@ vc_repair_frag(VRelStats *vacrelstats, Relation onerel,
* to get t_infomask of inserted heap tuple !!! * to get t_infomask of inserted heap tuple !!!
*/ */
ToPage = BufferGetPage(cur_buffer); ToPage = BufferGetPage(cur_buffer);
/* /*
* If this page was not used before - clean it. * If this page was not used before - clean it.
* *
@ -1546,13 +1553,15 @@ vc_repair_frag(VRelStats *vacrelstats, Relation onerel,
* vc_vacpage, because we have already incremented the * vc_vacpage, because we have already incremented the
* vpd's vpd_offsets_used field to account for the * vpd's vpd_offsets_used field to account for the
* tuple(s) we expect to move onto the page. Therefore * tuple(s) we expect to move onto the page. Therefore
* vc_vacpage's check for vpd_offsets_used == 0 is wrong. * vc_vacpage's check for vpd_offsets_used == 0 is
* But since that's a good debugging check for all other * wrong. But since that's a good debugging check for
* callers, we work around it here rather than remove it. * all other callers, we work around it here rather
* than remove it.
*/ */
if (!PageIsEmpty(ToPage) && vtmove[ti].cleanVpd) if (!PageIsEmpty(ToPage) && vtmove[ti].cleanVpd)
{ {
int sv_offsets_used = destvpd->vpd_offsets_used; int sv_offsets_used = destvpd->vpd_offsets_used;
destvpd->vpd_offsets_used = 0; destvpd->vpd_offsets_used = 0;
vc_vacpage(ToPage, destvpd); vc_vacpage(ToPage, destvpd);
destvpd->vpd_offsets_used = sv_offsets_used; destvpd->vpd_offsets_used = sv_offsets_used;

View File

@ -9,7 +9,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/commands/variable.c,v 1.33 2000/04/07 13:39:24 thomas Exp $ * $Header: /cvsroot/pgsql/src/backend/commands/variable.c,v 1.34 2000/04/12 17:15:00 momjian Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
@ -777,8 +777,9 @@ set_default_datestyle(void)
{ {
char *DBDate; char *DBDate;
/* Initialize from compile-time defaults in init/globals.c. /*
* NB: this is a necessary step; consider PGDATESTYLE="DEFAULT". * Initialize from compile-time defaults in init/globals.c. NB: this
* is a necessary step; consider PGDATESTYLE="DEFAULT".
*/ */
DefaultDateStyle = DateStyle; DefaultDateStyle = DateStyle;
DefaultEuroDates = EuroDates; DefaultEuroDates = EuroDates;
@ -788,9 +789,11 @@ set_default_datestyle(void)
if (DBDate == NULL) if (DBDate == NULL)
return; return;
/* Make a modifiable copy --- overwriting the env var doesn't seem /*
* Make a modifiable copy --- overwriting the env var doesn't seem
* like a good idea, even though we currently won't look at it again. * like a good idea, even though we currently won't look at it again.
* Note that we cannot use palloc at this early stage of initialization. * Note that we cannot use palloc at this early stage of
* initialization.
*/ */
DBDate = strdup(DBDate); DBDate = strdup(DBDate);
@ -1041,9 +1044,8 @@ reset_XactIsoLevel()
static bool static bool
parse_pg_options(char *value) parse_pg_options(char *value)
{ {
if (!superuser()) { if (!superuser())
elog(ERROR, "Only users with superuser privilege can set pg_options"); elog(ERROR, "Only users with superuser privilege can set pg_options");
}
if (value == NULL) if (value == NULL)
read_pg_options(0); read_pg_options(0);
else else
@ -1061,9 +1063,8 @@ show_pg_options(void)
static bool static bool
reset_pg_options(void) reset_pg_options(void)
{ {
if (!superuser()) { if (!superuser())
elog(ERROR, "Only users with superuser privilege can set pg_options"); elog(ERROR, "Only users with superuser privilege can set pg_options");
}
read_pg_options(0); read_pg_options(0);
return (TRUE); return (TRUE);
} }

View File

@ -6,7 +6,7 @@
* Portions Copyright (c) 1996-2000, PostgreSQL, Inc * Portions Copyright (c) 1996-2000, PostgreSQL, Inc
* Portions Copyright (c) 1994, Regents of the University of California * Portions Copyright (c) 1994, Regents of the University of California
* *
* $Id: execAmi.c,v 1.45 2000/01/26 05:56:21 momjian Exp $ * $Id: execAmi.c,v 1.46 2000/04/12 17:15:07 momjian Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
@ -236,8 +236,9 @@ ExecCloseR(Plan *node)
/* /*
* endscan released AccessShareLock acquired by beginscan. If we are * endscan released AccessShareLock acquired by beginscan. If we are
* holding any stronger locks on the rel, they should be held till end of * holding any stronger locks on the rel, they should be held till end
* xact. Therefore, we need only close the rel and not release locks. * of xact. Therefore, we need only close the rel and not release
* locks.
*/ */
if (relation != NULL) if (relation != NULL)
heap_close(relation, NoLock); heap_close(relation, NoLock);

View File

@ -27,7 +27,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/executor/execMain.c,v 1.112 2000/04/07 07:24:47 vadim Exp $ * $Header: /cvsroot/pgsql/src/backend/executor/execMain.c,v 1.113 2000/04/12 17:15:08 momjian Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
@ -82,6 +82,7 @@ static void ExecCheckRTPerms(List *rangeTable, CmdType operation,
int resultRelation, bool resultIsScanned); int resultRelation, bool resultIsScanned);
static void ExecCheckRTEPerms(RangeTblEntry *rte, CmdType operation, static void ExecCheckRTEPerms(RangeTblEntry *rte, CmdType operation,
bool isResultRelation, bool resultIsScanned); bool isResultRelation, bool resultIsScanned);
/* end of local decls */ /* end of local decls */
@ -491,10 +492,12 @@ ExecCheckPlanPerms(Plan *plan, CmdType operation,
if (app->inheritrelid > 0) if (app->inheritrelid > 0)
{ {
/* /*
* Append implements expansion of inheritance; all members * Append implements expansion of inheritance; all
* of inheritrtable list will be plugged into same RTE slot. * members of inheritrtable list will be plugged into
* Therefore, they are either all result relations or none. * same RTE slot. Therefore, they are either all
* result relations or none.
*/ */
List *rtable; List *rtable;
@ -576,10 +579,11 @@ ExecCheckRTEPerms(RangeTblEntry *rte, CmdType operation,
if (rte->skipAcl) if (rte->skipAcl)
{ {
/* /*
* This happens if the access to this table is due to a view * This happens if the access to this table is due to a view query
* query rewriting - the rewrite handler already checked the * rewriting - the rewrite handler already checked the permissions
* permissions against the view owner, so we just skip this entry. * against the view owner, so we just skip this entry.
*/ */
return; return;
} }
@ -625,9 +629,7 @@ ExecCheckRTEPerms(RangeTblEntry *rte, CmdType operation,
} }
} }
else else
{
aclcheck_result = CHECK(ACL_RD); aclcheck_result = CHECK(ACL_RD);
}
if (aclcheck_result != ACLCHECK_OK) if (aclcheck_result != ACLCHECK_OK)
elog(ERROR, "%s: %s", elog(ERROR, "%s: %s",
@ -734,8 +736,9 @@ InitPlan(CmdType operation, Query *parseTree, Plan *plan, EState *estate)
/* /*
* If there are indices on the result relation, open them and save * If there are indices on the result relation, open them and save
* descriptors in the result relation info, so that we can add new * descriptors in the result relation info, so that we can add new
* index entries for the tuples we add/update. We need not do this * index entries for the tuples we add/update. We need not do
* for a DELETE, however, since deletion doesn't affect indexes. * this for a DELETE, however, since deletion doesn't affect
* indexes.
*/ */
if (resultRelationDesc->rd_rel->relhasindex && if (resultRelationDesc->rd_rel->relhasindex &&
operation != CMD_DELETE) operation != CMD_DELETE)
@ -805,10 +808,11 @@ InitPlan(CmdType operation, Query *parseTree, Plan *plan, EState *estate)
targetList = plan->targetlist; targetList = plan->targetlist;
/* /*
* Now that we have the target list, initialize the junk filter if needed. * Now that we have the target list, initialize the junk filter if
* SELECT and INSERT queries need a filter if there are any junk attrs * needed. SELECT and INSERT queries need a filter if there are any
* in the tlist. UPDATE and DELETE always need one, since there's always * junk attrs in the tlist. UPDATE and DELETE always need one, since
* a junk 'ctid' attribute present --- no need to look first. * there's always a junk 'ctid' attribute present --- no need to look
* first.
*/ */
{ {
bool junk_filter_needed = false; bool junk_filter_needed = false;
@ -948,8 +952,8 @@ EndPlan(Plan *plan, EState *estate)
} }
/* /*
* close the result relations if necessary, * close the result relations if necessary, but hold locks on them
* but hold locks on them until xact commit * until xact commit
*/ */
if (resultRelationInfo != NULL) if (resultRelationInfo != NULL)
{ {
@ -1708,8 +1712,8 @@ ExecRelCheck(Relation rel, HeapTuple tuple, EState *estate)
/* /*
* NOTE: SQL92 specifies that a NULL result from a constraint * NOTE: SQL92 specifies that a NULL result from a constraint
* expression is not to be treated as a failure. Therefore, * expression is not to be treated as a failure. Therefore, tell
* tell ExecQual to return TRUE for NULL. * ExecQual to return TRUE for NULL.
*/ */
if (!ExecQual(qual, econtext, true)) if (!ExecQual(qual, econtext, true))
return check[i].ccname; return check[i].ccname;

View File

@ -8,7 +8,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/executor/execQual.c,v 1.68 2000/02/20 21:32:04 tgl Exp $ * $Header: /cvsroot/pgsql/src/backend/executor/execQual.c,v 1.69 2000/04/12 17:15:08 momjian Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
@ -108,12 +108,14 @@ ExecEvalArrayRef(ArrayRef *arrayRef,
} }
else else
{ {
/* Null refexpr indicates we are doing an INSERT into an array column.
* For now, we just take the refassgnexpr (which the parser will have /*
* ensured is an array value) and return it as-is, ignoring any * Null refexpr indicates we are doing an INSERT into an array
* subscripts that may have been supplied in the INSERT column list. * column. For now, we just take the refassgnexpr (which the
* This is a kluge, but it's not real clear what the semantics ought * parser will have ensured is an array value) and return it
* to be... * as-is, ignoring any subscripts that may have been supplied in
* the INSERT column list. This is a kluge, but it's not real
* clear what the semantics ought to be...
*/ */
array_scanner = NULL; array_scanner = NULL;
} }
@ -153,9 +155,7 @@ ExecEvalArrayRef(ArrayRef *arrayRef,
lIndex = lower.indx; lIndex = lower.indx;
} }
else else
{
lIndex = NULL; lIndex = NULL;
}
if (arrayRef->refassgnexpr != NULL) if (arrayRef->refassgnexpr != NULL)
{ {
@ -163,6 +163,7 @@ ExecEvalArrayRef(ArrayRef *arrayRef,
econtext, econtext,
isNull, isNull,
&dummy); &dummy);
if (*isNull) if (*isNull)
return (Datum) NULL; return (Datum) NULL;
@ -789,7 +790,11 @@ ExecMakeFunctionResult(Node *node,
if (argDone) if (argDone)
{ {
/* End of arguments, so reset the setArg flag and say "Done" */
/*
* End of arguments, so reset the setArg flag and say
* "Done"
*/
fcache->setArg = (char *) NULL; fcache->setArg = (char *) NULL;
fcache->hasSetArg = false; fcache->hasSetArg = false;
*isDone = true; *isDone = true;
@ -797,7 +802,8 @@ ExecMakeFunctionResult(Node *node,
break; break;
} }
/* If we reach here, loop around to run the function on the /*
* If we reach here, loop around to run the function on the
* new argument. * new argument.
*/ */
} }
@ -1003,20 +1009,22 @@ ExecEvalOr(Expr *orExpr, ExprContext *econtext, bool *isNull)
AnyNull = false; AnyNull = false;
/* /*
* If any of the clauses is TRUE, the OR result is TRUE regardless * If any of the clauses is TRUE, the OR result is TRUE regardless of
* of the states of the rest of the clauses, so we can stop evaluating * the states of the rest of the clauses, so we can stop evaluating
* and return TRUE immediately. If none are TRUE and one or more is * and return TRUE immediately. If none are TRUE and one or more is
* NULL, we return NULL; otherwise we return FALSE. This makes sense * NULL, we return NULL; otherwise we return FALSE. This makes sense
* when you interpret NULL as "don't know": if we have a TRUE then the * when you interpret NULL as "don't know": if we have a TRUE then the
* OR is TRUE even if we aren't sure about some of the other inputs. * OR is TRUE even if we aren't sure about some of the other inputs.
* If all the known inputs are FALSE, but we have one or more "don't * If all the known inputs are FALSE, but we have one or more "don't
* knows", then we have to report that we "don't know" what the OR's * knows", then we have to report that we "don't know" what the OR's
* result should be --- perhaps one of the "don't knows" would have been * result should be --- perhaps one of the "don't knows" would have
* TRUE if we'd known its value. Only when all the inputs are known * been TRUE if we'd known its value. Only when all the inputs are
* to be FALSE can we state confidently that the OR's result is FALSE. * known to be FALSE can we state confidently that the OR's result is
* FALSE.
*/ */
foreach(clause, clauses) foreach(clause, clauses)
{ {
/* /*
* We don't iterate over sets in the quals, so pass in an isDone * We don't iterate over sets in the quals, so pass in an isDone
* flag, but ignore it. * flag, but ignore it.
@ -1025,6 +1033,7 @@ ExecEvalOr(Expr *orExpr, ExprContext *econtext, bool *isNull)
econtext, econtext,
isNull, isNull,
&isDone); &isDone);
/* /*
* if we have a non-null true result, then return it. * if we have a non-null true result, then return it.
*/ */
@ -1065,6 +1074,7 @@ ExecEvalAnd(Expr *andExpr, ExprContext *econtext, bool *isNull)
*/ */
foreach(clause, clauses) foreach(clause, clauses)
{ {
/* /*
* We don't iterate over sets in the quals, so pass in an isDone * We don't iterate over sets in the quals, so pass in an isDone
* flag, but ignore it. * flag, but ignore it.
@ -1073,6 +1083,7 @@ ExecEvalAnd(Expr *andExpr, ExprContext *econtext, bool *isNull)
econtext, econtext,
isNull, isNull,
&isDone); &isDone);
/* /*
* if we have a non-null false result, then return it. * if we have a non-null false result, then return it.
*/ */
@ -1353,14 +1364,15 @@ ExecQual(List *qual, ExprContext *econtext, bool resultForNull)
/* /*
* If there is a null clause, consider the qualification to fail. * If there is a null clause, consider the qualification to fail.
* XXX is this still correct for constraints? It probably shouldn't * XXX is this still correct for constraints? It probably
* happen at all ... * shouldn't happen at all ...
*/ */
if (clause == NULL) if (clause == NULL)
return false; return false;
/* /*
* pass isDone, but ignore it. We don't iterate over multiple returns * pass isDone, but ignore it. We don't iterate over multiple
* in the qualifications. * returns in the qualifications.
*/ */
expr_value = ExecEvalExpr(clause, econtext, &isNull, &isDone); expr_value = ExecEvalExpr(clause, econtext, &isNull, &isDone);
@ -1429,7 +1441,8 @@ ExecTargetList(List *targetlist,
HeapTuple newTuple; HeapTuple newTuple;
bool isNull; bool isNull;
bool haveDoneIters; bool haveDoneIters;
static struct tupleDesc NullTupleDesc; /* we assume this inits to zeroes */ static struct tupleDesc NullTupleDesc; /* we assume this inits to
* zeroes */
/* /*
* debugging stuff * debugging stuff
@ -1512,7 +1525,8 @@ ExecTargetList(List *targetlist,
if (itemIsDone[resind]) if (itemIsDone[resind])
haveDoneIters = true; haveDoneIters = true;
else else
*isDone = false; /* we have undone Iters in the list */ *isDone = false; /* we have undone Iters in the
* list */
} }
} }
else else
@ -1571,7 +1585,9 @@ ExecTargetList(List *targetlist,
{ {
if (*isDone) if (*isDone)
{ {
/* all Iters are done, so return a null indicating tlist set
/*
* all Iters are done, so return a null indicating tlist set
* expansion is complete. * expansion is complete.
*/ */
newTuple = NULL; newTuple = NULL;
@ -1579,21 +1595,24 @@ ExecTargetList(List *targetlist,
} }
else else
{ {
/* We have some done and some undone Iters. Restart the done ones
* so that we can deliver a tuple (if possible). /*
* We have some done and some undone Iters. Restart the done
* ones so that we can deliver a tuple (if possible).
* *
* XXX this code is a crock, because it only works for Iters at * XXX this code is a crock, because it only works for Iters at
* the top level of tlist expressions, and doesn't even work right * the top level of tlist expressions, and doesn't even work
* for them: you should get all possible combinations of Iter * right for them: you should get all possible combinations of
* results, but you won't unless the numbers of values returned by * Iter results, but you won't unless the numbers of values
* each are relatively prime. Should have a mechanism more like * returned by each are relatively prime. Should have a
* aggregate functions, where we make a list of all Iters * mechanism more like aggregate functions, where we make a
* contained in the tlist and cycle through their values in a * list of all Iters contained in the tlist and cycle through
* methodical fashion. To do someday; can't get excited about * their values in a methodical fashion. To do someday; can't
* fixing a Berkeley feature that's not in SQL92. (The only * get excited about fixing a Berkeley feature that's not in
* reason we're doing this much is that we have to be sure all * SQL92. (The only reason we're doing this much is that we
* the Iters are run to completion, or their subplan executors * have to be sure all the Iters are run to completion, or
* will have unreleased resources, e.g. pinned buffers...) * their subplan executors will have unreleased resources,
* e.g. pinned buffers...)
*/ */
foreach(tl, targetlist) foreach(tl, targetlist)
{ {
@ -1613,8 +1632,10 @@ ExecTargetList(List *targetlist,
&itemIsDone[resind]); &itemIsDone[resind]);
if (itemIsDone[resind]) if (itemIsDone[resind])
{ {
/* Oh dear, this Iter is returning an empty set.
* Guess we can't make a tuple after all. /*
* Oh dear, this Iter is returning an empty
* set. Guess we can't make a tuple after all.
*/ */
*isDone = true; *isDone = true;
newTuple = NULL; newTuple = NULL;
@ -1639,6 +1660,7 @@ ExecTargetList(List *targetlist,
newTuple = (HeapTuple) heap_formtuple(targettype, values, null_head); newTuple = (HeapTuple) heap_formtuple(targettype, values, null_head);
exit: exit:
/* /*
* free the status arrays if we palloc'd them * free the status arrays if we palloc'd them
*/ */

View File

@ -15,7 +15,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/executor/execTuples.c,v 1.36 2000/01/27 18:11:27 tgl Exp $ * $Header: /cvsroot/pgsql/src/backend/executor/execTuples.c,v 1.37 2000/04/12 17:15:08 momjian Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
@ -385,7 +385,8 @@ ExecStoreTuple(HeapTuple tuple,
slot->ttc_buffer = buffer; slot->ttc_buffer = buffer;
slot->ttc_shouldFree = shouldFree; slot->ttc_shouldFree = shouldFree;
/* If tuple is on a disk page, keep the page pinned as long as we hold /*
* If tuple is on a disk page, keep the page pinned as long as we hold
* a pointer into it. * a pointer into it.
*/ */
if (BufferIsValid(buffer)) if (BufferIsValid(buffer))
@ -776,6 +777,7 @@ NodeGetResultTupleSlot(Plan *node)
case T_TidScan: case T_TidScan:
{ {
CommonScanState *scanstate = ((IndexScan *) node)->scan.scanstate; CommonScanState *scanstate = ((IndexScan *) node)->scan.scanstate;
slot = scanstate->cstate.cs_ResultTupleSlot; slot = scanstate->cstate.cs_ResultTupleSlot;
} }
break; break;

View File

@ -8,7 +8,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/executor/execUtils.c,v 1.54 2000/02/18 09:29:57 inoue Exp $ * $Header: /cvsroot/pgsql/src/backend/executor/execUtils.c,v 1.55 2000/04/12 17:15:08 momjian Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
@ -923,8 +923,8 @@ ExecOpenIndices(Oid resultRelationOid,
/* /*
* Hack for not btree and hash indices: they use relation * Hack for not btree and hash indices: they use relation
* level exclusive locking on update (i.e. - they are * level exclusive locking on update (i.e. - they are not
* not ready for MVCC) and so we have to exclusively lock * ready for MVCC) and so we have to exclusively lock
* indices here to prevent deadlocks if we will scan them * indices here to prevent deadlocks if we will scan them
* - index_beginscan places AccessShareLock, indices * - index_beginscan places AccessShareLock, indices
* update methods don't use locks at all. We release this * update methods don't use locks at all. We release this

View File

@ -9,7 +9,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/executor/functions.c,v 1.32 2000/04/04 21:44:39 tgl Exp $ * $Header: /cvsroot/pgsql/src/backend/executor/functions.c,v 1.33 2000/04/12 17:15:09 momjian Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
@ -150,6 +150,7 @@ init_execution_state(FunctionCachePtr fcache,
static TupleDesc static TupleDesc
postquel_start(execution_state *es) postquel_start(execution_state *es)
{ {
/* /*
* Do nothing for utility commands. (create, destroy...) DZ - * Do nothing for utility commands. (create, destroy...) DZ -
* 30-8-1996 * 30-8-1996
@ -166,9 +167,9 @@ postquel_getnext(execution_state *es)
if (es->qd->operation == CMD_UTILITY) if (es->qd->operation == CMD_UTILITY)
{ {
/* /*
* Process a utility command. (create, destroy...) DZ - * Process a utility command. (create, destroy...) DZ - 30-8-1996
* 30-8-1996
*/ */
ProcessUtility(es->qd->parsetree->utilityStmt, es->qd->dest); ProcessUtility(es->qd->parsetree->utilityStmt, es->qd->dest);
if (!LAST_POSTQUEL_COMMAND(es)) if (!LAST_POSTQUEL_COMMAND(es))
@ -184,6 +185,7 @@ postquel_getnext(execution_state *es)
static void static void
postquel_end(execution_state *es) postquel_end(execution_state *es)
{ {
/* /*
* Do nothing for utility commands. (create, destroy...) DZ - * Do nothing for utility commands. (create, destroy...) DZ -
* 30-8-1996 * 30-8-1996

View File

@ -32,7 +32,7 @@
* Portions Copyright (c) 1994, Regents of the University of California * Portions Copyright (c) 1994, Regents of the University of California
* *
* IDENTIFICATION * IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/executor/nodeAgg.c,v 1.62 2000/01/26 05:56:22 momjian Exp $ * $Header: /cvsroot/pgsql/src/backend/executor/nodeAgg.c,v 1.63 2000/04/12 17:15:09 momjian Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
@ -56,6 +56,7 @@
*/ */
typedef struct AggStatePerAggData typedef struct AggStatePerAggData
{ {
/* /*
* These values are set up during ExecInitAgg() and do not change * These values are set up during ExecInitAgg() and do not change
* thereafter: * thereafter:
@ -68,6 +69,7 @@ typedef struct AggStatePerAggData
Oid xfn1_oid; Oid xfn1_oid;
Oid xfn2_oid; Oid xfn2_oid;
Oid finalfn_oid; Oid finalfn_oid;
/* /*
* fmgr lookup data for transfer functions --- only valid when * fmgr lookup data for transfer functions --- only valid when
* corresponding oid is not InvalidOid * corresponding oid is not InvalidOid
@ -75,18 +77,21 @@ typedef struct AggStatePerAggData
FmgrInfo xfn1; FmgrInfo xfn1;
FmgrInfo xfn2; FmgrInfo xfn2;
FmgrInfo finalfn; FmgrInfo finalfn;
/* /*
* Type of input data and Oid of sort operator to use for it; * Type of input data and Oid of sort operator to use for it; only
* only set/used when aggregate has DISTINCT flag. (These are not * set/used when aggregate has DISTINCT flag. (These are not used
* used directly by nodeAgg, but must be passed to the Tuplesort object.) * directly by nodeAgg, but must be passed to the Tuplesort object.)
*/ */
Oid inputType; Oid inputType;
Oid sortOperator; Oid sortOperator;
/* /*
* fmgr lookup data for input type's equality operator --- only set/used * fmgr lookup data for input type's equality operator --- only
* when aggregate has DISTINCT flag. * set/used when aggregate has DISTINCT flag.
*/ */
FmgrInfo equalfn; FmgrInfo equalfn;
/* /*
* initial values from pg_aggregate entry * initial values from pg_aggregate entry
*/ */
@ -94,6 +99,7 @@ typedef struct AggStatePerAggData
Datum initValue2; /* for transtype2 */ Datum initValue2; /* for transtype2 */
bool initValue1IsNull, bool initValue1IsNull,
initValue2IsNull; initValue2IsNull;
/* /*
* We need the len and byval info for the agg's input and transition * We need the len and byval info for the agg's input and transition
* data types in order to know how to copy/delete values. * data types in order to know how to copy/delete values.
@ -106,14 +112,14 @@ typedef struct AggStatePerAggData
transtype2ByVal; transtype2ByVal;
/* /*
* These values are working state that is initialized at the start * These values are working state that is initialized at the start of
* of an input tuple group and updated for each input tuple. * an input tuple group and updated for each input tuple.
* *
* For a simple (non DISTINCT) aggregate, we just feed the input values * For a simple (non DISTINCT) aggregate, we just feed the input values
* straight to the transition functions. If it's DISTINCT, we pass the * straight to the transition functions. If it's DISTINCT, we pass
* input values into a Tuplesort object; then at completion of the input * the input values into a Tuplesort object; then at completion of the
* tuple group, we scan the sorted values, eliminate duplicates, and run * input tuple group, we scan the sorted values, eliminate duplicates,
* the transition functions on the rest. * and run the transition functions on the rest.
*/ */
Tuplesortstate *sortstate; /* sort object, if a DISTINCT agg */ Tuplesortstate *sortstate; /* sort object, if a DISTINCT agg */
@ -123,11 +129,13 @@ typedef struct AggStatePerAggData
bool value1IsNull, bool value1IsNull,
value2IsNull; value2IsNull;
bool noInitValue; /* true if value1 not set yet */ bool noInitValue; /* true if value1 not set yet */
/* /*
* Note: right now, noInitValue always has the same value as value1IsNull. * Note: right now, noInitValue always has the same value as
* But we should keep them separate because once the fmgr interface is * value1IsNull. But we should keep them separate because once the
* fixed, we'll need to distinguish a null returned by transfn1 from * fmgr interface is fixed, we'll need to distinguish a null returned
* a null we haven't yet replaced with an input value. * by transfn1 from a null we haven't yet replaced with an input
* value.
*/ */
} AggStatePerAggData; } AggStatePerAggData;
@ -153,8 +161,10 @@ initialize_aggregate (AggStatePerAgg peraggstate)
*/ */
if (aggref->aggdistinct) if (aggref->aggdistinct)
{ {
/* In case of rescan, maybe there could be an uncompleted
* sort operation? Clean it up if so. /*
* In case of rescan, maybe there could be an uncompleted sort
* operation? Clean it up if so.
*/ */
if (peraggstate->sortstate) if (peraggstate->sortstate)
tuplesort_end(peraggstate->sortstate); tuplesort_end(peraggstate->sortstate);
@ -214,6 +224,7 @@ advance_transition_functions (AggStatePerAgg peraggstate,
{ {
if (peraggstate->noInitValue) if (peraggstate->noInitValue)
{ {
/* /*
* value1 has not been initialized. This is the first non-NULL * value1 has not been initialized. This is the first non-NULL
* input value. We use it as the initial value for value1. * input value. We use it as the initial value for value1.
@ -270,9 +281,10 @@ finalize_aggregate (AggStatePerAgg peraggstate,
/* /*
* If it's a DISTINCT aggregate, all we've done so far is to stuff the * If it's a DISTINCT aggregate, all we've done so far is to stuff the
* input values into the sort object. Complete the sort, then run * input values into the sort object. Complete the sort, then run the
* the transition functions on the non-duplicate values. Note that * transition functions on the non-duplicate values. Note that
* DISTINCT always suppresses nulls, per SQL spec, regardless of usenulls. * DISTINCT always suppresses nulls, per SQL spec, regardless of
* usenulls.
*/ */
if (aggref->aggdistinct) if (aggref->aggdistinct)
{ {
@ -313,14 +325,14 @@ finalize_aggregate (AggStatePerAgg peraggstate,
} }
/* /*
* Now apply the agg's finalfn, or substitute the appropriate transition * Now apply the agg's finalfn, or substitute the appropriate
* value if there is no finalfn. * transition value if there is no finalfn.
* *
* XXX For now, only apply finalfn if we got at least one * XXX For now, only apply finalfn if we got at least one non-null input
* non-null input value. This prevents zero divide in AVG(). * value. This prevents zero divide in AVG(). If we had cleaner
* If we had cleaner handling of null inputs/results in functions, * handling of null inputs/results in functions, we could probably
* we could probably take out this hack and define the result * take out this hack and define the result for no inputs as whatever
* for no inputs as whatever finalfn returns for null input. * finalfn returns for null input.
*/ */
if (OidIsValid(peraggstate->finalfn_oid) && if (OidIsValid(peraggstate->finalfn_oid) &&
!peraggstate->noInitValue) !peraggstate->noInitValue)
@ -361,8 +373,8 @@ finalize_aggregate (AggStatePerAgg peraggstate,
elog(ERROR, "ExecAgg: no valid transition functions??"); elog(ERROR, "ExecAgg: no valid transition functions??");
/* /*
* Release any per-group working storage, unless we're passing * Release any per-group working storage, unless we're passing it back
* it back as the result of the aggregate. * as the result of the aggregate.
*/ */
if (OidIsValid(peraggstate->xfn1_oid) && if (OidIsValid(peraggstate->xfn1_oid) &&
!peraggstate->value1IsNull && !peraggstate->value1IsNull &&
@ -479,17 +491,17 @@ ExecAgg(Agg *node)
/* /*
* Keep a copy of the first input tuple for the projection. * Keep a copy of the first input tuple for the projection.
* (We only need one since only the GROUP BY columns in it * (We only need one since only the GROUP BY columns in it can
* can be referenced, and these will be the same for all * be referenced, and these will be the same for all tuples
* tuples aggregated over.) * aggregated over.)
*/ */
if (!inputTuple) if (!inputTuple)
inputTuple = heap_copytuple(outerslot->val); inputTuple = heap_copytuple(outerslot->val);
} }
/* /*
* Done scanning input tuple group. * Done scanning input tuple group. Finalize each aggregate
* Finalize each aggregate calculation. * calculation.
*/ */
for (aggno = 0; aggno < aggstate->numaggs; aggno++) for (aggno = 0; aggno < aggstate->numaggs; aggno++)
{ {
@ -502,14 +514,14 @@ ExecAgg(Agg *node)
/* /*
* If the outerPlan is a Group node, we will reach here after each * If the outerPlan is a Group node, we will reach here after each
* group. We are not done unless the Group node is done (a little * group. We are not done unless the Group node is done (a little
* ugliness here while we reach into the Group's state to find out). * ugliness here while we reach into the Group's state to find
* Furthermore, when grouping we return nothing at all unless we * out). Furthermore, when grouping we return nothing at all
* had some input tuple(s). By the nature of Group, there are * unless we had some input tuple(s). By the nature of Group,
* no empty groups, so if we get here with no input the whole scan * there are no empty groups, so if we get here with no input the
* is empty. * whole scan is empty.
* *
* If the outerPlan isn't a Group, we are done when we get here, * If the outerPlan isn't a Group, we are done when we get here, and
* and we will emit a (single) tuple even if there were no input * we will emit a (single) tuple even if there were no input
* tuples. * tuples.
*/ */
if (IsA(outerPlan, Group)) if (IsA(outerPlan, Group))
@ -523,17 +535,18 @@ ExecAgg(Agg *node)
else else
{ {
aggstate->agg_done = true; aggstate->agg_done = true;
/* /*
* If inputtuple==NULL (ie, the outerPlan didn't return anything), * If inputtuple==NULL (ie, the outerPlan didn't return
* create a dummy all-nulls input tuple for use by execProject. * anything), create a dummy all-nulls input tuple for use by
* 99.44% of the time this is a waste of cycles, because * execProject. 99.44% of the time this is a waste of cycles,
* ordinarily the projected output tuple's targetlist cannot * because ordinarily the projected output tuple's targetlist
* contain any direct (non-aggregated) references to input * cannot contain any direct (non-aggregated) references to
* columns, so the dummy tuple will not be referenced. However * input columns, so the dummy tuple will not be referenced.
* there are special cases where this isn't so --- in particular * However there are special cases where this isn't so --- in
* an UPDATE involving an aggregate will have a targetlist * particular an UPDATE involving an aggregate will have a
* reference to ctid. We need to return a null for ctid in that * targetlist reference to ctid. We need to return a null for
* situation, not coredump. * ctid in that situation, not coredump.
* *
* The values returned for the aggregates will be the initial * The values returned for the aggregates will be the initial
* values of the transition functions. * values of the transition functions.
@ -576,8 +589,8 @@ ExecAgg(Agg *node)
resultSlot = ExecProject(projInfo, &isDone); resultSlot = ExecProject(projInfo, &isDone);
/* /*
* If the completed tuple does not match the qualifications, * If the completed tuple does not match the qualifications, it is
* it is ignored and we loop back to try to process another group. * ignored and we loop back to try to process another group.
* Otherwise, return the tuple. * Otherwise, return the tuple.
*/ */
} }
@ -620,21 +633,23 @@ ExecInitAgg(Agg *node, EState *estate, Plan *parent)
* find aggregates in targetlist and quals * find aggregates in targetlist and quals
* *
* Note: pull_agg_clauses also checks that no aggs contain other agg * Note: pull_agg_clauses also checks that no aggs contain other agg
* calls in their arguments. This would make no sense under SQL semantics * calls in their arguments. This would make no sense under SQL
* anyway (and it's forbidden by the spec). Because that is true, we * semantics anyway (and it's forbidden by the spec). Because that is
* don't need to worry about evaluating the aggs in any particular order. * true, we don't need to worry about evaluating the aggs in any
* particular order.
*/ */
aggstate->aggs = nconc(pull_agg_clause((Node *) node->plan.targetlist), aggstate->aggs = nconc(pull_agg_clause((Node *) node->plan.targetlist),
pull_agg_clause((Node *) node->plan.qual)); pull_agg_clause((Node *) node->plan.qual));
aggstate->numaggs = numaggs = length(aggstate->aggs); aggstate->numaggs = numaggs = length(aggstate->aggs);
if (numaggs <= 0) if (numaggs <= 0)
{ {
/* /*
* This used to be treated as an error, but we can't do that anymore * This used to be treated as an error, but we can't do that
* because constant-expression simplification could optimize away * anymore because constant-expression simplification could
* all of the Aggrefs in the targetlist and qual. So, just make a * optimize away all of the Aggrefs in the targetlist and qual.
* debug note, and force numaggs positive so that palloc()s below * So, just make a debug note, and force numaggs positive so that
* don't choke. * palloc()s below don't choke.
*/ */
elog(DEBUG, "ExecInitAgg: could not find any aggregate functions"); elog(DEBUG, "ExecInitAgg: could not find any aggregate functions");
numaggs = 1; numaggs = 1;
@ -655,8 +670,8 @@ ExecInitAgg(Agg *node, EState *estate, Plan *parent)
ExecInitResultTupleSlot(estate, &aggstate->csstate.cstate); ExecInitResultTupleSlot(estate, &aggstate->csstate.cstate);
/* /*
* Set up aggregate-result storage in the expr context, * Set up aggregate-result storage in the expr context, and also
* and also allocate my private per-agg working storage * allocate my private per-agg working storage
*/ */
econtext = aggstate->csstate.cstate.cs_ExprContext; econtext = aggstate->csstate.cstate.cs_ExprContext;
econtext->ecxt_aggvalues = (Datum *) palloc(sizeof(Datum) * numaggs); econtext->ecxt_aggvalues = (Datum *) palloc(sizeof(Datum) * numaggs);
@ -762,9 +777,7 @@ ExecInitAgg(Agg *node, EState *estate, Plan *parent)
} }
if (OidIsValid(finalfn_oid)) if (OidIsValid(finalfn_oid))
{
fmgr_info(finalfn_oid, &peraggstate->finalfn); fmgr_info(finalfn_oid, &peraggstate->finalfn);
}
if (aggref->aggdistinct) if (aggref->aggdistinct)
{ {

View File

@ -8,7 +8,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/executor/nodeAppend.c,v 1.29 2000/01/26 05:56:22 momjian Exp $ * $Header: /cvsroot/pgsql/src/backend/executor/nodeAppend.c,v 1.30 2000/04/12 17:15:09 momjian Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
@ -304,6 +304,7 @@ ExecInitAppend(Append *node, EState *estate, Plan *parent)
{ {
JunkFilter *j = ExecInitJunkFilter(initNode->targetlist, JunkFilter *j = ExecInitJunkFilter(initNode->targetlist,
ExecGetTupType(initNode)); ExecGetTupType(initNode));
junkList = lappend(junkList, j); junkList = lappend(junkList, j);
} }

View File

@ -15,7 +15,7 @@
* locate group boundaries. * locate group boundaries.
* *
* IDENTIFICATION * IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/executor/nodeGroup.c,v 1.33 2000/01/27 18:11:27 tgl Exp $ * $Header: /cvsroot/pgsql/src/backend/executor/nodeGroup.c,v 1.34 2000/04/12 17:15:09 momjian Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
@ -97,8 +97,9 @@ ExecGroupEveryTuple(Group *node)
{ {
grpstate->grp_useFirstTuple = FALSE; grpstate->grp_useFirstTuple = FALSE;
/* note we rely on subplan to hold ownership of the tuple /*
* for as long as we need it; we don't copy it. * note we rely on subplan to hold ownership of the tuple for as
* long as we need it; we don't copy it.
*/ */
ExecStoreTuple(grpstate->grp_firstTuple, ExecStoreTuple(grpstate->grp_firstTuple,
grpstate->csstate.css_ScanTupleSlot, grpstate->csstate.css_ScanTupleSlot,
@ -122,6 +123,7 @@ ExecGroupEveryTuple(Group *node)
} }
else else
{ {
/* /*
* Compare with first tuple and see if this tuple is of the * Compare with first tuple and see if this tuple is of the
* same group. * same group.
@ -131,8 +133,10 @@ ExecGroupEveryTuple(Group *node)
node->numCols, node->grpColIdx, node->numCols, node->grpColIdx,
grpstate->eqfunctions)) grpstate->eqfunctions))
{ {
/* /*
* No; save the tuple to return it next time, and return NULL * No; save the tuple to return it next time, and return
* NULL
*/ */
grpstate->grp_useFirstTuple = TRUE; grpstate->grp_useFirstTuple = TRUE;
heap_freetuple(firsttuple); heap_freetuple(firsttuple);
@ -142,8 +146,9 @@ ExecGroupEveryTuple(Group *node)
} }
} }
/* note we rely on subplan to hold ownership of the tuple /*
* for as long as we need it; we don't copy it. * note we rely on subplan to hold ownership of the tuple for as
* long as we need it; we don't copy it.
*/ */
ExecStoreTuple(outerTuple, ExecStoreTuple(outerTuple,
grpstate->csstate.css_ScanTupleSlot, grpstate->csstate.css_ScanTupleSlot,
@ -227,8 +232,8 @@ ExecGroupOneTuple(Group *node)
outerTuple = outerslot->val; outerTuple = outerslot->val;
/* /*
* Compare with first tuple and see if this tuple is of the * Compare with first tuple and see if this tuple is of the same
* same group. * group.
*/ */
if (!execTuplesMatch(firsttuple, outerTuple, if (!execTuplesMatch(firsttuple, outerTuple,
tupdesc, tupdesc,
@ -244,8 +249,9 @@ ExecGroupOneTuple(Group *node)
*/ */
projInfo = grpstate->csstate.cstate.cs_ProjInfo; projInfo = grpstate->csstate.cstate.cs_ProjInfo;
/* note we rely on subplan to hold ownership of the tuple /*
* for as long as we need it; we don't copy it. * note we rely on subplan to hold ownership of the tuple for as long
* as we need it; we don't copy it.
*/ */
ExecStoreTuple(firsttuple, ExecStoreTuple(firsttuple,
grpstate->csstate.css_ScanTupleSlot, grpstate->csstate.css_ScanTupleSlot,

View File

@ -8,7 +8,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/executor/nodeIndexscan.c,v 1.48 2000/04/07 00:30:41 tgl Exp $ * $Header: /cvsroot/pgsql/src/backend/executor/nodeIndexscan.c,v 1.49 2000/04/12 17:15:09 momjian Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
@ -195,8 +195,8 @@ IndexNext(IndexScan *node)
List *qual; List *qual;
/* /*
* store the scanned tuple in the scan tuple slot of * store the scanned tuple in the scan tuple slot of the
* the scan state. Eventually we will only do this and not * scan state. Eventually we will only do this and not
* return a tuple. Note: we pass 'false' because tuples * return a tuple. Note: we pass 'false' because tuples
* returned by amgetnext are pointers onto disk pages and * returned by amgetnext are pointers onto disk pages and
* must not be pfree()'d. * must not be pfree()'d.
@ -208,16 +208,17 @@ IndexNext(IndexScan *node)
/* /*
* At this point we have an extra pin on the buffer, * At this point we have an extra pin on the buffer,
* because ExecStoreTuple incremented the pin count. * because ExecStoreTuple incremented the pin count. Drop
* Drop our local pin. * our local pin.
*/ */
ReleaseBuffer(buffer); ReleaseBuffer(buffer);
/* /*
* We must check to see if the current tuple was already * We must check to see if the current tuple was already
* matched by an earlier index, so we don't double-report it. * matched by an earlier index, so we don't double-report
* We do this by passing the tuple through ExecQual and * it. We do this by passing the tuple through ExecQual
* checking for failure with all previous qualifications. * and checking for failure with all previous
* qualifications.
*/ */
scanstate->cstate.cs_ExprContext->ecxt_scantuple = slot; scanstate->cstate.cs_ExprContext->ecxt_scantuple = slot;
qual = node->indxqualorig; qual = node->indxqualorig;
@ -380,6 +381,7 @@ ExecIndexReScan(IndexScan *node, ExprContext *exprCtxt, Plan *parent)
scanexpr = (run_keys[j] == RIGHT_OP) ? scanexpr = (run_keys[j] == RIGHT_OP) ?
(Node *) get_rightop(clause) : (Node *) get_rightop(clause) :
(Node *) get_leftop(clause); (Node *) get_leftop(clause);
/* /*
* pass in isDone but ignore it. We don't iterate in * pass in isDone but ignore it. We don't iterate in
* quals * quals
@ -1050,9 +1052,7 @@ ExecInitIndexScan(IndexScan *node, EState *estate, Plan *parent)
(Pointer *) &currentScanDesc); /* return: scan desc */ (Pointer *) &currentScanDesc); /* return: scan desc */
if (!RelationGetForm(currentRelation)->relhasindex) if (!RelationGetForm(currentRelation)->relhasindex)
{
elog(ERROR, "indexes of the relation %u was inactivated", reloid); elog(ERROR, "indexes of the relation %u was inactivated", reloid);
}
scanstate->css_currentRelation = currentRelation; scanstate->css_currentRelation = currentRelation;
scanstate->css_currentScanDesc = currentScanDesc; scanstate->css_currentScanDesc = currentScanDesc;

View File

@ -8,7 +8,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/executor/nodeSort.c,v 1.25 2000/01/26 05:56:23 momjian Exp $ * $Header: /cvsroot/pgsql/src/backend/executor/nodeSort.c,v 1.26 2000/04/12 17:15:09 momjian Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
@ -418,8 +418,8 @@ ExecReScanSort(Sort *node, ExprContext *exprCtxt, Plan *parent)
ExecClearTuple(sortstate->csstate.cstate.cs_ResultTupleSlot); ExecClearTuple(sortstate->csstate.cstate.cs_ResultTupleSlot);
/* /*
* If subnode is to be rescanned then we forget previous sort * If subnode is to be rescanned then we forget previous sort results;
* results; we have to re-read the subplan and re-sort. * we have to re-read the subplan and re-sort.
* *
* Otherwise we can just rewind and rescan the sorted output. * Otherwise we can just rewind and rescan the sorted output.
*/ */
@ -430,7 +430,5 @@ ExecReScanSort(Sort *node, ExprContext *exprCtxt, Plan *parent)
sortstate->tuplesortstate = NULL; sortstate->tuplesortstate = NULL;
} }
else else
{
tuplesort_rescan((Tuplesortstate *) sortstate->tuplesortstate); tuplesort_rescan((Tuplesortstate *) sortstate->tuplesortstate);
} }
}

View File

@ -7,7 +7,7 @@
* Portions Copyright (c) 1994, Regents of the University of California * Portions Copyright (c) 1994, Regents of the University of California
* *
* IDENTIFICATION * IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/executor/nodeSubplan.c,v 1.24 2000/03/23 07:32:58 tgl Exp $ * $Header: /cvsroot/pgsql/src/backend/executor/nodeSubplan.c,v 1.25 2000/04/12 17:15:10 momjian Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
@ -67,8 +67,8 @@ ExecSubPlan(SubPlan *node, List *pvar, ExprContext *econtext, bool *isNull)
ExecReScan(plan, (ExprContext *) NULL, plan); ExecReScan(plan, (ExprContext *) NULL, plan);
/* /*
* For all sublink types except EXPR_SUBLINK, the result is boolean * For all sublink types except EXPR_SUBLINK, the result is boolean as
* as are the results of the combining operators. We combine results * are the results of the combining operators. We combine results
* within a tuple (if there are multiple columns) using OR semantics * within a tuple (if there are multiple columns) using OR semantics
* if "useor" is true, AND semantics if not. We then combine results * if "useor" is true, AND semantics if not. We then combine results
* across tuples (if the subplan produces more than one) using OR * across tuples (if the subplan produces more than one) using OR
@ -106,13 +106,14 @@ ExecSubPlan(SubPlan *node, List *pvar, ExprContext *econtext, bool *isNull)
if (found) if (found)
elog(ERROR, "More than one tuple returned by a subselect used as an expression."); elog(ERROR, "More than one tuple returned by a subselect used as an expression.");
found = true; found = true;
/* /*
* We need to copy the subplan's tuple in case the result is of * We need to copy the subplan's tuple in case the result is
* pass-by-ref type --- our return value will point into this * of pass-by-ref type --- our return value will point into
* copied tuple! Can't use the subplan's instance of the tuple * this copied tuple! Can't use the subplan's instance of the
* since it won't still be valid after next ExecProcNode() call. * tuple since it won't still be valid after next
* node->curTuple keeps track of the copied tuple for eventual * ExecProcNode() call. node->curTuple keeps track of the
* freeing. * copied tuple for eventual freeing.
*/ */
tup = heap_copytuple(tup); tup = heap_copytuple(tup);
if (node->curTuple) if (node->curTuple)
@ -129,7 +130,8 @@ ExecSubPlan(SubPlan *node, List *pvar, ExprContext *econtext, bool *isNull)
found = true; found = true;
/* For ALL, ANY, and MULTIEXPR sublinks, iterate over combining /*
* For ALL, ANY, and MULTIEXPR sublinks, iterate over combining
* operators for columns of tuple. * operators for columns of tuple.
*/ */
foreach(lst, sublink->oper) foreach(lst, sublink->oper)
@ -140,12 +142,12 @@ ExecSubPlan(SubPlan *node, List *pvar, ExprContext *econtext, bool *isNull)
bool expnull; bool expnull;
/* /*
* The righthand side of the expression should be either a Const * The righthand side of the expression should be either a
* or a function call or RelabelType node taking a Const as arg * Const or a function call or RelabelType node taking a Const
* (these nodes represent run-time type coercions inserted by * as arg (these nodes represent run-time type coercions
* the parser to get to the input type needed by the operator). * inserted by the parser to get to the input type needed by
* Find the Const node and insert the actual righthand-side value * the operator). Find the Const node and insert the actual
* into it. * righthand-side value into it.
*/ */
if (!IsA(con, Const)) if (!IsA(con, Const))
{ {
@ -166,11 +168,13 @@ ExecSubPlan(SubPlan *node, List *pvar, ExprContext *econtext, bool *isNull)
} }
con->constvalue = heap_getattr(tup, col, tdesc, con->constvalue = heap_getattr(tup, col, tdesc,
&(con->constisnull)); &(con->constisnull));
/* /*
* Now we can eval the combining operator for this column. * Now we can eval the combining operator for this column.
*/ */
expresult = ExecEvalExpr((Node *) expr, econtext, &expnull, expresult = ExecEvalExpr((Node *) expr, econtext, &expnull,
(bool *) NULL); (bool *) NULL);
/* /*
* Combine the result into the row result as appropriate. * Combine the result into the row result as appropriate.
*/ */
@ -240,7 +244,9 @@ ExecSubPlan(SubPlan *node, List *pvar, ExprContext *econtext, bool *isNull)
if (!found) if (!found)
{ {
/* deal with empty subplan result. result/isNull were previously
/*
* deal with empty subplan result. result/isNull were previously
* initialized correctly for all sublink types except EXPR and * initialized correctly for all sublink types except EXPR and
* MULTIEXPR; for those, return NULL. * MULTIEXPR; for those, return NULL.
*/ */
@ -354,9 +360,9 @@ ExecSetParamPlan(SubPlan *node)
/* /*
* We need to copy the subplan's tuple in case any of the params * We need to copy the subplan's tuple in case any of the params
* are pass-by-ref type --- the pointers stored in the param structs * are pass-by-ref type --- the pointers stored in the param
* will point at this copied tuple! node->curTuple keeps track * structs will point at this copied tuple! node->curTuple keeps
* of the copied tuple for eventual freeing. * track of the copied tuple for eventual freeing.
*/ */
tup = heap_copytuple(tup); tup = heap_copytuple(tup);
if (node->curTuple) if (node->curTuple)

View File

@ -8,7 +8,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/executor/nodeTidscan.c,v 1.5 2000/04/07 00:30:41 tgl Exp $ * $Header: /cvsroot/pgsql/src/backend/executor/nodeTidscan.c,v 1.6 2000/04/12 17:15:10 momjian Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
@ -80,7 +80,8 @@ TidNext(TidScan *node)
bool bBackward; bool bBackward;
int tidNumber; int tidNumber;
ItemPointer *tidList, itemptr; ItemPointer *tidList,
itemptr;
/* ---------------- /* ----------------
* extract necessary information from tid scan node * extract necessary information from tid scan node
@ -175,17 +176,17 @@ TidNext(TidScan *node)
false); /* don't pfree */ false); /* don't pfree */
/* /*
* At this point we have an extra pin on the buffer, * At this point we have an extra pin on the buffer, because
* because ExecStoreTuple incremented the pin count. * ExecStoreTuple incremented the pin count. Drop our local
* Drop our local pin. * pin.
*/ */
ReleaseBuffer(buffer); ReleaseBuffer(buffer);
/* /*
* We must check to see if the current tuple would have * We must check to see if the current tuple would have been
* been matched by an earlier tid, so we don't double * matched by an earlier tid, so we don't double report it. We
* report it. We do this by passing the tuple through * do this by passing the tuple through ExecQual and look for
* ExecQual and look for failure with all previous * failure with all previous qualifications.
* qualifications.
*/ */
for (prev_tid = 0; prev_tid < tidstate->tss_TidPtr; for (prev_tid = 0; prev_tid < tidstate->tss_TidPtr;
prev_tid++) prev_tid++)

View File

@ -8,7 +8,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/executor/nodeUnique.c,v 1.27 2000/01/27 18:11:27 tgl Exp $ * $Header: /cvsroot/pgsql/src/backend/executor/nodeUnique.c,v 1.28 2000/04/12 17:15:10 momjian Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */

View File

@ -10,7 +10,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/lib/dllist.c,v 1.16 2000/01/26 05:56:26 momjian Exp $ * $Header: /cvsroot/pgsql/src/backend/lib/dllist.c,v 1.17 2000/04/12 17:15:10 momjian Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
@ -128,14 +128,16 @@ DLRemove(Dlelem *e)
if (e->dle_prev) if (e->dle_prev)
e->dle_prev->dle_next = e->dle_next; e->dle_prev->dle_next = e->dle_next;
else /* must be the head element */ else
/* must be the head element */
{ {
Assert(e == l->dll_head); Assert(e == l->dll_head);
l->dll_head = e->dle_next; l->dll_head = e->dle_next;
} }
if (e->dle_next) if (e->dle_next)
e->dle_next->dle_prev = e->dle_prev; e->dle_next->dle_prev = e->dle_prev;
else /* must be the tail element */ else
/* must be the tail element */
{ {
Assert(e == l->dll_tail); Assert(e == l->dll_tail);
l->dll_tail = e->dle_prev; l->dll_tail = e->dle_prev;
@ -236,7 +238,8 @@ DLMoveToFront(Dlelem *e)
if (e->dle_next) if (e->dle_next)
e->dle_next->dle_prev = e->dle_prev; e->dle_next->dle_prev = e->dle_prev;
else /* must be the tail element */ else
/* must be the tail element */
{ {
Assert(e == l->dll_tail); Assert(e == l->dll_tail);
l->dll_tail = e->dle_prev; l->dll_tail = e->dle_prev;

View File

@ -9,7 +9,7 @@
* Portions Copyright (c) 1996-2000, PostgreSQL, Inc * Portions Copyright (c) 1996-2000, PostgreSQL, Inc
* Portions Copyright (c) 1994, Regents of the University of California * Portions Copyright (c) 1994, Regents of the University of California
* *
* $Id: stringinfo.c,v 1.24 2000/01/26 05:56:26 momjian Exp $ * $Id: stringinfo.c,v 1.25 2000/04/12 17:15:11 momjian Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
@ -122,10 +122,11 @@ appendStringInfo(StringInfo str, const char *fmt,...)
nprinted = vsnprintf(str->data + str->len, avail, nprinted = vsnprintf(str->data + str->len, avail,
fmt, args); fmt, args);
va_end(args); va_end(args);
/* /*
* Note: some versions of vsnprintf return the number of chars * Note: some versions of vsnprintf return the number of chars
* actually stored, but at least one returns -1 on failure. * actually stored, but at least one returns -1 on failure. Be
* Be conservative about believing whether the print worked. * conservative about believing whether the print worked.
*/ */
if (nprinted >= 0 && nprinted < avail - 1) if (nprinted >= 0 && nprinted < avail - 1)
{ {

View File

@ -8,7 +8,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/libpq/auth.c,v 1.43 2000/01/26 05:56:28 momjian Exp $ * $Header: /cvsroot/pgsql/src/backend/libpq/auth.c,v 1.44 2000/04/12 17:15:13 momjian Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
@ -472,6 +472,7 @@ be_recvauth(Port *port)
AuthRequest areq = AUTH_REQ_OK; AuthRequest areq = AUTH_REQ_OK;
PacketDoneProc auth_handler = NULL; PacketDoneProc auth_handler = NULL;
switch (port->auth_method) switch (port->auth_method)
{ {
case uaReject: case uaReject:

View File

@ -7,7 +7,7 @@
* Portions Copyright (c) 1996-2000, PostgreSQL, Inc * Portions Copyright (c) 1996-2000, PostgreSQL, Inc
* Portions Copyright (c) 1994, Regents of the University of California * Portions Copyright (c) 1994, Regents of the University of California
* *
* $Id: be-dumpdata.c,v 1.32 2000/01/26 05:56:28 momjian Exp $ * $Id: be-dumpdata.c,v 1.33 2000/04/12 17:15:14 momjian Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */

View File

@ -8,7 +8,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/libpq/be-fsstubs.c,v 1.43 2000/01/26 05:56:28 momjian Exp $ * $Header: /cvsroot/pgsql/src/backend/libpq/be-fsstubs.c,v 1.44 2000/04/12 17:15:14 momjian Exp $
* *
* NOTES * NOTES
* This should be moved to a more appropriate place. It is here * This should be moved to a more appropriate place. It is here
@ -259,9 +259,9 @@ lo_tell(int fd)
} }
/* /*
* We assume we do not need to switch contexts for inv_tell. * We assume we do not need to switch contexts for inv_tell. That is
* That is true for now, but is probably more than this module * true for now, but is probably more than this module ought to
* ought to assume... * assume...
*/ */
return inv_tell(cookies[fd]); return inv_tell(cookies[fd]);
} }
@ -269,10 +269,11 @@ lo_tell(int fd)
int int
lo_unlink(Oid lobjId) lo_unlink(Oid lobjId)
{ {
/* /*
* inv_drop does not need a context switch, indeed it doesn't * inv_drop does not need a context switch, indeed it doesn't touch
* touch any LO-specific data structures at all. (Again, that's * any LO-specific data structures at all. (Again, that's probably
* probably more than this module ought to be assuming.) * more than this module ought to be assuming.)
* *
* XXX there ought to be some code to clean up any open LOs that * XXX there ought to be some code to clean up any open LOs that
* reference the specified relation... as is, they remain "open". * reference the specified relation... as is, they remain "open".
@ -417,9 +418,9 @@ lo_export(Oid lobjId, text *filename)
/* /*
* open the file to be written to * open the file to be written to
* *
* Note: we reduce backend's normal 077 umask to the slightly * Note: we reduce backend's normal 077 umask to the slightly friendlier
* friendlier 022. This code used to drop it all the way to 0, * 022. This code used to drop it all the way to 0, but creating
* but creating world-writable export files doesn't seem wise. * world-writable export files doesn't seem wise.
*/ */
nbytes = VARSIZE(filename) - VARHDRSZ + 1; nbytes = VARSIZE(filename) - VARHDRSZ + 1;
if (nbytes > FNAME_BUFSIZE) if (nbytes > FNAME_BUFSIZE)
@ -470,8 +471,9 @@ lo_commit(bool isCommit)
currentContext = MemoryContextSwitchTo((MemoryContext) fscxt); currentContext = MemoryContextSwitchTo((MemoryContext) fscxt);
/* Clean out still-open index scans (not necessary if aborting) /*
* and clear cookies array so that LO fds are no longer good. * Clean out still-open index scans (not necessary if aborting) and
* clear cookies array so that LO fds are no longer good.
*/ */
for (i = 0; i < MAX_LOBJ_FDS; i++) for (i = 0; i < MAX_LOBJ_FDS; i++)
{ {

View File

@ -5,7 +5,7 @@
* wherein you authenticate a user by seeing what IP address the system * wherein you authenticate a user by seeing what IP address the system
* says he comes from and possibly using ident). * says he comes from and possibly using ident).
* *
* $Id: hba.c,v 1.50 2000/03/17 02:36:08 tgl Exp $ * $Id: hba.c,v 1.51 2000/04/12 17:15:14 momjian Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
@ -221,7 +221,8 @@ process_hba_record(FILE *file, hbaPort *port, bool *matches_p, bool *error_p)
#ifdef USE_SSL #ifdef USE_SSL
/* If SSL, then check that we are on SSL */ /* If SSL, then check that we are on SSL */
if (strcmp(buf, "hostssl") == 0) { if (strcmp(buf, "hostssl") == 0)
{
if (!port->ssl) if (!port->ssl)
discard = 1; discard = 1;

View File

@ -8,7 +8,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/libpq/Attic/portalbuf.c,v 1.23 2000/03/17 02:36:08 tgl Exp $ * $Header: /cvsroot/pgsql/src/backend/libpq/Attic/portalbuf.c,v 1.24 2000/04/12 17:15:14 momjian Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */

View File

@ -29,7 +29,7 @@
* Portions Copyright (c) 1996-2000, PostgreSQL, Inc * Portions Copyright (c) 1996-2000, PostgreSQL, Inc
* Portions Copyright (c) 1994, Regents of the University of California * Portions Copyright (c) 1994, Regents of the University of California
* *
* $Id: pqcomm.c,v 1.87 2000/01/26 05:56:29 momjian Exp $ * $Id: pqcomm.c,v 1.88 2000/04/12 17:15:14 momjian Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
@ -561,9 +561,7 @@ pq_getstring(StringInfo s)
/* Read until we get the terminating '\0' */ /* Read until we get the terminating '\0' */
while ((c = pq_getbyte()) != EOF && c != '\0') while ((c = pq_getbyte()) != EOF && c != '\0')
{
appendStringInfoChar(s, c); appendStringInfoChar(s, c);
}
if (c == EOF) if (c == EOF)
return EOF; return EOF;
@ -614,6 +612,7 @@ pq_flush(void)
while (bufptr < bufend) while (bufptr < bufend)
{ {
int r; int r;
#ifdef USE_SSL #ifdef USE_SSL
if (MyProcPort->ssl) if (MyProcPort->ssl)
r = SSL_write(MyProcPort->ssl, bufptr, bufend - bufptr); r = SSL_write(MyProcPort->ssl, bufptr, bufend - bufptr);

View File

@ -16,7 +16,7 @@
* Portions Copyright (c) 1996-2000, PostgreSQL, Inc * Portions Copyright (c) 1996-2000, PostgreSQL, Inc
* Portions Copyright (c) 1994, Regents of the University of California * Portions Copyright (c) 1994, Regents of the University of California
* *
* $Id: pqformat.c,v 1.12 2000/01/26 05:56:29 momjian Exp $ * $Id: pqformat.c,v 1.13 2000/04/12 17:15:14 momjian Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
@ -156,6 +156,7 @@ void
pq_sendstring(StringInfo buf, const char *str) pq_sendstring(StringInfo buf, const char *str)
{ {
int slen = strlen(str); int slen = strlen(str);
#ifdef MULTIBYTE #ifdef MULTIBYTE
char *p; char *p;
@ -237,6 +238,7 @@ int
pq_puttextmessage(char msgtype, const char *str) pq_puttextmessage(char msgtype, const char *str)
{ {
int slen = strlen(str); int slen = strlen(str);
#ifdef MULTIBYTE #ifdef MULTIBYTE
char *p; char *p;
@ -244,6 +246,7 @@ pq_puttextmessage(char msgtype, const char *str)
if (p != str) /* actual conversion has been done? */ if (p != str) /* actual conversion has been done? */
{ {
int result = pq_putmessage(msgtype, p, strlen(p) + 1); int result = pq_putmessage(msgtype, p, strlen(p) + 1);
pfree(p); pfree(p);
return result; return result;
} }
@ -308,8 +311,10 @@ int
pq_getstr(StringInfo s) pq_getstr(StringInfo s)
{ {
int result; int result;
#ifdef MULTIBYTE #ifdef MULTIBYTE
char *p; char *p;
#endif #endif
result = pq_getstring(s); result = pq_getstring(s);

View File

@ -9,7 +9,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/libpq/Attic/pqpacket.c,v 1.25 2000/03/19 22:10:07 tgl Exp $ * $Header: /cvsroot/pgsql/src/backend/libpq/Attic/pqpacket.c,v 1.26 2000/04/12 17:15:14 momjian Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */

View File

@ -8,7 +8,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/nodes/copyfuncs.c,v 1.112 2000/04/08 00:21:15 tgl Exp $ * $Header: /cvsroot/pgsql/src/backend/nodes/copyfuncs.c,v 1.113 2000/04/12 17:15:16 momjian Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
@ -1108,6 +1108,7 @@ _copyIndexOptInfo(IndexOptInfo *from)
static void static void
CopyPathFields(Path *from, Path *newnode) CopyPathFields(Path *from, Path *newnode)
{ {
/* /*
* Modify the next line, since it causes the copying to cycle (i.e. * Modify the next line, since it causes the copying to cycle (i.e.
* the parent points right back here! -- JMH, 7/7/92. Old version: * the parent points right back here! -- JMH, 7/7/92. Old version:
@ -1189,6 +1190,7 @@ _copyTidPath(TidPath *from)
return newnode; return newnode;
} }
/* ---------------- /* ----------------
* CopyJoinPathFields * CopyJoinPathFields
* *
@ -1497,8 +1499,8 @@ _copyQuery(Query *from)
/* /*
* We do not copy the planner internal fields: base_rel_list, * We do not copy the planner internal fields: base_rel_list,
* join_rel_list, equi_key_list, query_pathkeys. * join_rel_list, equi_key_list, query_pathkeys. Not entirely clear if
* Not entirely clear if this is right? * this is right?
*/ */
return newnode; return newnode;

View File

@ -8,7 +8,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/nodes/equalfuncs.c,v 1.65 2000/03/22 22:08:32 tgl Exp $ * $Header: /cvsroot/pgsql/src/backend/nodes/equalfuncs.c,v 1.66 2000/04/12 17:15:16 momjian Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
@ -81,9 +81,11 @@ _equalFjoin(Fjoin *a, Fjoin *b)
static bool static bool
_equalExpr(Expr *a, Expr *b) _equalExpr(Expr *a, Expr *b)
{ {
/* We do not examine typeOid, since the optimizer often doesn't
* bother to set it in created nodes, and it is logically a /*
* derivative of the oper field anyway. * We do not examine typeOid, since the optimizer often doesn't bother
* to set it in created nodes, and it is logically a derivative of the
* oper field anyway.
*/ */
if (a->opType != b->opType) if (a->opType != b->opType)
return false; return false;
@ -134,7 +136,9 @@ _equalOper(Oper *a, Oper *b)
return false; return false;
if (a->opresulttype != b->opresulttype) if (a->opresulttype != b->opresulttype)
return false; return false;
/* We do not examine opid, opsize, or op_fcache, since these are
/*
* We do not examine opid, opsize, or op_fcache, since these are
* logically derived from opno, and they may not be set yet depending * logically derived from opno, and they may not be set yet depending
* on how far along the node is in the parse/plan pipeline. * on how far along the node is in the parse/plan pipeline.
* *
@ -156,10 +160,11 @@ _equalConst(Const *a, Const *b)
if (a->constbyval != b->constbyval) if (a->constbyval != b->constbyval)
return false; return false;
/* XXX What about constisset and constiscast? */ /* XXX What about constisset and constiscast? */
/* /*
* We treat all NULL constants of the same type as equal. * We treat all NULL constants of the same type as equal. Someday this
* Someday this might need to change? But datumIsEqual * might need to change? But datumIsEqual doesn't work on nulls,
* doesn't work on nulls, so... * so...
*/ */
if (a->constisnull) if (a->constisnull)
return true; return true;
@ -320,7 +325,9 @@ _equalArrayRef(ArrayRef *a, ArrayRef *b)
static bool static bool
_equalRelOptInfo(RelOptInfo *a, RelOptInfo *b) _equalRelOptInfo(RelOptInfo *a, RelOptInfo *b)
{ {
/* We treat RelOptInfos as equal if they refer to the same base rels
/*
* We treat RelOptInfos as equal if they refer to the same base rels
* joined in the same order. Is this sufficient? * joined in the same order. Is this sufficient?
*/ */
return equali(a->relids, b->relids); return equali(a->relids, b->relids);
@ -329,8 +336,10 @@ _equalRelOptInfo(RelOptInfo *a, RelOptInfo *b)
static bool static bool
_equalIndexOptInfo(IndexOptInfo *a, IndexOptInfo *b) _equalIndexOptInfo(IndexOptInfo *a, IndexOptInfo *b)
{ {
/* We treat IndexOptInfos as equal if they refer to the same index.
* Is this sufficient? /*
* We treat IndexOptInfos as equal if they refer to the same index. Is
* this sufficient?
*/ */
if (a->indexoid != b->indexoid) if (a->indexoid != b->indexoid)
return false; return false;
@ -354,7 +363,9 @@ _equalPath(Path *a, Path *b)
return false; return false;
if (!equal(a->parent, b->parent)) if (!equal(a->parent, b->parent))
return false; return false;
/* do not check path costs, since they may not be set yet, and being
/*
* do not check path costs, since they may not be set yet, and being
* float values there are roundoff error issues anyway... * float values there are roundoff error issues anyway...
*/ */
if (!equal(a->pathkeys, b->pathkeys)) if (!equal(a->pathkeys, b->pathkeys))
@ -375,8 +386,10 @@ _equalIndexPath(IndexPath *a, IndexPath *b)
return false; return false;
if (!equali(a->joinrelids, b->joinrelids)) if (!equali(a->joinrelids, b->joinrelids))
return false; return false;
/* Skip 'rows' because of possibility of floating-point roundoff error.
* It should be derivable from the other fields anyway. /*
* Skip 'rows' because of possibility of floating-point roundoff
* error. It should be derivable from the other fields anyway.
*/ */
return true; return true;
} }
@ -448,6 +461,7 @@ _equalHashPath(HashPath *a, HashPath *b)
static bool static bool
_equalIndexScan(IndexScan *a, IndexScan *b) _equalIndexScan(IndexScan *a, IndexScan *b)
{ {
/* /*
* if(a->scan.plan.cost != b->scan.plan.cost) return(false); * if(a->scan.plan.cost != b->scan.plan.cost) return(false);
*/ */
@ -642,9 +656,9 @@ _equalQuery(Query *a, Query *b)
/* /*
* We do not check the internal-to-the-planner fields: base_rel_list, * We do not check the internal-to-the-planner fields: base_rel_list,
* join_rel_list, equi_key_list, query_pathkeys. * join_rel_list, equi_key_list, query_pathkeys. They might not be set
* They might not be set yet, and in any case they should be derivable * yet, and in any case they should be derivable from the other
* from the other fields. * fields.
*/ */
return true; return true;
} }
@ -882,7 +896,8 @@ equal(void *a, void *b)
List *lb = (List *) b; List *lb = (List *) b;
List *l; List *l;
/* Try to reject by length check before we grovel through /*
* Try to reject by length check before we grovel through
* all the elements... * all the elements...
*/ */
if (length(la) != length(lb)) if (length(la) != length(lb))

View File

@ -8,7 +8,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/nodes/Attic/freefuncs.c,v 1.39 2000/03/14 23:06:28 thomas Exp $ * $Header: /cvsroot/pgsql/src/backend/nodes/Attic/freefuncs.c,v 1.40 2000/04/12 17:15:16 momjian Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
@ -746,7 +746,9 @@ _freeRelOptInfo(RelOptInfo *node)
freeObject(node->targetlist); freeObject(node->targetlist);
freeObject(node->pathlist); freeObject(node->pathlist);
/* XXX is this right? cheapest-path fields will typically be pointers
/*
* XXX is this right? cheapest-path fields will typically be pointers
* into pathlist, not separate structs... * into pathlist, not separate structs...
*/ */
freeObject(node->cheapest_startup_path); freeObject(node->cheapest_startup_path);
@ -870,7 +872,9 @@ FreeJoinPathFields(JoinPath *node)
{ {
freeObject(node->outerjoinpath); freeObject(node->outerjoinpath);
freeObject(node->innerjoinpath); freeObject(node->innerjoinpath);
/* XXX probably wrong, since ordinarily a JoinPath would share its
/*
* XXX probably wrong, since ordinarily a JoinPath would share its
* restrictinfo list with other paths made for the same join? * restrictinfo list with other paths made for the same join?
*/ */
freeObject(node->joinrestrictinfo); freeObject(node->joinrestrictinfo);
@ -970,7 +974,9 @@ _freeRestrictInfo(RestrictInfo *node)
* ---------------- * ----------------
*/ */
freeObject(node->clause); freeObject(node->clause);
/* this is certainly wrong? IndexOptInfos don't belong to
/*
* this is certainly wrong? IndexOptInfos don't belong to
* RestrictInfo... * RestrictInfo...
*/ */
freeObject(node->subclauseindices); freeObject(node->subclauseindices);

View File

@ -8,7 +8,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/nodes/list.c,v 1.30 2000/02/21 18:47:00 tgl Exp $ * $Header: /cvsroot/pgsql/src/backend/nodes/list.c,v 1.31 2000/04/12 17:15:16 momjian Exp $
* *
* NOTES * NOTES
* XXX a few of the following functions are duplicated to handle * XXX a few of the following functions are duplicated to handle

View File

@ -8,7 +8,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/nodes/makefuncs.c,v 1.20 2000/02/15 03:37:09 thomas Exp $ * $Header: /cvsroot/pgsql/src/backend/nodes/makefuncs.c,v 1.21 2000/04/12 17:15:16 momjian Exp $
* *
* NOTES * NOTES
* Creator functions in POSTGRES 4.2 are generated automatically. Most of * Creator functions in POSTGRES 4.2 are generated automatically. Most of
@ -62,11 +62,13 @@ makeVar(Index varno,
var->vartype = vartype; var->vartype = vartype;
var->vartypmod = vartypmod; var->vartypmod = vartypmod;
var->varlevelsup = varlevelsup; var->varlevelsup = varlevelsup;
/* /*
* Since few if any routines ever create Var nodes with varnoold/varoattno * Since few if any routines ever create Var nodes with
* different from varno/varattno, we don't provide separate arguments * varnoold/varoattno different from varno/varattno, we don't provide
* for them, but just initialize them to the given varno/varattno. * separate arguments for them, but just initialize them to the given
* This reduces code clutter and chance of error for most callers. * varno/varattno. This reduces code clutter and chance of error for
* most callers.
*/ */
var->varnoold = varno; var->varnoold = varno;
var->varoattno = varattno; var->varoattno = varattno;
@ -107,7 +109,9 @@ makeResdom(AttrNumber resno,
resdom->restype = restype; resdom->restype = restype;
resdom->restypmod = restypmod; resdom->restypmod = restypmod;
resdom->resname = resname; resdom->resname = resname;
/* For historical reasons, ressortgroupref defaults to 0 while
/*
* For historical reasons, ressortgroupref defaults to 0 while
* reskey/reskeyop are passed in explicitly. This is pretty silly. * reskey/reskeyop are passed in explicitly. This is pretty silly.
*/ */
resdom->ressortgroupref = 0; resdom->ressortgroupref = 0;
@ -159,8 +163,3 @@ makeAttr(char *relname, char *attname)
return a; return a;
} }

View File

@ -9,7 +9,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/nodes/nodes.c,v 1.12 2000/01/26 05:56:31 momjian Exp $ * $Header: /cvsroot/pgsql/src/backend/nodes/nodes.c,v 1.13 2000/04/12 17:15:16 momjian Exp $
* *
* HISTORY * HISTORY
* Andrew Yu Oct 20, 1994 file creation * Andrew Yu Oct 20, 1994 file creation

View File

@ -6,7 +6,7 @@
* Portions Copyright (c) 1996-2000, PostgreSQL, Inc * Portions Copyright (c) 1996-2000, PostgreSQL, Inc
* Portions Copyright (c) 1994, Regents of the University of California * Portions Copyright (c) 1994, Regents of the University of California
* *
* $Header: /cvsroot/pgsql/src/backend/nodes/outfuncs.c,v 1.113 2000/03/24 02:58:25 tgl Exp $ * $Header: /cvsroot/pgsql/src/backend/nodes/outfuncs.c,v 1.114 2000/04/12 17:15:16 momjian Exp $
* *
* NOTES * NOTES
* Every (plan) node in POSTGRES has an associated "out" routine which * Every (plan) node in POSTGRES has an associated "out" routine which
@ -60,10 +60,11 @@ _outToken(StringInfo str, char *s)
appendStringInfo(str, "<>"); appendStringInfo(str, "<>");
return; return;
} }
/* /*
* Look for characters or patterns that are treated specially by * Look for characters or patterns that are treated specially by
* read.c (either in lsptok() or in nodeRead()), and therefore need * read.c (either in lsptok() or in nodeRead()), and therefore need a
* a protective backslash. * protective backslash.
*/ */
/* These characters only need to be quoted at the start of the string */ /* These characters only need to be quoted at the start of the string */
if (*s == '<' || if (*s == '<' ||
@ -1286,8 +1287,10 @@ _outValue(StringInfo str, Value *value)
appendStringInfo(str, " %ld ", value->val.ival); appendStringInfo(str, " %ld ", value->val.ival);
break; break;
case T_Float: case T_Float:
/* We assume the value is a valid numeric literal
* and so does not need quoting. /*
* We assume the value is a valid numeric literal and so does
* not need quoting.
*/ */
appendStringInfo(str, " %s ", value->val.str); appendStringInfo(str, " %s ", value->val.str);
break; break;

View File

@ -8,7 +8,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/nodes/print.c,v 1.37 2000/02/15 20:49:12 tgl Exp $ * $Header: /cvsroot/pgsql/src/backend/nodes/print.c,v 1.38 2000/04/12 17:15:16 momjian Exp $
* *
* HISTORY * HISTORY
* AUTHOR DATE MAJOR EVENT * AUTHOR DATE MAJOR EVENT

View File

@ -9,7 +9,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/nodes/read.c,v 1.21 2000/02/21 18:47:00 tgl Exp $ * $Header: /cvsroot/pgsql/src/backend/nodes/read.c,v 1.22 2000/04/12 17:15:16 momjian Exp $
* *
* HISTORY * HISTORY
* AUTHOR DATE MAJOR EVENT * AUTHOR DATE MAJOR EVENT
@ -208,11 +208,11 @@ nodeTokenType(char *token, int length)
if ((numlen > 0 && isdigit(*numptr)) || if ((numlen > 0 && isdigit(*numptr)) ||
(numlen > 1 && *numptr == '.' && isdigit(numptr[1]))) (numlen > 1 && *numptr == '.' && isdigit(numptr[1])))
{ {
/* /*
* Yes. Figure out whether it is integral or float; * Yes. Figure out whether it is integral or float; this requires
* this requires both a syntax check and a range check. * both a syntax check and a range check. strtol() can do both for
* strtol() can do both for us. * us. We know the token will end at a character that strtol will
* We know the token will end at a character that strtol will
* stop at, so we do not need to modify the string. * stop at, so we do not need to modify the string.
*/ */
errno = 0; errno = 0;
@ -221,9 +221,10 @@ nodeTokenType(char *token, int length)
return T_Float; return T_Float;
return T_Integer; return T_Integer;
} }
/* /*
* these three cases do not need length checks, since lsptok() * these three cases do not need length checks, since lsptok() will
* will always treat them as single-byte tokens * always treat them as single-byte tokens
*/ */
else if (*token == '(') else if (*token == '(')
retval = LEFT_PAREN; retval = LEFT_PAREN;
@ -305,6 +306,7 @@ nodeRead(bool read_car_only)
{ {
/* must be "<>" */ /* must be "<>" */
this_value = NULL; this_value = NULL;
/* /*
* It might be NULL but it is an atom! * It might be NULL but it is an atom!
*/ */
@ -321,7 +323,11 @@ nodeRead(bool read_car_only)
} }
break; break;
case T_Integer: case T_Integer:
/* we know that the token terminates on a char atol will stop at */
/*
* we know that the token terminates on a char atol will stop
* at
*/
this_value = (Node *) makeInteger(atol(token)); this_value = (Node *) makeInteger(atol(token));
make_dotted_pair_cell = true; make_dotted_pair_cell = true;
break; break;

View File

@ -8,7 +8,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/nodes/readfuncs.c,v 1.87 2000/03/22 22:08:32 tgl Exp $ * $Header: /cvsroot/pgsql/src/backend/nodes/readfuncs.c,v 1.88 2000/04/12 17:15:17 momjian Exp $
* *
* NOTES * NOTES
* Most of the read functions for plan nodes are tested. (In fact, they * Most of the read functions for plan nodes are tested. (In fact, they

View File

@ -6,7 +6,7 @@
* Portions Copyright (c) 1996-2000, PostgreSQL, Inc * Portions Copyright (c) 1996-2000, PostgreSQL, Inc
* Portions Copyright (c) 1994, Regents of the University of California * Portions Copyright (c) 1994, Regents of the University of California
* *
* $Id: geqo_eval.c,v 1.48 2000/02/15 20:49:14 tgl Exp $ * $Id: geqo_eval.c,v 1.49 2000/04/12 17:15:18 momjian Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
@ -99,8 +99,8 @@ geqo_eval(Query *root, Gene *tour, int num_gene)
/* /*
* compute fitness * compute fitness
* *
* XXX geqo does not currently support optimization for partial * XXX geqo does not currently support optimization for partial result
* result retrieval --- how to fix? * retrieval --- how to fix?
*/ */
fitness = joinrel->cheapest_total_path->total_cost; fitness = joinrel->cheapest_total_path->total_cost;

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