1
0
mirror of https://github.com/postgres/postgres.git synced 2025-04-21 12:05:57 +03:00

pgindent run on all C files. Java run to follow. initdb/regression

tests pass.
This commit is contained in:
Bruce Momjian 2001-10-25 05:50:21 +00:00
parent 59da2105d8
commit b81844b173
818 changed files with 21684 additions and 20491 deletions

View File

@ -34,7 +34,6 @@ 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

@ -11,18 +11,21 @@
typedef int (*CMPFUNC) (const void *a, const void *b); typedef int (*CMPFUNC) (const void *a, const void *b);
typedef void (*BINARY_UNION) (Datum *, char *); typedef void (*BINARY_UNION) (Datum *, char *);
typedef struct intkey { typedef struct intkey
{
int4 lower; int4 lower;
int4 upper; int4 upper;
} INT4KEY; } INT4KEY;
typedef struct tskey { typedef struct tskey
{
Timestamp lower; Timestamp lower;
Timestamp upper; Timestamp upper;
} TSKEY; } TSKEY;
/* used for sorting */ /* used for sorting */
typedef struct rix { typedef struct rix
{
int index; int index;
char *r; char *r;
} RIX; } RIX;
@ -129,17 +132,19 @@ gint4_compress(PG_FUNCTION_ARGS)
GISTENTRY *entry = (GISTENTRY *) PG_GETARG_POINTER(0); GISTENTRY *entry = (GISTENTRY *) PG_GETARG_POINTER(0);
GISTENTRY *retval; GISTENTRY *retval;
if ( entry->leafkey) { if (entry->leafkey)
{
INT4KEY *r = palloc(sizeof(INT4KEY)); INT4KEY *r = palloc(sizeof(INT4KEY));
retval = palloc(sizeof(GISTENTRY)); retval = palloc(sizeof(GISTENTRY));
r->lower = r->upper = (entry->key); r->lower = r->upper = (entry->key);
gistentryinit(*retval, PointerGetDatum(r), entry->rel, entry->page, gistentryinit(*retval, PointerGetDatum(r), entry->rel, entry->page,
entry->offset, sizeof(INT4KEY), FALSE); entry->offset, sizeof(INT4KEY), FALSE);
} else {
retval = entry;
} }
else
retval = entry;
PG_RETURN_POINTER(retval); PG_RETURN_POINTER(retval);
} }
@ -152,7 +157,8 @@ gint4_consistent(PG_FUNCTION_ARGS)
StrategyNumber strategy = (StrategyNumber) PG_GETARG_UINT16(2); StrategyNumber strategy = (StrategyNumber) PG_GETARG_UINT16(2);
bool retval; bool retval;
switch(strategy) { switch (strategy)
{
case BTLessEqualStrategyNumber: case BTLessEqualStrategyNumber:
retval = (query >= kkk->lower); retval = (query >= kkk->lower);
break; break;
@ -188,8 +194,10 @@ Datum
gint4_union(PG_FUNCTION_ARGS) gint4_union(PG_FUNCTION_ARGS)
{ {
bytea *entryvec = (bytea *) PG_GETARG_POINTER(0); bytea *entryvec = (bytea *) PG_GETARG_POINTER(0);
int i, numranges; int i,
INT4KEY *cur, *out=palloc(sizeof(INT4KEY)); numranges;
INT4KEY *cur,
*out = palloc(sizeof(INT4KEY));
numranges = (VARSIZE(entryvec) - VARHDRSZ) / sizeof(GISTENTRY); numranges = (VARSIZE(entryvec) - VARHDRSZ) / sizeof(GISTENTRY);
*(int *) PG_GETARG_POINTER(1) = sizeof(INT4KEY); *(int *) PG_GETARG_POINTER(1) = sizeof(INT4KEY);
@ -198,10 +206,13 @@ gint4_union(PG_FUNCTION_ARGS)
out->lower = cur->lower; out->lower = cur->lower;
out->upper = cur->upper; out->upper = cur->upper;
for (i = 1; i < numranges; i++) { for (i = 1; i < numranges; i++)
{
cur = (INT4KEY *) DatumGetPointer((((GISTENTRY *) (VARDATA(entryvec)))[i].key)); cur = (INT4KEY *) DatumGetPointer((((GISTENTRY *) (VARDATA(entryvec)))[i].key));
if ( out->lower > cur->lower ) out->lower = cur->lower; if (out->lower > cur->lower)
if ( out->upper < cur->upper ) out->upper = cur->upper; out->lower = cur->lower;
if (out->upper < cur->upper)
out->upper = cur->upper;
} }
PG_RETURN_POINTER(out); PG_RETURN_POINTER(out);
@ -247,12 +258,16 @@ gint4_binary_union(Datum *r1, char *r2)
{ {
INT4KEY *b1; INT4KEY *b1;
INT4KEY *b2 = (INT4KEY *) r2; INT4KEY *b2 = (INT4KEY *) r2;
if ( ! DatumGetPointer( *r1 ) ) {
if (!DatumGetPointer(*r1))
{
*r1 = PointerGetDatum(palloc(sizeof(INT4KEY))); *r1 = PointerGetDatum(palloc(sizeof(INT4KEY)));
b1 = (INT4KEY *) DatumGetPointer(*r1); b1 = (INT4KEY *) DatumGetPointer(*r1);
b1->upper = b2->upper; b1->upper = b2->upper;
b1->lower = b2->lower; b1->lower = b2->lower;
} else { }
else
{
b1 = (INT4KEY *) DatumGetPointer(*r1); b1 = (INT4KEY *) DatumGetPointer(*r1);
b1->lower = (b1->lower > b2->lower) ? b1->lower = (b1->lower > b2->lower) ?
@ -264,7 +279,8 @@ gint4_binary_union(Datum *r1, char *r2)
static int static int
int4key_cmp(const void *a, const void *b) { int4key_cmp(const void *a, const void *b)
{
return (((INT4KEY *) (((RIX *) a)->r))->lower - ((INT4KEY *) (((RIX *) b)->r))->lower); return (((INT4KEY *) (((RIX *) a)->r))->lower - ((INT4KEY *) (((RIX *) b)->r))->lower);
} }
@ -278,24 +294,29 @@ gts_compress(PG_FUNCTION_ARGS)
GISTENTRY *entry = (GISTENTRY *) PG_GETARG_POINTER(0); GISTENTRY *entry = (GISTENTRY *) PG_GETARG_POINTER(0);
GISTENTRY *retval; GISTENTRY *retval;
if ( entry->leafkey) { if (entry->leafkey)
{
TSKEY *r = (TSKEY *) palloc(sizeof(TSKEY)); TSKEY *r = (TSKEY *) palloc(sizeof(TSKEY));
retval = palloc(sizeof(GISTENTRY)); retval = palloc(sizeof(GISTENTRY));
if ( entry->key ) { if (entry->key)
{
r->lower = r->upper = *(Timestamp *) (entry->key); r->lower = r->upper = *(Timestamp *) (entry->key);
gistentryinit(*retval, PointerGetDatum(r), gistentryinit(*retval, PointerGetDatum(r),
entry->rel, entry->page, entry->rel, entry->page,
entry->offset, sizeof(TSKEY), FALSE); entry->offset, sizeof(TSKEY), FALSE);
} else { }
else
{
gistentryinit(*retval, PointerGetDatum(NULL), gistentryinit(*retval, PointerGetDatum(NULL),
entry->rel, entry->page, entry->rel, entry->page,
entry->offset, 0, FALSE); entry->offset, 0, FALSE);
} }
} else {
retval = entry;
} }
else
retval = entry;
PG_RETURN_POINTER(retval); PG_RETURN_POINTER(retval);
} }
@ -307,15 +328,17 @@ gts_consistent(PG_FUNCTION_ARGS)
StrategyNumber strategy = (StrategyNumber) PG_GETARG_UINT16(2); StrategyNumber strategy = (StrategyNumber) PG_GETARG_UINT16(2);
bool retval; bool retval;
TSKEY *key; TSKEY *key;
/* /*
** if entry is not leaf, use gbox_internal_consistent, * * if entry is not leaf, use gbox_internal_consistent, * else use
** else use gbox_leaf_consistent * gbox_leaf_consistent
*/ */
if (!entry->key) if (!entry->key)
return FALSE; return FALSE;
key = (TSKEY *) DatumGetPointer(entry->key); key = (TSKEY *) DatumGetPointer(entry->key);
switch(strategy) { switch (strategy)
{
case BTLessEqualStrategyNumber: case BTLessEqualStrategyNumber:
retval = TSGE(query, &(key->lower)); retval = TSGE(query, &(key->lower));
break; break;
@ -351,8 +374,10 @@ Datum
gts_union(PG_FUNCTION_ARGS) gts_union(PG_FUNCTION_ARGS)
{ {
bytea *entryvec = (bytea *) PG_GETARG_POINTER(0); bytea *entryvec = (bytea *) PG_GETARG_POINTER(0);
int i, numranges; int i,
TSKEY *cur, *out=palloc(sizeof(TSKEY)); numranges;
TSKEY *cur,
*out = palloc(sizeof(TSKEY));
numranges = (VARSIZE(entryvec) - VARHDRSZ) / sizeof(GISTENTRY); numranges = (VARSIZE(entryvec) - VARHDRSZ) / sizeof(GISTENTRY);
*(int *) PG_GETARG_POINTER(1) = sizeof(TSKEY); *(int *) PG_GETARG_POINTER(1) = sizeof(TSKEY);
@ -361,10 +386,13 @@ gts_union(PG_FUNCTION_ARGS)
out->lower = cur->lower; out->lower = cur->lower;
out->upper = cur->upper; out->upper = cur->upper;
for (i = 1; i < numranges; i++) { for (i = 1; i < numranges; i++)
{
cur = (TSKEY *) DatumGetPointer((((GISTENTRY *) (VARDATA(entryvec)))[i].key)); cur = (TSKEY *) DatumGetPointer((((GISTENTRY *) (VARDATA(entryvec)))[i].key));
if ( TSGT( &out->lower, &cur->lower ) ) out->lower = cur->lower; if (TSGT(&out->lower, &cur->lower))
if ( TSLT( &out->upper, &cur->upper ) ) out->upper = cur->upper; out->lower = cur->lower;
if (TSLT(&out->upper, &cur->upper))
out->upper = cur->upper;
} }
PG_RETURN_POINTER(out); PG_RETURN_POINTER(out);
@ -417,6 +445,7 @@ gts_same(PG_FUNCTION_ARGS)
TSKEY *b2 = (TSKEY *) PG_GETARG_POINTER(1); TSKEY *b2 = (TSKEY *) PG_GETARG_POINTER(1);
bool *result = (bool *) PG_GETARG_POINTER(2); bool *result = (bool *) PG_GETARG_POINTER(2);
if (b1 && b2) if (b1 && b2)
*result = (TSEQ(&(b1->lower), &(b2->lower)) && TSEQ(&(b1->upper), &(b2->upper))) ? TRUE : FALSE; *result = (TSEQ(&(b1->lower), &(b2->lower)) && TSEQ(&(b1->upper), &(b2->upper))) ? TRUE : FALSE;
else else
@ -430,12 +459,15 @@ gts_binary_union(Datum *r1, char *r2)
TSKEY *b1; TSKEY *b1;
TSKEY *b2 = (TSKEY *) r2; TSKEY *b2 = (TSKEY *) r2;
if ( ! DatumGetPointer( *r1 ) ) { if (!DatumGetPointer(*r1))
{
*r1 = PointerGetDatum(palloc(sizeof(TSKEY))); *r1 = PointerGetDatum(palloc(sizeof(TSKEY)));
b1 = (TSKEY *) DatumGetPointer(*r1); b1 = (TSKEY *) DatumGetPointer(*r1);
b1->upper = b2->upper; b1->upper = b2->upper;
b1->lower = b2->lower; b1->lower = b2->lower;
} else { }
else
{
b1 = (TSKEY *) DatumGetPointer(*r1); b1 = (TSKEY *) DatumGetPointer(*r1);
b1->lower = (TSGT(&b1->lower, &b2->lower)) ? b1->lower = (TSGT(&b1->lower, &b2->lower)) ?
@ -446,7 +478,8 @@ gts_binary_union(Datum *r1, char *r2)
} }
static int static int
tskey_cmp(const void *a, const void *b) { tskey_cmp(const void *a, const void *b)
{
return DatumGetInt32( return DatumGetInt32(
DirectFunctionCall2( DirectFunctionCall2(
timestamp_cmp, timestamp_cmp,
@ -482,19 +515,24 @@ btree_picksplit(bytea *entryvec, GIST_SPLITVEC *v, BINARY_UNION bu, CMPFUNC cmp)
array = (RIX *) palloc(sizeof(RIX) * (maxoff + 1)); array = (RIX *) palloc(sizeof(RIX) * (maxoff + 1));
/* copy the data into RIXes, and sort the RIXes */ /* copy the data into RIXes, and sort the RIXes */
for (i = FirstOffsetNumber; i <= maxoff; i = OffsetNumberNext(i)) { for (i = FirstOffsetNumber; i <= maxoff; i = OffsetNumberNext(i))
{
array[i].index = i; array[i].index = i;
array[i].r = (char *) DatumGetPointer((((GISTENTRY *) (VARDATA(entryvec)))[i].key)); array[i].r = (char *) DatumGetPointer((((GISTENTRY *) (VARDATA(entryvec)))[i].key));
} }
qsort((void *) &array[FirstOffsetNumber], maxoff - FirstOffsetNumber + 1, qsort((void *) &array[FirstOffsetNumber], maxoff - FirstOffsetNumber + 1,
sizeof(RIX), cmp); sizeof(RIX), cmp);
for (i = FirstOffsetNumber; i <= maxoff; i = OffsetNumberNext(i)) { for (i = FirstOffsetNumber; i <= maxoff; i = OffsetNumberNext(i))
if (i <= (maxoff - FirstOffsetNumber + 1)/2) { {
if (i <= (maxoff - FirstOffsetNumber + 1) / 2)
{
v->spl_left[v->spl_nleft] = array[i].index; v->spl_left[v->spl_nleft] = array[i].index;
v->spl_nleft++; v->spl_nleft++;
(*bu) (&v->spl_ldatum, array[i].r); (*bu) (&v->spl_ldatum, array[i].r);
} else { }
else
{
v->spl_right[v->spl_nright] = array[i].index; v->spl_right[v->spl_nright] = array[i].index;
v->spl_nright++; v->spl_nright++;
(*bu) (&v->spl_rdatum, array[i].r); (*bu) (&v->spl_rdatum, array[i].r);
@ -520,7 +558,8 @@ btree_decompress(PG_FUNCTION_ARGS)
* In/Out for keys, not really needed * In/Out for keys, not really needed
**************************************************/ **************************************************/
Datum Datum
int4key_in(PG_FUNCTION_ARGS) { int4key_in(PG_FUNCTION_ARGS)
{
INT4KEY *key = palloc(sizeof(INT4KEY)); INT4KEY *key = palloc(sizeof(INT4KEY));
if (sscanf(PG_GETARG_POINTER(0), "%d|%d", &(key->lower), &(key->upper)) != 2) if (sscanf(PG_GETARG_POINTER(0), "%d|%d", &(key->lower), &(key->upper)) != 2)
@ -529,21 +568,26 @@ int4key_in(PG_FUNCTION_ARGS) {
PG_RETURN_POINTER(key); PG_RETURN_POINTER(key);
} }
Datum int4key_out(PG_FUNCTION_ARGS) { Datum
int4key_out(PG_FUNCTION_ARGS)
{
INT4KEY *key = (INT4KEY *) PG_GETARG_POINTER(0); INT4KEY *key = (INT4KEY *) PG_GETARG_POINTER(0);
char *str = palloc(sizeof(char) * 22); char *str = palloc(sizeof(char) * 22);
sprintf(str, "%d|%d", key->lower, key->upper); sprintf(str, "%d|%d", key->lower, key->upper);
PG_RETURN_POINTER(str); PG_RETURN_POINTER(str);
} }
Datum Datum
tskey_in(PG_FUNCTION_ARGS) { tskey_in(PG_FUNCTION_ARGS)
{
elog(ERROR, "Not implemented"); elog(ERROR, "Not implemented");
PG_RETURN_POINTER(NULL); PG_RETURN_POINTER(NULL);
} }
Datum Datum
tskey_out(PG_FUNCTION_ARGS) { tskey_out(PG_FUNCTION_ARGS)
{
elog(ERROR, "Not implemented"); elog(ERROR, "Not implemented");
PG_RETURN_POINTER(NULL); PG_RETURN_POINTER(NULL);
} }

View File

@ -4,7 +4,7 @@
* darcy@druid.net * darcy@druid.net
* http://www.druid.net/darcy/ * http://www.druid.net/darcy/
* *
* $Id: chkpass.c,v 1.4 2001/05/30 02:11:46 darcy Exp $ * $Id: chkpass.c,v 1.5 2001/10/25 05:49:19 momjian Exp $
* best viewed with tabs set to 4 * best viewed with tabs set to 4
*/ */
@ -166,7 +166,8 @@ chkpass_eq(PG_FUNCTION_ARGS)
if (!a1 || !a2) if (!a1 || !a2)
PG_RETURN_BOOL(0); PG_RETURN_BOOL(0);
if (a2->vl_len < 12) sz = a2->vl_len - 4; if (a2->vl_len < 12)
sz = a2->vl_len - 4;
strncpy(str, a2->vl_dat, sz); strncpy(str, a2->vl_dat, sz);
str[sz] = 0; str[sz] = 0;
PG_RETURN_BOOL(strcmp(a1->password, crypt(str, a1->password)) == 0); PG_RETURN_BOOL(strcmp(a1->password, crypt(str, a1->password)) == 0);
@ -181,10 +182,11 @@ chkpass_ne(PG_FUNCTION_ARGS)
char str[10]; char str[10];
int sz = 8; int sz = 8;
if (!a1 || !a2) PG_RETURN_BOOL(0); if (!a1 || !a2)
if (a2->vl_len < 12) sz = a2->vl_len - 4; PG_RETURN_BOOL(0);
if (a2->vl_len < 12)
sz = a2->vl_len - 4;
strncpy(str, a2->vl_dat, sz); strncpy(str, a2->vl_dat, sz);
str[sz] = 0; str[sz] = 0;
PG_RETURN_BOOL(strcmp(a1->password, crypt(str, a1->password)) != 0); PG_RETURN_BOOL(strcmp(a1->password, crypt(str, a1->password)) != 0);
} }

View File

@ -166,7 +166,6 @@ g_cube_consistent(GISTENTRY *entry,
NDBOX * query, NDBOX * query,
StrategyNumber strategy) StrategyNumber strategy)
{ {
/* /*
* if entry is not leaf, use g_cube_internal_consistent, else use * if entry is not leaf, use g_cube_internal_consistent, else use
* g_cube_leaf_consistent * g_cube_leaf_consistent
@ -365,7 +364,6 @@ g_cube_picksplit(bytea *entryvec,
maxoff = OffsetNumberNext(maxoff); maxoff = OffsetNumberNext(maxoff);
for (i = FirstOffsetNumber; i <= maxoff; i = OffsetNumberNext(i)) for (i = FirstOffsetNumber; i <= maxoff; i = OffsetNumberNext(i))
{ {
/* /*
* If we've already decided where to place this item, just put it * If we've already decided where to place this item, just put it
* on the right list. Otherwise, we need to figure out which page * on the right list. Otherwise, we need to figure out which page
@ -1001,7 +999,6 @@ cube_contains(NDBOX * box_a, NDBOX * box_b)
if (a->dim < b->dim) if (a->dim < b->dim)
{ {
/* /*
* the further comparisons will make sense if the excess * the further comparisons will make sense if the excess
* dimensions of (b) were zeroes * dimensions of (b) were zeroes

View File

@ -21,7 +21,9 @@
/* open a dbf-file, get it's field-info and store this information */ /* open a dbf-file, get it's field-info and store this information */
dbhead *dbf_open(u_char *file, int flags) { dbhead *
dbf_open(u_char *file, int flags)
{
int file_no; int file_no;
dbhead *dbh; dbhead *dbh;
f_descr *fields; f_descr *fields;
@ -29,22 +31,24 @@ dbhead *dbf_open(u_char *file, int flags) {
dbf_field *fieldc; dbf_field *fieldc;
int t; int t;
if ((dbh = (dbhead *)malloc(sizeof(dbhead))) == NULL) { if ((dbh = (dbhead *) malloc(sizeof(dbhead))) == NULL)
return (dbhead *) DBF_ERROR; return (dbhead *) DBF_ERROR;
}
if ((head = (dbf_header *)malloc(sizeof(dbf_header))) == NULL) { if ((head = (dbf_header *) malloc(sizeof(dbf_header))) == NULL)
{
free(dbh); free(dbh);
return (dbhead *) DBF_ERROR; return (dbhead *) DBF_ERROR;
} }
if ((fieldc = (dbf_field *)malloc(sizeof(dbf_field))) == NULL) { if ((fieldc = (dbf_field *) malloc(sizeof(dbf_field))) == NULL)
{
free(head); free(head);
free(dbh); free(dbh);
return (dbhead *) DBF_ERROR; return (dbhead *) DBF_ERROR;
} }
if ((file_no = open(file, flags)) == -1) { if ((file_no = open(file, flags)) == -1)
{
free(fieldc); free(fieldc);
free(head); free(head);
free(dbh); free(dbh);
@ -53,7 +57,8 @@ dbhead *dbf_open(u_char *file, int flags) {
/* read in the disk-header */ /* read in the disk-header */
if (read(file_no, head, sizeof(dbf_header)) == -1) { if (read(file_no, head, sizeof(dbf_header)) == -1)
{
close(file_no); close(file_no);
free(fieldc); free(fieldc);
free(head); free(head);
@ -61,7 +66,8 @@ dbhead *dbf_open(u_char *file, int flags) {
return (dbhead *) DBF_ERROR; return (dbhead *) DBF_ERROR;
} }
if (!(head->dbh_dbt & DBH_NORMAL)) { if (!(head->dbh_dbt & DBH_NORMAL))
{
close(file_no); close(file_no);
free(fieldc); free(fieldc);
free(head); free(head);
@ -70,11 +76,10 @@ dbhead *dbf_open(u_char *file, int flags) {
} }
dbh->db_fd = file_no; dbh->db_fd = file_no;
if (head->dbh_dbt & DBH_MEMO) { if (head->dbh_dbt & DBH_MEMO)
dbh->db_memo = 1; dbh->db_memo = 1;
} else { else
dbh->db_memo = 0; dbh->db_memo = 0;
}
dbh->db_year = head->dbh_year; dbh->db_year = head->dbh_year;
dbh->db_month = head->dbh_month; dbh->db_month = head->dbh_month;
dbh->db_day = head->dbh_day; dbh->db_day = head->dbh_day;
@ -84,15 +89,16 @@ dbhead *dbf_open(u_char *file, int flags) {
dbh->db_rlen = get_short((u_char *) &head->dbh_rlen); dbh->db_rlen = get_short((u_char *) &head->dbh_rlen);
dbh->db_nfields = (dbh->db_hlen - sizeof(dbf_header)) / sizeof(dbf_field); dbh->db_nfields = (dbh->db_hlen - sizeof(dbf_header)) / sizeof(dbf_field);
/* dbh->db_hlen - sizeof(dbf_header) isn't the /*
correct size, cos dbh->hlen is in fact * dbh->db_hlen - sizeof(dbf_header) isn't the correct size, cos
a little more cos of the 0x0D (and * dbh->hlen is in fact a little more cos of the 0x0D (and possibly
possibly another byte, 0x4E, I have * another byte, 0x4E, I have seen this somewhere). Because of
seen this somewhere). Because of rounding * rounding everything turns out right :)
everything turns out right :) */ */
if ((fields = (f_descr *) calloc(dbh->db_nfields, sizeof(f_descr))) if ((fields = (f_descr *) calloc(dbh->db_nfields, sizeof(f_descr)))
== NULL) { == NULL)
{
close(file_no); close(file_no);
free(fieldc); free(fieldc);
free(head); free(head);
@ -100,11 +106,13 @@ dbhead *dbf_open(u_char *file, int flags) {
return (dbhead *) DBF_ERROR; return (dbhead *) DBF_ERROR;
} }
for (t = 0; t < dbh->db_nfields; t++) { for (t = 0; t < dbh->db_nfields; t++)
{
/* Maybe I have calculated the number of fields incorrectly. This can happen /* Maybe I have calculated the number of fields incorrectly. This can happen
when programs reserve lots of space at the end of the header for future when programs reserve lots of space at the end of the header for future
expansion. This will catch this situation */ expansion. This will catch this situation */
if (fields[t].db_name[0] == 0x0D) { if (fields[t].db_name[0] == 0x0D)
{
dbh->db_nfields = t; dbh->db_nfields = t;
break; break;
} }
@ -118,9 +126,8 @@ dbhead *dbf_open(u_char *file, int flags) {
dbh->db_offset = dbh->db_hlen; dbh->db_offset = dbh->db_hlen;
dbh->db_fields = fields; dbh->db_fields = fields;
if ((dbh->db_buff = (u_char *)malloc(dbh->db_rlen)) == NULL) { if ((dbh->db_buff = (u_char *) malloc(dbh->db_rlen)) == NULL)
return (dbhead *) DBF_ERROR; return (dbhead *) DBF_ERROR;
}
free(fieldc); free(fieldc);
free(head); free(head);
@ -128,14 +135,15 @@ dbhead *dbf_open(u_char *file, int flags) {
return dbh; return dbh;
} }
int dbf_write_head(dbhead *dbh) { int
dbf_write_head(dbhead * dbh)
{
dbf_header head; dbf_header head;
time_t now; time_t now;
struct tm *dbf_time; struct tm *dbf_time;
if (lseek(dbh->db_fd, 0, SEEK_SET) == -1) { if (lseek(dbh->db_fd, 0, SEEK_SET) == -1)
return DBF_ERROR; return DBF_ERROR;
}
/* fill up the diskheader */ /* fill up the diskheader */
@ -143,12 +151,14 @@ int dbf_write_head(dbhead *dbh) {
memset(&head, '\0', sizeof(dbf_header)); memset(&head, '\0', sizeof(dbf_header));
head.dbh_dbt = DBH_NORMAL; head.dbh_dbt = DBH_NORMAL;
if (dbh->db_memo) head.dbh_dbt = DBH_MEMO; if (dbh->db_memo)
head.dbh_dbt = DBH_MEMO;
now = time((time_t *) NULL); now = time((time_t *) NULL);
dbf_time = localtime(&now); dbf_time = localtime(&now);
head.dbh_year = dbf_time->tm_year; head.dbh_year = dbf_time->tm_year;
head.dbh_month = dbf_time->tm_mon + 1; /* Months since January + 1 */ head.dbh_month = dbf_time->tm_mon + 1; /* Months since January +
* 1 */
head.dbh_day = dbf_time->tm_mday; head.dbh_day = dbf_time->tm_mday;
put_long(head.dbh_records, dbh->db_records); put_long(head.dbh_records, dbh->db_records);
@ -161,19 +171,21 @@ int dbf_write_head(dbhead *dbh) {
return 0; return 0;
} }
int dbf_put_fields(dbhead *dbh) { int
dbf_put_fields(dbhead * dbh)
{
dbf_field field; dbf_field field;
u_long t; u_long t;
u_char end = 0x0D; u_char end = 0x0D;
if (lseek(dbh->db_fd, sizeof(dbf_header), SEEK_SET) == -1) { if (lseek(dbh->db_fd, sizeof(dbf_header), SEEK_SET) == -1)
return DBF_ERROR; return DBF_ERROR;
}
/* Set dataarea of field to '\0' */ /* Set dataarea of field to '\0' */
memset(&field, '\0', sizeof(dbf_field)); memset(&field, '\0', sizeof(dbf_field));
for (t = 0; t < dbh->db_nfields; t++) { for (t = 0; t < dbh->db_nfields; t++)
{
strncpy(field.dbf_name, dbh->db_fields[t].db_name, DBF_NAMELEN - 1); strncpy(field.dbf_name, dbh->db_fields[t].db_name, DBF_NAMELEN - 1);
field.dbf_type = dbh->db_fields[t].db_type; field.dbf_type = dbh->db_fields[t].db_type;
field.dbf_flen = dbh->db_fields[t].db_flen; field.dbf_flen = dbh->db_fields[t].db_flen;
@ -189,16 +201,18 @@ int dbf_put_fields(dbhead *dbh) {
return 0; return 0;
} }
int dbf_add_field(dbhead *dbh, u_char *name, u_char type, int
u_char length, u_char dec) { dbf_add_field(dbhead * dbh, u_char *name, u_char type,
u_char length, u_char dec)
{
f_descr *ptr; f_descr *ptr;
u_char *foo; u_char *foo;
u_long size, field_no; u_long size,
field_no;
size = (dbh->db_nfields + 1) * sizeof(f_descr); size = (dbh->db_nfields + 1) * sizeof(f_descr);
if (!(ptr = (f_descr *) realloc(dbh->db_fields, size))) { if (!(ptr = (f_descr *) realloc(dbh->db_fields, size)))
return DBF_ERROR; return DBF_ERROR;
}
dbh->db_fields = ptr; dbh->db_fields = ptr;
field_no = dbh->db_nfields; field_no = dbh->db_nfields;
@ -211,29 +225,34 @@ u_long size, field_no;
dbh->db_hlen += sizeof(dbf_field); dbh->db_hlen += sizeof(dbf_field);
dbh->db_rlen += length; dbh->db_rlen += length;
if (!(foo = (u_char *) realloc(dbh->db_buff, dbh->db_rlen))) { if (!(foo = (u_char *) realloc(dbh->db_buff, dbh->db_rlen)))
return DBF_ERROR; return DBF_ERROR;
}
dbh->db_buff = foo; dbh->db_buff = foo;
return 0; return 0;
} }
dbhead *dbf_open_new(u_char *name, int flags) { dbhead *
dbf_open_new(u_char *name, int flags)
{
dbhead *dbh; dbhead *dbh;
if (!(dbh = (dbhead *)malloc(sizeof(dbhead)))) { if (!(dbh = (dbhead *) malloc(sizeof(dbhead))))
return (dbhead *) DBF_ERROR; return (dbhead *) DBF_ERROR;
}
if (flags & O_CREAT) { if (flags & O_CREAT)
if ((dbh->db_fd = open(name, flags, DBF_FILE_MODE)) == -1) { {
if ((dbh->db_fd = open(name, flags, DBF_FILE_MODE)) == -1)
{
free(dbh); free(dbh);
return (dbhead *) DBF_ERROR; return (dbhead *) DBF_ERROR;
} }
} else { }
if ((dbh->db_fd = open(name, flags)) == -1) { else
{
if ((dbh->db_fd = open(name, flags)) == -1)
{
free(dbh); free(dbh);
return (dbhead *) DBF_ERROR; return (dbhead *) DBF_ERROR;
} }
@ -256,26 +275,31 @@ dbhead *dbh;
return dbh; return dbh;
} }
void dbf_close(dbhead *dbh) { void
dbf_close(dbhead * dbh)
{
int t; int t;
close(dbh->db_fd); close(dbh->db_fd);
for (t = 0; t < dbh->db_nfields; t++) { for (t = 0; t < dbh->db_nfields; t++)
free(&dbh->db_fields[t]); free(&dbh->db_fields[t]);
}
if (dbh->db_buff != NULL) { if (dbh->db_buff != NULL)
free(dbh->db_buff); free(dbh->db_buff);
}
free(dbh); free(dbh);
} }
int dbf_get_record(dbhead *dbh, field *fields, u_long rec) { int
dbf_get_record(dbhead * dbh, field * fields, u_long rec)
{
u_char *data; u_char *data;
int t, i, offset; int t,
u_char *dbffield, *end; i,
offset;
u_char *dbffield,
*end;
/* calculate at which offset we have to read. *DON'T* forget the /* calculate at which offset we have to read. *DON'T* forget the
0x0D which seperates field-descriptions from records! 0x0D which seperates field-descriptions from records!
@ -284,7 +308,8 @@ int dbf_get_record(dbhead *dbh, field *fields, u_long rec) {
*/ */
offset = dbh->db_hlen + (rec * dbh->db_rlen); offset = dbh->db_hlen + (rec * dbh->db_rlen);
if (lseek(dbh->db_fd, offset, SEEK_SET) == -1) { if (lseek(dbh->db_fd, offset, SEEK_SET) == -1)
{
lseek(dbh->db_fd, 0, SEEK_SET); lseek(dbh->db_fd, 0, SEEK_SET);
dbh->db_offset = 0; dbh->db_offset = 0;
return DBF_ERROR; return DBF_ERROR;
@ -296,30 +321,35 @@ int dbf_get_record(dbhead *dbh, field *fields, u_long rec) {
read(dbh->db_fd, data, dbh->db_rlen); read(dbh->db_fd, data, dbh->db_rlen);
if (data[0] == DBF_DELETED) { if (data[0] == DBF_DELETED)
return DBF_DELETED; return DBF_DELETED;
}
dbffield = &data[1]; dbffield = &data[1];
for (t = 0; t < dbh->db_nfields; t++) { for (t = 0; t < dbh->db_nfields; t++)
{
strncpy(fields[t].db_name, dbh->db_fields[t].db_name, DBF_NAMELEN); strncpy(fields[t].db_name, dbh->db_fields[t].db_name, DBF_NAMELEN);
fields[t].db_type = dbh->db_fields[t].db_type; fields[t].db_type = dbh->db_fields[t].db_type;
fields[t].db_flen = dbh->db_fields[t].db_flen; fields[t].db_flen = dbh->db_fields[t].db_flen;
fields[t].db_dec = dbh->db_fields[t].db_dec; fields[t].db_dec = dbh->db_fields[t].db_dec;
if (fields[t].db_type == 'C') { if (fields[t].db_type == 'C')
{
end = &dbffield[fields[t].db_flen - 1]; end = &dbffield[fields[t].db_flen - 1];
i = fields[t].db_flen; i = fields[t].db_flen;
while (( i > 0) && ((*end < 0x21) || (*end > 0x7E))) { while ((i > 0) && ((*end < 0x21) || (*end > 0x7E)))
{
end--; end--;
i--; i--;
} }
strncpy(fields[t].db_contents, dbffield, i); strncpy(fields[t].db_contents, dbffield, i);
fields[t].db_contents[i] = '\0'; fields[t].db_contents[i] = '\0';
} else { }
else
{
end = dbffield; end = dbffield;
i = fields[t].db_flen; i = fields[t].db_flen;
while (( i > 0) && ((*end < 0x21) || (*end > 0x7E))) { while ((i > 0) && ((*end < 0x21) || (*end > 0x7E)))
{
end++; end++;
i--; i--;
} }
@ -335,19 +365,24 @@ int dbf_get_record(dbhead *dbh, field *fields, u_long rec) {
return DBF_VALID; return DBF_VALID;
} }
field *dbf_build_record(dbhead *dbh) { field *
dbf_build_record(dbhead * dbh)
{
int t; int t;
field *fields; field *fields;
if (!(fields = (field *)calloc(dbh->db_nfields, sizeof(field)))) { if (!(fields = (field *) calloc(dbh->db_nfields, sizeof(field))))
return (field *) DBF_ERROR; return (field *) DBF_ERROR;
}
for ( t = 0; t < dbh->db_nfields; t++) { for (t = 0; t < dbh->db_nfields; t++)
{
if (!(fields[t].db_contents = if (!(fields[t].db_contents =
(u_char *)malloc(dbh->db_fields[t].db_flen + 1))) { (u_char *) malloc(dbh->db_fields[t].db_flen + 1)))
for (t = 0; t < dbh->db_nfields; t++) { {
if (fields[t].db_contents != 0) { for (t = 0; t < dbh->db_nfields; t++)
{
if (fields[t].db_contents != 0)
{
free(fields[t].db_contents); free(fields[t].db_contents);
free(fields); free(fields);
} }
@ -363,21 +398,31 @@ field *dbf_build_record(dbhead *dbh) {
return fields; return fields;
} }
void dbf_free_record(dbhead *dbh, field *rec) { void
dbf_free_record(dbhead * dbh, field * rec)
{
int t; int t;
for ( t = 0; t < dbh->db_nfields; t++) { for (t = 0; t < dbh->db_nfields; t++)
free(rec[t].db_contents); free(rec[t].db_contents);
}
free(rec); free(rec);
} }
int dbf_put_record(dbhead *dbh, field *rec, u_long where) { int
u_long offset, new, idx, t, h, length; dbf_put_record(dbhead * dbh, field * rec, u_long where)
u_char *data, end = 0x1a; {
u_long offset,
new,
idx,
t,
h,
length;
u_char *data,
end = 0x1a;
double fl; double fl;
u_char foo[128], format[32]; u_char foo[128],
format[32];
/* offset: offset in file for this record /* offset: offset in file for this record
new: real offset after lseek new: real offset after lseek
@ -399,16 +444,17 @@ int dbf_put_record(dbhead *dbh, field *rec, u_long where) {
DO A SEEK_END WITH 0!!!!!! USE -1 !!!!!!!!!! DO A SEEK_END WITH 0!!!!!! USE -1 !!!!!!!!!!
*/ */
if (where > dbh->db_records) { if (where > dbh->db_records)
if ((new = lseek(dbh->db_fd, -1, SEEK_END)) == -1) { {
if ((new = lseek(dbh->db_fd, -1, SEEK_END)) == -1)
return DBF_ERROR; return DBF_ERROR;
}
dbh->db_records++; dbh->db_records++;
} else {
offset = dbh->db_hlen + (where * dbh->db_rlen);
if ((new = lseek(dbh->db_fd, offset, SEEK_SET)) == -1) {
return DBF_ERROR;
} }
else
{
offset = dbh->db_hlen + (where * dbh->db_rlen);
if ((new = lseek(dbh->db_fd, offset, SEEK_SET)) == -1)
return DBF_ERROR;
} }
dbh->db_offset = new; dbh->db_offset = new;
@ -421,32 +467,36 @@ int dbf_put_record(dbhead *dbh, field *rec, u_long where) {
/* data[0] = DBF_VALID; */ /* data[0] = DBF_VALID; */
idx = 1; idx = 1;
for (t = 0; t < dbh->db_nfields; t++) { for (t = 0; t < dbh->db_nfields; t++)
{
/* if field is empty, don't do a thing */ /* if field is empty, don't do a thing */
if (rec[t].db_contents[0] != '\0') { if (rec[t].db_contents[0] != '\0')
{
/* Handle text */ /* Handle text */
if (rec[t].db_type == 'C') { if (rec[t].db_type == 'C')
if (strlen(rec[t].db_contents) > rec[t].db_flen) { {
if (strlen(rec[t].db_contents) > rec[t].db_flen)
length = rec[t].db_flen; length = rec[t].db_flen;
} else { else
length = strlen(rec[t].db_contents); length = strlen(rec[t].db_contents);
}
strncpy(data + idx, rec[t].db_contents, length); strncpy(data + idx, rec[t].db_contents, length);
} else { }
else
{
/* Handle the rest */ /* Handle the rest */
/* Numeric is special, because of real numbers */ /* Numeric is special, because of real numbers */
if ((rec[t].db_type == 'N') && (rec[t].db_dec != 0)) { if ((rec[t].db_type == 'N') && (rec[t].db_dec != 0))
{
fl = atof(rec[t].db_contents); fl = atof(rec[t].db_contents);
sprintf(format, "%%.%df", rec[t].db_dec); sprintf(format, "%%.%df", rec[t].db_dec);
sprintf(foo, format, fl); sprintf(foo, format, fl);
} else { }
else
strcpy(foo, rec[t].db_contents); strcpy(foo, rec[t].db_contents);
} if (strlen(foo) > rec[t].db_flen)
if (strlen(foo) > rec[t].db_flen) {
length = rec[t].db_flen; length = rec[t].db_flen;
} else { else
length = strlen(foo); length = strlen(foo);
}
h = rec[t].db_flen - length; h = rec[t].db_flen - length;
strncpy(data + idx + h, foo, length); strncpy(data + idx + h, foo, length);
} }
@ -458,7 +508,8 @@ int dbf_put_record(dbhead *dbh, field *rec, u_long where) {
return DBF_ERROR; return DBF_ERROR;
/* There's a 0x1A at the end of a dbf-file */ /* There's a 0x1A at the end of a dbf-file */
if (where == dbh->db_records) { if (where == dbh->db_records)
{
if (write(dbh->db_fd, &end, 1) != 1) if (write(dbh->db_fd, &end, 1) != 1)
return DBF_ERROR; return DBF_ERROR;
} }

View File

@ -41,7 +41,8 @@
/* diskheader */ /* diskheader */
typedef struct { typedef struct
{
u_char dbh_dbt; /* indentification field */ u_char dbh_dbt; /* indentification field */
u_char dbh_year; /* last modification-date */ u_char dbh_year; /* last modification-date */
u_char dbh_month; u_char dbh_month;
@ -54,19 +55,21 @@ typedef struct {
/* disk field-description */ /* disk field-description */
typedef struct { typedef struct
{
u_char dbf_name[DBF_NAMELEN]; /* field-name terminated with \0 */ u_char dbf_name[DBF_NAMELEN]; /* field-name terminated with \0 */
u_char dbf_type; /* field-type */ u_char dbf_type; /* field-type */
u_char dbf_reserved[4]; /* some reserved stuff */ u_char dbf_reserved[4]; /* some reserved stuff */
u_char dbf_flen; /* field-length */ u_char dbf_flen; /* field-length */
u_char dbf_dec; /* number of decimal positions if u_char dbf_dec; /* number of decimal positions if type is
type is 'N' */ * 'N' */
u_char dbf_stub[14]; /* stuff we don't need */ u_char dbf_stub[14]; /* stuff we don't need */
} dbf_field; } dbf_field;
/* memory field-description */ /* memory field-description */
typedef struct { typedef struct
{
u_char db_name[DBF_NAMELEN]; /* field-name terminated with \0 */ u_char db_name[DBF_NAMELEN]; /* field-name terminated with \0 */
u_char db_type; /* field-type */ u_char db_type; /* field-type */
u_char db_flen; /* field-length */ u_char db_flen; /* field-length */
@ -75,7 +78,8 @@ typedef struct {
/* memory dfb-header */ /* memory dfb-header */
typedef struct { typedef struct
{
int db_fd; /* file-descriptor */ int db_fd; /* file-descriptor */
u_long db_offset; /* current offset in file */ u_long db_offset; /* current offset in file */
u_char db_memo; /* memo-file present */ u_char db_memo; /* memo-file present */
@ -83,15 +87,14 @@ typedef struct {
u_char db_month; u_char db_month;
u_char db_day; u_char db_day;
u_long db_hlen; /* length of the diskheader, for u_long db_hlen; /* length of the diskheader, for
calculating the offsets */ * calculating the offsets */
u_long db_records; /* number of records */ u_long db_records; /* number of records */
u_long db_currec; /* current record-number starting u_long db_currec; /* current record-number starting at 0 */
at 0 */
u_short db_rlen; /* length of the record */ u_short db_rlen; /* length of the record */
u_char db_nfields; /* number of fields */ u_char db_nfields; /* number of fields */
u_char *db_buff; /* record-buffer to save malloc()'s */ u_char *db_buff; /* record-buffer to save malloc()'s */
f_descr *db_fields; /* pointer to an array of field- f_descr *db_fields; /* pointer to an array of field-
descriptions */ * descriptions */
} dbhead; } dbhead;
/* structure that contains everything a user wants from a field, including /* structure that contains everything a user wants from a field, including
@ -99,7 +102,8 @@ typedef struct {
length of db_name! This is because a field doesn't have to be completely length of db_name! This is because a field doesn't have to be completely
filled */ filled */
typedef struct { typedef struct
{
u_char db_name[DBF_NAMELEN]; /* field-name terminated with \0 */ u_char db_name[DBF_NAMELEN]; /* field-name terminated with \0 */
u_char db_type; /* field-type */ u_char db_type; /* field-type */
u_char db_flen; /* field-length */ u_char db_flen; /* field-length */
@ -131,5 +135,4 @@ extern long get_long(u_char *cp);
extern void put_long(u_char *cp, long lval); extern void put_long(u_char *cp, long lval);
extern short get_short(u_char *cp); extern short get_short(u_char *cp);
extern void put_short(u_char *cp, short lval); extern void put_short(u_char *cp, short lval);
#endif /* _DBF_H */ #endif /* _DBF_H */

View File

@ -22,9 +22,14 @@
#include "libpq-fe.h" #include "libpq-fe.h"
#include "dbf.h" #include "dbf.h"
int verbose = 0, upper = 0, lower = 0, create = 0, fieldlow = 0; int verbose = 0,
upper = 0,
lower = 0,
create = 0,
fieldlow = 0;
int del = 0; int del = 0;
unsigned int begin = 0, end = 0; unsigned int begin = 0,
end = 0;
unsigned int t_block = 0; unsigned int t_block = 0;
#ifdef HAVE_ICONV_H #ifdef HAVE_ICONV_H
@ -51,6 +56,7 @@ void do_inserts(PGconn *, char*, dbhead*);
int check_table(PGconn *, char *); int check_table(PGconn *, char *);
char *Escape(char *); char *Escape(char *);
#ifdef HAVE_ICONV_H #ifdef HAVE_ICONV_H
char *convert_charset(char *string); char *convert_charset(char *string);
#endif #endif
@ -60,48 +66,63 @@ unsigned int isinteger(char *);
char *simple_prompt(const char *prompt, int maxlen, bool echo); char *simple_prompt(const char *prompt, int maxlen, bool echo);
unsigned int isinteger(char *buff) { unsigned int
isinteger(char *buff)
{
char *i = buff; char *i = buff;
while (*i != '\0') { while (*i != '\0')
{
if (i == buff) if (i == buff)
if ((*i == '-') || if ((*i == '-') ||
(*i == '+')) { (*i == '+'))
i++; continue; {
i++;
continue;
} }
if (!isdigit((int)*i)) return 0; if (!isdigit((int) *i))
return 0;
i++; i++;
} }
return 1; return 1;
} }
inline void strtoupper(char *string) { inline void
while(*string != '\0') { strtoupper(char *string)
{
while (*string != '\0')
{
*string = toupper(*string); *string = toupper(*string);
string++; string++;
} }
} }
inline void strtolower(char *string) { inline void
while(*string != '\0') { strtolower(char *string)
{
while (*string != '\0')
{
*string = tolower(*string); *string = tolower(*string);
string++; string++;
} }
} }
/* FIXME: should this check for overflow? */ /* FIXME: should this check for overflow? */
char *Escape(char *string) { char *
char *foo, *bar; Escape(char *string)
{
char *foo,
*bar;
foo = escape_buff; foo = escape_buff;
bar = string; bar = string;
while (*bar != '\0') { while (*bar != '\0')
{
if ((*bar == '\t') || if ((*bar == '\t') ||
(*bar == '\n') || (*bar == '\n') ||
(*bar == '\\')) { (*bar == '\\'))
*foo++ = '\\'; *foo++ = '\\';
}
*foo++ = *bar++; *foo++ = *bar++;
} }
*foo = '\0'; *foo = '\0';
@ -110,16 +131,22 @@ char *Escape(char *string) {
} }
#ifdef HAVE_ICONV_H #ifdef HAVE_ICONV_H
char *convert_charset(char *string) { char *
size_t in_size, out_size, nconv; convert_charset(char *string)
char *in_ptr,*out_ptr; {
size_t in_size,
out_size,
nconv;
char *in_ptr,
*out_ptr;
in_size = strlen(string) + 1; in_size = strlen(string) + 1;
out_size = sizeof(convert_charset_buff); out_size = sizeof(convert_charset_buff);
in_ptr = string; in_ptr = string;
out_ptr = convert_charset_buff; out_ptr = convert_charset_buff;
iconv(iconv_d, NULL, &in_size, &out_ptr, &out_size); /* necessary to reset state information */ iconv(iconv_d, NULL, &in_size, &out_ptr, &out_size); /* necessary to reset
* state information */
while (in_size > 0) while (in_size > 0)
{ {
nconv = iconv(iconv_d, &in_ptr, &in_size, &out_ptr, &out_size); nconv = iconv(iconv_d, &in_ptr, &in_size, &out_ptr, &out_size);
@ -136,27 +163,32 @@ char *convert_charset(char *string) {
} }
#endif #endif
int check_table(PGconn *conn, char *table) { int
check_table(PGconn *conn, char *table)
{
char *q = "select relname from pg_class where " char *q = "select relname from pg_class where "
"relkind='r' and relname !~* '^pg'"; "relkind='r' and relname !~* '^pg'";
PGresult *res; PGresult *res;
int i = 0; int i = 0;
if (!(res = PQexec(conn, q))) { if (!(res = PQexec(conn, q)))
{
printf("%s\n", PQerrorMessage(conn)); printf("%s\n", PQerrorMessage(conn));
return 0; return 0;
} }
for (i = 0; i < PQntuples(res); i++) { for (i = 0; i < PQntuples(res); i++)
if (!strcmp(table, PQgetvalue(res, i, PQfnumber(res, "relname")))) { {
if (!strcmp(table, PQgetvalue(res, i, PQfnumber(res, "relname"))))
return 1; return 1;
} }
}
return 0; return 0;
} }
void usage(void){ void
usage(void)
{
printf("dbf2pg\n" printf("dbf2pg\n"
"usage: dbf2pg [-u | -l] [-h hostname] [-W] [-U username]\n" "usage: dbf2pg [-u | -l] [-h hostname] [-W] [-U username]\n"
" [-B transaction_size] [-F charset_from [-T charset_to]]\n" " [-B transaction_size] [-F charset_from [-T charset_to]]\n"
@ -169,47 +201,58 @@ void usage(void){
/* Mainly for avoiding conflicts between fieldnames and SQL-reserved */ /* Mainly for avoiding conflicts between fieldnames and SQL-reserved */
/* keywords */ /* keywords */
void do_substitute(char *subarg, dbhead *dbh) void
do_substitute(char *subarg, dbhead * dbh)
{ {
/* NOTE: subarg is modified in this function */ /* NOTE: subarg is modified in this function */
int i,bad; int i,
char *p,*oldname,*newname; bad;
if (!subarg) { char *p,
*oldname,
*newname;
if (!subarg)
return; return;
} if (verbose > 1)
if (verbose>1) {
printf("Substituting new field names\n"); printf("Substituting new field names\n");
}
/* use strstr instead of strtok because of possible empty tokens */ /* use strstr instead of strtok because of possible empty tokens */
oldname = subarg; oldname = subarg;
while (oldname && strlen(oldname) && (p=strstr(oldname,"=")) ) { while (oldname && strlen(oldname) && (p = strstr(oldname, "=")))
{
*p = '\0'; /* mark end of oldname */ *p = '\0'; /* mark end of oldname */
newname = ++p; /* point past \0 of oldname */ newname = ++p; /* point past \0 of oldname */
if (strlen(newname)) { /* if not an empty string */ if (strlen(newname))
{ /* if not an empty string */
p = strstr(newname, ","); p = strstr(newname, ",");
if (p) { if (p)
{
*p = '\0'; /* mark end of newname */ *p = '\0'; /* mark end of newname */
p++; /* point past where the comma was */ p++; /* point past where the comma was */
} }
} }
if (strlen(newname)>=DBF_NAMELEN) { if (strlen(newname) >= DBF_NAMELEN)
{
printf("Truncating new field name %s to %d chars\n", printf("Truncating new field name %s to %d chars\n",
newname, DBF_NAMELEN - 1); newname, DBF_NAMELEN - 1);
newname[DBF_NAMELEN - 1] = '\0'; newname[DBF_NAMELEN - 1] = '\0';
} }
bad = 1; bad = 1;
for (i=0;i<dbh->db_nfields;i++) { for (i = 0; i < dbh->db_nfields; i++)
if (strcmp(dbh->db_fields[i].db_name,oldname)==0) { {
if (strcmp(dbh->db_fields[i].db_name, oldname) == 0)
{
bad = 0; bad = 0;
strcpy(dbh->db_fields[i].db_name, newname); strcpy(dbh->db_fields[i].db_name, newname);
if (verbose>1) { if (verbose > 1)
{
printf("Substitute old:%s new:%s\n", printf("Substitute old:%s new:%s\n",
oldname, newname); oldname, newname);
} }
break; break;
} }
} }
if (bad) { if (bad)
{
printf("Warning: old field name %s not found\n", printf("Warning: old field name %s not found\n",
oldname); oldname);
} }
@ -217,18 +260,21 @@ void do_substitute(char *subarg, dbhead *dbh)
} }
} /* do_substitute */ } /* do_substitute */
void do_create(PGconn *conn, char *table, dbhead *dbh) { void
do_create(PGconn *conn, char *table, dbhead * dbh)
{
char *query; char *query;
char t[20]; char t[20];
int i, length; int i,
length;
PGresult *res; PGresult *res;
if (verbose > 1) { if (verbose > 1)
printf("Building CREATE-clause\n"); printf("Building CREATE-clause\n");
}
if (!(query = (char *) malloc( if (!(query = (char *) malloc(
(dbh->db_nfields * 40) + 29 + strlen(table)))) { (dbh->db_nfields * 40) + 29 + strlen(table))))
{
fprintf(stderr, "Memory allocation error in function do_create\n"); fprintf(stderr, "Memory allocation error in function do_create\n");
PQfinish(conn); PQfinish(conn);
close(dbh->db_fd); close(dbh->db_fd);
@ -238,39 +284,41 @@ void do_create(PGconn *conn, char *table, dbhead *dbh) {
sprintf(query, "CREATE TABLE %s (", table); sprintf(query, "CREATE TABLE %s (", table);
length = strlen(query); length = strlen(query);
for ( i = 0; i < dbh->db_nfields; i++) { for (i = 0; i < dbh->db_nfields; i++)
if (!strlen(dbh->db_fields[i].db_name)) { {
if (!strlen(dbh->db_fields[i].db_name))
{
continue; continue;
/* skip field if length of name == 0 */ /* skip field if length of name == 0 */
} }
if ((strlen(query) != length)) { if ((strlen(query) != length))
strcat(query, ","); strcat(query, ",");
}
if (fieldlow) if (fieldlow)
strtolower(dbh->db_fields[i].db_name); strtolower(dbh->db_fields[i].db_name);
strcat(query, dbh->db_fields[i].db_name); strcat(query, dbh->db_fields[i].db_name);
switch(dbh->db_fields[i].db_type) { switch (dbh->db_fields[i].db_type)
{
case 'D': case 'D':
strcat(query, " date"); strcat(query, " date");
break; break;
case 'C': case 'C':
if (dbh->db_fields[i].db_flen > 1) { if (dbh->db_fields[i].db_flen > 1)
{
strcat(query, " varchar"); strcat(query, " varchar");
sprintf(t, "(%d)", sprintf(t, "(%d)",
dbh->db_fields[i].db_flen); dbh->db_fields[i].db_flen);
strcat(query, t); strcat(query, t);
} else {
strcat(query, " char");
} }
else
strcat(query, " char");
break; break;
case 'N': case 'N':
if (dbh->db_fields[i].db_dec != 0) { if (dbh->db_fields[i].db_dec != 0)
strcat(query, " real"); strcat(query, " real");
} else { else
strcat(query, " int"); strcat(query, " int");
}
break; break;
case 'L': case 'L':
strcat(query, " char"); strcat(query, " char");
@ -280,12 +328,14 @@ void do_create(PGconn *conn, char *table, dbhead *dbh) {
strcat(query, ")"); strcat(query, ")");
if (verbose > 1) { if (verbose > 1)
{
printf("Sending create-clause\n"); printf("Sending create-clause\n");
printf("%s\n", query); printf("%s\n", query);
} }
if ((res = PQexec(conn, query)) == NULL) { if ((res = PQexec(conn, query)) == NULL)
{
fprintf(stderr, "Error creating table!\n"); fprintf(stderr, "Error creating table!\n");
fprintf(stderr, "Detailed report: %s\n", PQerrorMessage(conn)); fprintf(stderr, "Detailed report: %s\n", PQerrorMessage(conn));
close(dbh->db_fd); close(dbh->db_fd);
@ -300,31 +350,41 @@ void do_create(PGconn *conn, char *table, dbhead *dbh) {
} }
/* FIXME: can be optimized to not use strcat, but it is worth the effort? */ /* FIXME: can be optimized to not use strcat, but it is worth the effort? */
void do_inserts(PGconn *conn, char *table, dbhead *dbh) { void
do_inserts(PGconn *conn, char *table, dbhead * dbh)
{
PGresult *res; PGresult *res;
field *fields; field *fields;
int i, h, result; int i,
char *query, *foo; h,
result;
char *query,
*foo;
char pgdate[10]; char pgdate[10];
if (verbose > 1) { if (verbose > 1)
printf("Inserting records\n"); printf("Inserting records\n");
}
h = 2; /* 2 because of terminating \n\0 */ h = 2; /* 2 because of terminating \n\0 */
for ( i = 0 ; i < dbh->db_nfields ; i++ ) { for (i = 0; i < dbh->db_nfields; i++)
{
h += dbh->db_fields[i].db_flen > 2 ? h += dbh->db_fields[i].db_flen > 2 ?
dbh->db_fields[i].db_flen : dbh->db_fields[i].db_flen :
2; /* account for possible NULL values (\N) */ 2; /* account for possible NULL values (\N) */
h += 1; /* the delimiter */ h += 1; /* the delimiter */
} }
/* make sure we can build the COPY query, note that we don't need to just /*
add this value, since the COPY query is a separate query (see below) */ * make sure we can build the COPY query, note that we don't need to
if (h < 17+strlen(table)) h = 17+strlen(table); * just add this value, since the COPY query is a separate query (see
* below)
*/
if (h < 17 + strlen(table))
h = 17 + strlen(table);
if (!(query = (char *)malloc(h))) { if (!(query = (char *) malloc(h)))
{
PQfinish(conn); PQfinish(conn);
fprintf(stderr, fprintf(stderr,
"Memory allocation error in function do_inserts (query)\n"); "Memory allocation error in function do_inserts (query)\n");
@ -333,7 +393,8 @@ void do_inserts(PGconn *conn, char *table, dbhead *dbh) {
exit(1); exit(1);
} }
if ((fields = dbf_build_record(dbh)) == (field *)DBF_ERROR) { if ((fields = dbf_build_record(dbh)) == (field *) DBF_ERROR)
{
fprintf(stderr, fprintf(stderr,
"Couldn't allocate memory for record in do_insert\n"); "Couldn't allocate memory for record in do_insert\n");
PQfinish(conn); PQfinish(conn);
@ -342,26 +403,32 @@ void do_inserts(PGconn *conn, char *table, dbhead *dbh) {
exit(1); exit(1);
} }
if (end == 0) /* "end" is a user option, if not specified, */ if (end == 0) /* "end" is a user option, if not
* specified, */
end = dbh->db_records; /* then all records are processed. */ end = dbh->db_records; /* then all records are processed. */
if (t_block == 0) /* user not specified transaction block size */ if (t_block == 0) /* user not specified transaction block
* size */
t_block = end - begin; /* then we set it to be the full data */ t_block = end - begin; /* then we set it to be the full data */
for (i = begin; i < end; i++) { for (i = begin; i < end; i++)
{
/* we need to start a new transaction and COPY statement */ /* we need to start a new transaction and COPY statement */
if (((i-begin) % t_block) == 0) { if (((i - begin) % t_block) == 0)
{
if (verbose > 1) if (verbose > 1)
fprintf(stderr, "Transaction: START\n"); fprintf(stderr, "Transaction: START\n");
res = PQexec(conn, "BEGIN"); res = PQexec(conn, "BEGIN");
if (res == NULL) { if (res == NULL)
{
fprintf(stderr, "Error starting transaction!\n"); fprintf(stderr, "Error starting transaction!\n");
fprintf(stderr, "Detailed report: %s\n", PQerrorMessage(conn)); fprintf(stderr, "Detailed report: %s\n", PQerrorMessage(conn));
exit(1); exit(1);
} }
sprintf(query, "COPY %s FROM stdin", table); sprintf(query, "COPY %s FROM stdin", table);
res = PQexec(conn, query); res = PQexec(conn, query);
if (res == NULL) { if (res == NULL)
{
fprintf(stderr, "Error starting COPY!\n"); fprintf(stderr, "Error starting COPY!\n");
fprintf(stderr, "Detailed report: %s\n", PQerrorMessage(conn)); fprintf(stderr, "Detailed report: %s\n", PQerrorMessage(conn));
exit(1); exit(1);
@ -370,22 +437,22 @@ void do_inserts(PGconn *conn, char *table, dbhead *dbh) {
/* build line and submit */ /* build line and submit */
result = dbf_get_record(dbh, fields, i); result = dbf_get_record(dbh, fields, i);
if (result == DBF_VALID) { if (result == DBF_VALID)
{
query[0] = '\0'; query[0] = '\0';
for (h = 0; h < dbh->db_nfields; h++) { for (h = 0; h < dbh->db_nfields; h++)
if (!strlen(fields[h].db_name)) { {
if (!strlen(fields[h].db_name))
continue; continue;
}
if (h != 0) /* not for the first field! */ if (h != 0) /* not for the first field! */
strcat(query, "\t"); /* COPY statement field separator */ strcat(query, "\t"); /* COPY statement field
* separator */
if (upper) { if (upper)
strtoupper(fields[h].db_contents); strtoupper(fields[h].db_contents);
} if (lower)
if (lower) {
strtolower(fields[h].db_contents); strtolower(fields[h].db_contents);
}
foo = fields[h].db_contents; foo = fields[h].db_contents;
#ifdef HAVE_ICONV_H #ifdef HAVE_ICONV_H
@ -395,53 +462,67 @@ void do_inserts(PGconn *conn, char *table, dbhead *dbh) {
foo = Escape(foo); foo = Escape(foo);
/* handle the date first - liuk */ /* handle the date first - liuk */
if(fields[h].db_type=='D') { if (fields[h].db_type == 'D')
if((strlen(foo)==8) && isinteger(foo)) { {
if ((strlen(foo) == 8) && isinteger(foo))
{
sprintf(pgdate, "%c%c%c%c-%c%c-%c%c", sprintf(pgdate, "%c%c%c%c-%c%c-%c%c",
foo[0], foo[1], foo[2], foo[3], foo[0], foo[1], foo[2], foo[3],
foo[4], foo[5], foo[6], foo[7]); foo[4], foo[5], foo[6], foo[7]);
strcat(query, pgdate); strcat(query, pgdate);
} else { }
/* empty field must be inserted as NULL value in this else
way */ {
/*
* empty field must be inserted as NULL value in
* this way
*/
strcat(query, "\\N"); strcat(query, "\\N");
} }
} }
else if ((fields[h].db_type == 'N') && else if ((fields[h].db_type == 'N') &&
(fields[h].db_dec == 0)){ (fields[h].db_dec == 0))
if (isinteger(foo)) { {
if (isinteger(foo))
strcat(query, foo); strcat(query, foo);
} else { else
{
strcat(query, "\\N"); strcat(query, "\\N");
if (verbose) if (verbose)
fprintf(stderr, "Illegal numeric value found " fprintf(stderr, "Illegal numeric value found "
"in record %d, field \"%s\"\n", "in record %d, field \"%s\"\n",
i, fields[h].db_name); i, fields[h].db_name);
} }
} else { }
else
{
strcat(query, foo); /* must be character */ strcat(query, foo); /* must be character */
} }
} }
strcat(query, "\n"); strcat(query, "\n");
if ((verbose > 1) && (( i % 100) == 0)) {/* Only show every 100 */ if ((verbose > 1) && ((i % 100) == 0))
{ /* Only show every 100 */
printf("Inserting record %d\n", i); /* records. */ printf("Inserting record %d\n", i); /* records. */
} }
PQputline(conn, query); PQputline(conn, query);
} }
/* we need to end this copy and transaction */ /* we need to end this copy and transaction */
if (((i-begin) % t_block) == t_block-1) { if (((i - begin) % t_block) == t_block - 1)
{
if (verbose > 1) if (verbose > 1)
fprintf(stderr, "Transaction: END\n"); fprintf(stderr, "Transaction: END\n");
PQputline(conn, "\\.\n"); PQputline(conn, "\\.\n");
if (PQendcopy(conn) != 0) { if (PQendcopy(conn) != 0)
{
fprintf(stderr, "Something went wrong while copying. Check " fprintf(stderr, "Something went wrong while copying. Check "
"your tables!\n"); "your tables!\n");
exit(1); exit(1);
} }
res = PQexec(conn, "END"); res = PQexec(conn, "END");
if (res == NULL) { if (res == NULL)
{
fprintf(stderr, "Error committing work!\n"); fprintf(stderr, "Error committing work!\n");
fprintf(stderr, "Detailed report: %s\n", PQerrorMessage(conn)); fprintf(stderr, "Detailed report: %s\n", PQerrorMessage(conn));
exit(1); exit(1);
@ -451,17 +532,20 @@ void do_inserts(PGconn *conn, char *table, dbhead *dbh) {
/* last row copied in, end copy and transaction */ /* last row copied in, end copy and transaction */
/* remember, i is now 1 greater then when we left the loop */ /* remember, i is now 1 greater then when we left the loop */
if (((i-begin) % t_block) != 0) { if (((i - begin) % t_block) != 0)
{
if (verbose > 1) if (verbose > 1)
fprintf(stderr, "Transaction: END\n"); fprintf(stderr, "Transaction: END\n");
PQputline(conn, "\\.\n"); PQputline(conn, "\\.\n");
if (PQendcopy(conn) != 0) { if (PQendcopy(conn) != 0)
{
fprintf(stderr, "Something went wrong while copying. Check " fprintf(stderr, "Something went wrong while copying. Check "
"your tables!\n"); "your tables!\n");
} }
res = PQexec(conn, "END"); res = PQexec(conn, "END");
if (res == NULL) { if (res == NULL)
{
fprintf(stderr, "Error committing work!\n"); fprintf(stderr, "Error committing work!\n");
fprintf(stderr, "Detailed report: %s\n", PQerrorMessage(conn)); fprintf(stderr, "Detailed report: %s\n", PQerrorMessage(conn));
exit(1); exit(1);
@ -492,7 +576,9 @@ simple_prompt(const char *prompt, int maxlen, bool echo)
{ {
int length; int length;
char *destination; char *destination;
FILE *termin, *termout; FILE *termin,
*termout;
#ifdef HAVE_TERMIOS_H #ifdef HAVE_TERMIOS_H
struct termios t_orig, struct termios t_orig,
t; t;
@ -505,8 +591,8 @@ simple_prompt(const char *prompt, int maxlen, bool echo)
prompt_state = true; /* disable SIGINT */ prompt_state = true; /* disable SIGINT */
/* /*
* Do not try to collapse these into one "w+" mode file. * Do not try to collapse these into one "w+" mode file. Doesn't work
* Doesn't work on some platforms (eg, HPUX 10.20). * on some platforms (eg, HPUX 10.20).
*/ */
termin = fopen("/dev/tty", "r"); termin = fopen("/dev/tty", "r");
termout = fopen("/dev/tty", "w"); termout = fopen("/dev/tty", "w");
@ -579,7 +665,8 @@ simple_prompt(const char *prompt, int maxlen, bool echo)
} }
int main(int argc, char **argv) int
main(int argc, char **argv)
{ {
PGconn *conn; PGconn *conn;
int i; int i;
@ -588,10 +675,13 @@ int main(int argc, char **argv)
char *query; char *query;
dbhead *dbh; dbhead *dbh;
while ((i = getopt(argc, argv, "DWflucvh:b:e:d:t:s:B:U:F:T:")) != EOF) { while ((i = getopt(argc, argv, "DWflucvh:b:e:d:t:s:B:U:F:T:")) != EOF)
switch (i) { {
switch (i)
{
case 'D': case 'D':
if (create) { if (create)
{
usage(); usage();
printf("Can't use -c and -D at the same time!\n"); printf("Can't use -c and -D at the same time!\n");
exit(1); exit(1);
@ -608,7 +698,8 @@ int main(int argc, char **argv)
verbose++; verbose++;
break; break;
case 'c': case 'c':
if (del) { if (del)
{
usage(); usage();
printf("Can't use -c and -D at the same time!\n"); printf("Can't use -c and -D at the same time!\n");
exit(1); exit(1);
@ -619,7 +710,8 @@ int main(int argc, char **argv)
lower = 1; lower = 1;
break; break;
case 'u': case 'u':
if (lower) { if (lower)
{
usage(); usage();
printf("Can't use -u and -l at the same time!\n"); printf("Can't use -u and -l at the same time!\n");
exit(1); exit(1);
@ -663,7 +755,11 @@ int main(int argc, char **argv)
break; break;
case '?': case '?':
usage(); usage();
/* FIXME: Ivan thinks this is bad: printf("unknown argument: %s\n", argv[0]); */
/*
* FIXME: Ivan thinks this is bad: printf("unknown
* argument: %s\n", argv[0]);
*/
exit(1); exit(1);
break; break;
default: default:
@ -674,7 +770,8 @@ int main(int argc, char **argv)
argc -= optind; argc -= optind;
argv = &argv[optind]; argv = &argv[optind];
if (argc != 1) { if (argc != 1)
{
usage(); usage();
if (username) if (username)
free(username); free(username);
@ -699,11 +796,11 @@ int main(int argc, char **argv)
} }
#endif #endif
if (verbose > 1) { if (verbose > 1)
printf("Opening dbf-file\n"); printf("Opening dbf-file\n");
}
if ((dbh = dbf_open(argv[0], O_RDONLY)) == (dbhead *)-1) { if ((dbh = dbf_open(argv[0], O_RDONLY)) == (dbhead *) - 1)
{
fprintf(stderr, "Couldn't open xbase-file %s\n", argv[0]); fprintf(stderr, "Couldn't open xbase-file %s\n", argv[0]);
if (username) if (username)
free(username); free(username);
@ -718,26 +815,28 @@ int main(int argc, char **argv)
for (i = 0; i < dbh->db_nfields; i++) for (i = 0; i < dbh->db_nfields; i++)
strtolower(dbh->db_fields[i].db_name); strtolower(dbh->db_fields[i].db_name);
if (verbose) { if (verbose)
{
printf("dbf-file: %s, PG-dbase: %s, PG-table: %s\n", argv[0], printf("dbf-file: %s, PG-dbase: %s, PG-table: %s\n", argv[0],
dbase, dbase,
table); table);
printf("Number of records: %ld\n", dbh->db_records); printf("Number of records: %ld\n", dbh->db_records);
printf("NAME:\t\tLENGTH:\t\tTYPE:\n"); printf("NAME:\t\tLENGTH:\t\tTYPE:\n");
printf("-------------------------------------\n"); printf("-------------------------------------\n");
for (i = 0; i < dbh->db_nfields ; i++) { for (i = 0; i < dbh->db_nfields; i++)
{
printf("%-12s\t%7d\t\t%5c\n", dbh->db_fields[i].db_name, printf("%-12s\t%7d\t\t%5c\n", dbh->db_fields[i].db_name,
dbh->db_fields[i].db_flen, dbh->db_fields[i].db_flen,
dbh->db_fields[i].db_type); dbh->db_fields[i].db_type);
} }
} }
if (verbose > 1) { if (verbose > 1)
printf("Making connection to PG-server\n"); printf("Making connection to PG-server\n");
}
conn = PQsetdbLogin(host, NULL, NULL, NULL, dbase, username, password); conn = PQsetdbLogin(host, NULL, NULL, NULL, dbase, username, password);
if (PQstatus(conn) != CONNECTION_OK) { if (PQstatus(conn) != CONNECTION_OK)
{
fprintf(stderr, "Couldn't get a connection with the "); fprintf(stderr, "Couldn't get a connection with the ");
fprintf(stderr, "designated host!\n"); fprintf(stderr, "designated host!\n");
fprintf(stderr, "Detailed report: %s\n", PQerrorMessage(conn)); fprintf(stderr, "Detailed report: %s\n", PQerrorMessage(conn));
@ -756,8 +855,10 @@ int main(int argc, char **argv)
do_substitute(subarg, dbh); do_substitute(subarg, dbh);
/* create table if specified, else check if target table exists */ /* create table if specified, else check if target table exists */
if (!create) { if (!create)
if (!check_table(conn, table)) { {
if (!check_table(conn, table))
{
printf("Table does not exist!\n"); printf("Table does not exist!\n");
if (username) if (username)
free(username); free(username);
@ -767,8 +868,10 @@ int main(int argc, char **argv)
iconv_close(iconv_d); iconv_close(iconv_d);
exit(1); exit(1);
} }
if (del) { if (del)
if (!(query = (char *)malloc(13 + strlen(table)))) { {
if (!(query = (char *) malloc(13 + strlen(table))))
{
printf("Memory-allocation error in main (delete)!\n"); printf("Memory-allocation error in main (delete)!\n");
close(dbh->db_fd); close(dbh->db_fd);
free(dbh); free(dbh);
@ -781,15 +884,17 @@ int main(int argc, char **argv)
iconv_close(iconv_d); iconv_close(iconv_d);
exit(1); exit(1);
} }
if (verbose > 1) { if (verbose > 1)
printf("Deleting from original table\n"); printf("Deleting from original table\n");
}
sprintf(query, "DELETE FROM %s", table); sprintf(query, "DELETE FROM %s", table);
PQexec(conn, query); PQexec(conn, query);
free(query); free(query);
} }
} else { }
if (!(query = (char *)malloc(12 + strlen(table)))) { else
{
if (!(query = (char *) malloc(12 + strlen(table))))
{
printf("Memory-allocation error in main (drop)!\n"); printf("Memory-allocation error in main (drop)!\n");
close(dbh->db_fd); close(dbh->db_fd);
free(dbh); free(dbh);
@ -802,9 +907,8 @@ int main(int argc, char **argv)
iconv_close(iconv_d); iconv_close(iconv_d);
exit(1); exit(1);
} }
if (verbose > 1) { if (verbose > 1)
printf("Dropping original table (if one exists)\n"); printf("Dropping original table (if one exists)\n");
}
sprintf(query, "DROP TABLE %s", table); sprintf(query, "DROP TABLE %s", table);
PQexec(conn, query); PQexec(conn, query);
free(query); free(query);
@ -819,9 +923,8 @@ int main(int argc, char **argv)
PQexec(conn, "SET DATESTYLE TO 'ISO';"); PQexec(conn, "SET DATESTYLE TO 'ISO';");
do_inserts(conn, table, dbh); do_inserts(conn, table, dbh);
if (verbose > 1) { if (verbose > 1)
printf("Closing up....\n"); printf("Closing up....\n");
}
close(dbh->db_fd); close(dbh->db_fd);
free(dbh); free(dbh);

View File

@ -5,7 +5,8 @@
/* /*
* routine to change little endian long to host long * routine to change little endian long to host long
*/ */
long get_long(u_char *cp) long
get_long(u_char *cp)
{ {
long ret; long ret;
@ -17,7 +18,8 @@ long get_long(u_char *cp)
return ret; return ret;
} }
void put_long(u_char *cp, long lval) void
put_long(u_char *cp, long lval)
{ {
cp[0] = lval & 0xff; cp[0] = lval & 0xff;
cp[1] = (lval >> 8) & 0xff; cp[1] = (lval >> 8) & 0xff;
@ -28,7 +30,8 @@ void put_long(u_char *cp, long lval)
/* /*
* routine to change little endian short to host short * routine to change little endian short to host short
*/ */
short get_short(u_char *cp) short
get_short(u_char *cp)
{ {
short ret; short ret;
@ -38,7 +41,8 @@ short get_short(u_char *cp)
return ret; return ret;
} }
void put_short(u_char *cp, short sval) void
put_short(u_char *cp, short sval)
{ {
cp[0] = sval & 0xff; cp[0] = sval & 0xff;
cp[1] = (sval >> 8) & 0xff; cp[1] = (sval >> 8) & 0xff;

View File

@ -41,18 +41,17 @@ dblink(PG_FUNCTION_ARGS)
int ntuples = 0; int ntuples = 0;
ReturnSetInfo *rsi; ReturnSetInfo *rsi;
if (PG_ARGISNULL(0) || PG_ARGISNULL(1)) { if (PG_ARGISNULL(0) || PG_ARGISNULL(1))
elog(ERROR, "dblink: NULL arguments are not permitted"); elog(ERROR, "dblink: NULL arguments are not permitted");
}
if (fcinfo->resultinfo == NULL || ! IsA(fcinfo->resultinfo, ReturnSetInfo)) { if (fcinfo->resultinfo == NULL || !IsA(fcinfo->resultinfo, ReturnSetInfo))
elog(ERROR, "dblink: function called in context that does not accept a set result"); elog(ERROR, "dblink: function called in context that does not accept a set result");
}
optstr = DatumGetCString(DirectFunctionCall1(textout, PointerGetDatum(PG_GETARG_TEXT_P(0)))); optstr = DatumGetCString(DirectFunctionCall1(textout, PointerGetDatum(PG_GETARG_TEXT_P(0))));
sqlstatement = DatumGetCString(DirectFunctionCall1(textout, PointerGetDatum(PG_GETARG_TEXT_P(1)))); sqlstatement = DatumGetCString(DirectFunctionCall1(textout, PointerGetDatum(PG_GETARG_TEXT_P(1))));
if (fcinfo->flinfo->fn_extra == NULL) { if (fcinfo->flinfo->fn_extra == NULL)
{
conn = PQconnectdb(optstr); conn = PQconnectdb(optstr);
if (PQstatus(conn) == CONNECTION_BAD) if (PQstatus(conn) == CONNECTION_BAD)
@ -73,13 +72,14 @@ dblink(PG_FUNCTION_ARGS)
PQclear(res); PQclear(res);
execstatement = (char *) palloc(strlen(curstr) + strlen(sqlstatement) + 1); execstatement = (char *) palloc(strlen(curstr) + strlen(sqlstatement) + 1);
if (execstatement != NULL) { if (execstatement != NULL)
{
strcpy(execstatement, curstr); strcpy(execstatement, curstr);
strcat(execstatement, sqlstatement); strcat(execstatement, sqlstatement);
strcat(execstatement, "\0"); strcat(execstatement, "\0");
} else {
elog(ERROR, "dblink: insufficient memory" );
} }
else
elog(ERROR, "dblink: insufficient memory");
res = PQexec(conn, execstatement); res = PQexec(conn, execstatement);
if (!res || (PQresultStatus(res) != PGRES_COMMAND_OK && PQresultStatus(res) != PGRES_TUPLES_OK)) if (!res || (PQresultStatus(res) != PGRES_COMMAND_OK && PQresultStatus(res) != PGRES_TUPLES_OK))
@ -88,14 +88,17 @@ dblink(PG_FUNCTION_ARGS)
PQclear(res); PQclear(res);
PQfinish(conn); PQfinish(conn);
elog(ERROR, "dblink: sql error: %s", msg); elog(ERROR, "dblink: sql error: %s", msg);
} else { }
else
{
/* /*
* got results, start fetching them * got results, start fetching them
*/ */
PQclear(res); PQclear(res);
res = PQexec(conn, "FETCH ALL in mycursor"); res = PQexec(conn, "FETCH ALL in mycursor");
if (!res || PQresultStatus(res) != PGRES_TUPLES_OK) { if (!res || PQresultStatus(res) != PGRES_TUPLES_OK)
{
msg = pstrdup(PQerrorMessage(conn)); msg = pstrdup(PQerrorMessage(conn));
PQclear(res); PQclear(res);
PQfinish(conn); PQfinish(conn);
@ -104,7 +107,8 @@ dblink(PG_FUNCTION_ARGS)
ntuples = PQntuples(res); ntuples = PQntuples(res);
if (ntuples > 0) { if (ntuples > 0)
{
results = init_dblink_results(fcinfo->flinfo->fn_mcxt); results = init_dblink_results(fcinfo->flinfo->fn_mcxt);
results->tup_num = 0; results->tup_num = 0;
@ -132,7 +136,9 @@ dblink(PG_FUNCTION_ARGS)
PG_RETURN_POINTER(results); PG_RETURN_POINTER(results);
} else { }
else
{
PQclear(res); PQclear(res);
@ -153,7 +159,9 @@ dblink(PG_FUNCTION_ARGS)
PG_RETURN_NULL(); PG_RETURN_NULL();
} }
} }
} else { }
else
{
/* /*
* check for more results * check for more results
*/ */
@ -162,8 +170,8 @@ dblink(PG_FUNCTION_ARGS)
results->tup_num++; results->tup_num++;
ntuples = PQntuples(results->res); ntuples = PQntuples(results->res);
if (results->tup_num < ntuples) { if (results->tup_num < ntuples)
{
/* /*
* fetch them if available * fetch them if available
*/ */
@ -173,8 +181,9 @@ dblink(PG_FUNCTION_ARGS)
PG_RETURN_POINTER(results); PG_RETURN_POINTER(results);
} else { }
else
{
/* /*
* or if no more, clean things up * or if no more, clean things up
*/ */
@ -211,41 +220,41 @@ dblink_tok(PG_FUNCTION_ARGS)
int nfields = 0; int nfields = 0;
int text_len = 0; int text_len = 0;
if (PG_ARGISNULL(0) || PG_ARGISNULL(1)) { if (PG_ARGISNULL(0) || PG_ARGISNULL(1))
elog(ERROR, "dblink: NULL arguments are not permitted"); elog(ERROR, "dblink: NULL arguments are not permitted");
}
results = (dblink_results *) PG_GETARG_POINTER(0); results = (dblink_results *) PG_GETARG_POINTER(0);
if (results == NULL) { if (results == NULL)
elog(ERROR, "dblink: function called with invalid result pointer"); elog(ERROR, "dblink: function called with invalid result pointer");
}
fldnum = PG_GETARG_INT32(1); fldnum = PG_GETARG_INT32(1);
if (fldnum < 0) { if (fldnum < 0)
elog(ERROR, "dblink: field number < 0 not permitted"); elog(ERROR, "dblink: field number < 0 not permitted");
}
nfields = PQnfields(results->res); nfields = PQnfields(results->res);
if (fldnum > (nfields - 1)) { if (fldnum > (nfields - 1))
elog(ERROR, "dblink: field number %d does not exist", fldnum); elog(ERROR, "dblink: field number %d does not exist", fldnum);
}
if (PQgetisnull(results->res, results->tup_num, fldnum) == 1) { if (PQgetisnull(results->res, results->tup_num, fldnum) == 1)
{
PG_RETURN_NULL(); PG_RETURN_NULL();
} else { }
else
{
text_len = PQgetlength(results->res, results->tup_num, fldnum); text_len = PQgetlength(results->res, results->tup_num, fldnum);
result = (char *) palloc(text_len + 1); result = (char *) palloc(text_len + 1);
if (result != NULL) { if (result != NULL)
{
strcpy(result, PQgetvalue(results->res, results->tup_num, fldnum)); strcpy(result, PQgetvalue(results->res, results->tup_num, fldnum));
strcat(result, "\0"); strcat(result, "\0");
} else {
elog(ERROR, "dblink: insufficient memory" );
} }
else
elog(ERROR, "dblink: insufficient memory");
result_text = DatumGetTextP(DirectFunctionCall1(textin, CStringGetDatum(result))); result_text = DatumGetTextP(DirectFunctionCall1(textin, CStringGetDatum(result)));

View File

@ -66,5 +66,4 @@ extern Datum dblink_tok(PG_FUNCTION_ARGS);
* Internal declarations * Internal declarations
*/ */
dblink_results *init_dblink_results(MemoryContext fn_mcxt); dblink_results *init_dblink_results(MemoryContext fn_mcxt);
#endif /* DBLINK_H */ #endif /* DBLINK_H */

View File

@ -103,7 +103,6 @@ char *StopWords[] = { /* list of words to skip in indexing */
"the", "the",
"yes" "yes"
}; };
#endif /* USE_STOP_WORDS */ #endif /* USE_STOP_WORDS */
/* stuff for caching query-plans, stolen from contrib/spi/\*.c */ /* stuff for caching query-plans, stolen from contrib/spi/\*.c */
@ -205,9 +204,7 @@ fti(PG_FUNCTION_ARGS)
snprintf(query, MAX_FTI_QUERY_LENGTH, "D%s", indexname); snprintf(query, MAX_FTI_QUERY_LENGTH, "D%s", indexname);
for (i = 1; i < nargs; i++) for (i = 1; i < nargs; i++)
{
snprintf(query, MAX_FTI_QUERY_LENGTH, "%s$%s", query, args[i]); snprintf(query, MAX_FTI_QUERY_LENGTH, "%s$%s", query, args[i]);
}
plan = find_plan(query, &DeletePlans, &nDeletePlans); plan = find_plan(query, &DeletePlans, &nDeletePlans);
if (plan->nplans <= 0) if (plan->nplans <= 0)
@ -252,9 +249,7 @@ fti(PG_FUNCTION_ARGS)
snprintf(query, MAX_FTI_QUERY_LENGTH, "I%s", indexname); snprintf(query, MAX_FTI_QUERY_LENGTH, "I%s", indexname);
for (i = 1; i < nargs; i++) for (i = 1; i < nargs; i++)
{
snprintf(query, MAX_FTI_QUERY_LENGTH, "%s$%s", query, args[i]); snprintf(query, MAX_FTI_QUERY_LENGTH, "%s$%s", query, args[i]);
}
plan = find_plan(query, &InsertPlans, &nInsertPlans); plan = find_plan(query, &InsertPlans, &nInsertPlans);
@ -348,7 +343,6 @@ breakup(char *string, char *substring)
while (cur_pos > string) /* don't read before start of 'string' */ while (cur_pos > string) /* don't read before start of 'string' */
{ {
/* /*
* skip pieces at the end of a string that are not alfa-numeric * skip pieces at the end of a string that are not alfa-numeric
* (ie. 'string$%^&', last_start first points to '&', and after * (ie. 'string$%^&', last_start first points to '&', and after

View File

@ -62,11 +62,10 @@ levenshtein(PG_FUNCTION_ARGS)
int j; int j;
/* /*
* Fetch the arguments. * Fetch the arguments. str_s is referred to as the "source" cols =
* str_s is referred to as the "source" * length of source + 1 to allow for the initialization column str_t
* cols = length of source + 1 to allow for the initialization column * is referred to as the "target", rows = length of target + 1 rows =
* str_t is referred to as the "target", rows = length of target + 1 * length of target + 1 to allow for the initialization row
* rows = length of target + 1 to allow for the initialization row
*/ */
str_s = DatumGetCString(DirectFunctionCall1(textout, PointerGetDatum(PG_GETARG_TEXT_P(0)))); str_s = DatumGetCString(DirectFunctionCall1(textout, PointerGetDatum(PG_GETARG_TEXT_P(0))));
str_t = DatumGetCString(DirectFunctionCall1(textout, PointerGetDatum(PG_GETARG_TEXT_P(1)))); str_t = DatumGetCString(DirectFunctionCall1(textout, PointerGetDatum(PG_GETARG_TEXT_P(1))));
@ -75,18 +74,19 @@ levenshtein(PG_FUNCTION_ARGS)
rows = strlen(str_t) + 1; rows = strlen(str_t) + 1;
/* /*
* Restrict the length of the strings being compared to something reasonable * Restrict the length of the strings being compared to something
* because we will have to perform rows * cols calcualtions. If longer strings need to be * reasonable because we will have to perform rows * cols
* compared, increase MAX_LEVENSHTEIN_STRLEN to suit (but within your tolerance for * calcualtions. If longer strings need to be compared, increase
* speed and memory usage). * MAX_LEVENSHTEIN_STRLEN to suit (but within your tolerance for speed
* and memory usage).
*/ */
if ((cols > MAX_LEVENSHTEIN_STRLEN + 1) || (rows > MAX_LEVENSHTEIN_STRLEN + 1)) if ((cols > MAX_LEVENSHTEIN_STRLEN + 1) || (rows > MAX_LEVENSHTEIN_STRLEN + 1))
elog(ERROR, "levenshtein: Arguments may not exceed %d characters in length", MAX_LEVENSHTEIN_STRLEN); elog(ERROR, "levenshtein: Arguments may not exceed %d characters in length", MAX_LEVENSHTEIN_STRLEN);
/* /*
* If either rows or cols is 0, the answer is the other value. * If either rows or cols is 0, the answer is the other value. This
* This makes sense since it would take that many insertions * makes sense since it would take that many insertions the build a
* the build a matching string * matching string
*/ */
if (cols == 0) if (cols == 0)
@ -96,8 +96,9 @@ levenshtein(PG_FUNCTION_ARGS)
PG_RETURN_INT32(cols); PG_RETURN_INT32(cols);
/* /*
* Allocate two vectors of integers. One will be used for the "upper" row, * Allocate two vectors of integers. One will be used for the "upper"
* the other for the "lower" row. Initialize the "upper" row to 0..cols * row, the other for the "lower" row. Initialize the "upper" row to
* 0..cols
*/ */
u_cells = palloc(sizeof(int) * cols); u_cells = palloc(sizeof(int) * cols);
for (i = 0; i < cols; i++) for (i = 0; i < cols; i++)
@ -106,19 +107,20 @@ levenshtein(PG_FUNCTION_ARGS)
l_cells = palloc(sizeof(int) * cols); l_cells = palloc(sizeof(int) * cols);
/* /*
* Use str_s0 to "rewind" the pointer to str_s in the nested for loop below * Use str_s0 to "rewind" the pointer to str_s in the nested for loop
* below
*/ */
str_s0 = str_s; str_s0 = str_s;
/* /*
* Loop throught the rows, starting at row 1. Row 0 is used for the initial * Loop throught the rows, starting at row 1. Row 0 is used for the
* "upper" row. * initial "upper" row.
*/ */
for (j = 1; j < rows; j++) for (j = 1; j < rows; j++)
{ {
/* /*
* We'll always start with col 1, * We'll always start with col 1, and initialize lower row col 0
* and initialize lower row col 0 to j * to j
*/ */
l_cells[0] = j; l_cells[0] = j;
@ -130,9 +132,10 @@ levenshtein(PG_FUNCTION_ARGS)
int c3 = 0; int c3 = 0;
/* /*
* The "cost" value is 0 if the character at the current col position * The "cost" value is 0 if the character at the current col
* in the source string, matches the character at the current row position * position in the source string, matches the character at the
* in the target string; cost is 1 otherwise. * current row position in the target string; cost is 1
* otherwise.
*/ */
c = ((CHAREQ(str_s, str_t)) ? 0 : 1); c = ((CHAREQ(str_s, str_t)) ? 0 : 1);
@ -152,8 +155,7 @@ levenshtein(PG_FUNCTION_ARGS)
c3 = u_cells[i - 1] + c; c3 = u_cells[i - 1] + c;
/* /*
* The lower right cell is set to the minimum * The lower right cell is set to the minimum of c1, c2, c3
* of c1, c2, c3
*/ */
l_cells[i] = (c1 < c2 ? c1 : c2) < c3 ? (c1 < c2 ? c1 : c2) : c3; l_cells[i] = (c1 < c2 ? c1 : c2) < c3 ? (c1 < c2 ? c1 : c2) : c3;
@ -164,8 +166,8 @@ levenshtein(PG_FUNCTION_ARGS)
} }
/* /*
* Lower row now becomes the upper row, and the upper row * Lower row now becomes the upper row, and the upper row gets
* gets reused as the new lower row. * reused as the new lower row.
*/ */
tmp = u_cells; tmp = u_cells;
u_cells = l_cells; u_cells = l_cells;
@ -183,8 +185,8 @@ levenshtein(PG_FUNCTION_ARGS)
} }
/* /*
* Because the final value (at position row, col) was swapped from * Because the final value (at position row, col) was swapped from the
* the lower row to the upper row, that's where we'll find it. * lower row to the upper row, that's where we'll find it.
*/ */
PG_RETURN_INT32(u_cells[cols - 1]); PG_RETURN_INT32(u_cells[cols - 1]);
} }
@ -266,15 +268,17 @@ metaphone(PG_FUNCTION_ARGS)
/* Allows us to safely look ahead an arbitrary # of letters */ /* Allows us to safely look ahead an arbitrary # of letters */
/* I probably could have just used strlen... */ /* I probably could have just used strlen... */
char Lookahead(char * word, int how_far) { char
Lookahead(char *word, int how_far)
{
char letter_ahead = '\0'; /* null by default */ char letter_ahead = '\0'; /* null by default */
int idx; int idx;
for (idx = 0; word[idx] != '\0' && idx < how_far; idx++); for (idx = 0; word[idx] != '\0' && idx < how_far; idx++);
/* Edge forward in the string... */ /* Edge forward in the string... */
letter_ahead = word[idx]; /* idx will be either == to how_far or letter_ahead = word[idx]; /* idx will be either == to how_far or at
* at the end of the string * the end of the string */
*/
return letter_ahead; return letter_ahead;
} }
@ -290,21 +294,22 @@ char Lookahead(char * word, int how_far) {
#define Isbreak(c) (!isalpha(c)) #define Isbreak(c) (!isalpha(c))
int _metaphone ( int
_metaphone(
/* IN */ /* IN */
char *word, char *word,
int max_phonemes, int max_phonemes,
/* OUT */ /* OUT */
char **phoned_word char **phoned_word
) { )
{
int w_idx = 0; /* point in the phonization we're at. */ int w_idx = 0; /* point in the phonization we're at. */
int p_idx = 0; /* end of the phoned phrase */ int p_idx = 0; /* end of the phoned phrase */
/*-- Parameter checks --*/ /*-- Parameter checks --*/
/* /*
* Shouldn't be necessary, but left these here anyway * Shouldn't be necessary, but left these here anyway jec Aug 3, 2001
* jec Aug 3, 2001
*/ */
/* Negative phoneme length is meaningless */ /* Negative phoneme length is meaningless */
@ -316,11 +321,14 @@ int _metaphone (
elog(ERROR, "metaphone: Input string length must be > 0"); elog(ERROR, "metaphone: Input string length must be > 0");
/*-- Allocate memory for our phoned_phrase --*/ /*-- Allocate memory for our phoned_phrase --*/
if (max_phonemes == 0) { /* Assume largest possible */ if (max_phonemes == 0)
{ /* Assume largest possible */
*phoned_word = palloc(sizeof(char) * strlen(word) +1); *phoned_word = palloc(sizeof(char) * strlen(word) +1);
if (!*phoned_word) if (!*phoned_word)
return META_ERROR; return META_ERROR;
} else { }
else
{
*phoned_word = palloc(sizeof(char) * max_phonemes + 1); *phoned_word = palloc(sizeof(char) * max_phonemes + 1);
if (!*phoned_word) if (!*phoned_word)
return META_ERROR; return META_ERROR;
@ -328,23 +336,28 @@ int _metaphone (
/*-- The first phoneme has to be processed specially. --*/ /*-- The first phoneme has to be processed specially. --*/
/* Find our first letter */ /* Find our first letter */
for( ; !isalpha(Curr_Letter); w_idx++ ) { for (; !isalpha(Curr_Letter); w_idx++)
{
/* On the off chance we were given nothing but crap... */ /* On the off chance we were given nothing but crap... */
if( Curr_Letter == '\0' ) { if (Curr_Letter == '\0')
{
End_Phoned_Word End_Phoned_Word
return META_SUCCESS; /* For testing */ return META_SUCCESS; /* For testing */
} }
} }
switch (Curr_Letter) { switch (Curr_Letter)
{
/* AE becomes E */ /* AE becomes E */
case 'A': case 'A':
if( Next_Letter == 'E' ) { if (Next_Letter == 'E')
{
Phonize('E'); Phonize('E');
w_idx += 2; w_idx += 2;
} }
/* Remember, preserve vowels at the beginning */ /* Remember, preserve vowels at the beginning */
else { else
{
Phonize('A'); Phonize('A');
w_idx++; w_idx++;
} }
@ -353,14 +366,16 @@ int _metaphone (
case 'G': case 'G':
case 'K': case 'K':
case 'P': case 'P':
if( Next_Letter == 'N' ) { if (Next_Letter == 'N')
{
Phonize('N'); Phonize('N');
w_idx += 2; w_idx += 2;
} }
break; break;
/* WH becomes H,
WR becomes R /*
W if followed by a vowel */ * WH becomes H, WR becomes R W if followed by a vowel
*/
case 'W': case 'W':
if (Next_Letter == 'H' || if (Next_Letter == 'H' ||
Next_Letter == 'R') Next_Letter == 'R')
@ -368,7 +383,8 @@ int _metaphone (
Phonize(Next_Letter); Phonize(Next_Letter);
w_idx += 2; w_idx += 2;
} }
else if ( isvowel(Next_Letter) ) { else if (isvowel(Next_Letter))
{
Phonize('W'); Phonize('W');
w_idx += 2; w_idx += 2;
} }
@ -380,9 +396,9 @@ int _metaphone (
w_idx++; w_idx++;
break; break;
/* Vowels are kept */ /* Vowels are kept */
/* We did A already
case 'A': /*
case 'a': * We did A already case 'A': case 'a':
*/ */
case 'E': case 'E':
case 'I': case 'I':
@ -401,17 +417,21 @@ int _metaphone (
/* On to the metaphoning */ /* On to the metaphoning */
for (; Curr_Letter != '\0' && for (; Curr_Letter != '\0' &&
(max_phonemes == 0 || Phone_Len < max_phonemes); (max_phonemes == 0 || Phone_Len < max_phonemes);
w_idx++) { w_idx++)
/* How many letters to skip because an eariler encoding handled {
* multiple letters */ /*
* How many letters to skip because an eariler encoding handled
* multiple letters
*/
unsigned short int skip_letter = 0; unsigned short int skip_letter = 0;
/* THOUGHT: It would be nice if, rather than having things like... /*
* well, SCI. For SCI you encode the S, then have to remember * THOUGHT: It would be nice if, rather than having things
* to skip the C. So the phonome SCI invades both S and C. It would * like... well, SCI. For SCI you encode the S, then have to
* be better, IMHO, to skip the C from the S part of the encoding. * remember to skip the C. So the phonome SCI invades both S and
* Hell, I'm trying it. * C. It would be better, IMHO, to skip the C from the S part of
* the encoding. Hell, I'm trying it.
*/ */
/* Ignore non-alphas */ /* Ignore non-alphas */
@ -423,95 +443,104 @@ int _metaphone (
Curr_Letter != 'C') Curr_Letter != 'C')
continue; continue;
switch (Curr_Letter) { switch (Curr_Letter)
{
/* B -> B unless in MB */ /* B -> B unless in MB */
case 'B': case 'B':
if (Prev_Letter != 'M') if (Prev_Letter != 'M')
Phonize('B'); Phonize('B');
break; break;
/* 'sh' if -CIA- or -CH, but not SCH, except SCHW.
* (SCHW is handled in S) /*
* S if -CI-, -CE- or -CY- * 'sh' if -CIA- or -CH, but not SCH, except SCHW. (SCHW
* dropped if -SCI-, SCE-, -SCY- (handed in S) * is handled in S) S if -CI-, -CE- or -CY- dropped if
* else K * -SCI-, SCE-, -SCY- (handed in S) else K
*/ */
case 'C': case 'C':
if( MAKESOFT(Next_Letter) ) { /* C[IEY] */ if (MAKESOFT(Next_Letter))
{ /* C[IEY] */
if (After_Next_Letter == 'A' && if (After_Next_Letter == 'A' &&
Next_Letter == 'I' ) { /* CIA */ Next_Letter == 'I')
{ /* CIA */
Phonize(SH); Phonize(SH);
} }
/* SC[IEY] */ /* SC[IEY] */
else if ( Prev_Letter == 'S' ) { else if (Prev_Letter == 'S')
{
/* Dropped */ /* Dropped */
} }
else { else
Phonize('S'); Phonize('S');
} }
} else if (Next_Letter == 'H')
else if ( Next_Letter == 'H' ) { {
#ifndef USE_TRADITIONAL_METAPHONE #ifndef USE_TRADITIONAL_METAPHONE
if (After_Next_Letter == 'R' || if (After_Next_Letter == 'R' ||
Prev_Letter == 'S' ) { /* Christ, School */ Prev_Letter == 'S')
{ /* Christ, School */
Phonize('K'); Phonize('K');
} }
else { else
Phonize(SH); Phonize(SH);
}
#else #else
Phonize(SH); Phonize(SH);
#endif #endif
skip_letter++; skip_letter++;
} }
else { else
Phonize('K'); Phonize('K');
}
break; break;
/* J if in -DGE-, -DGI- or -DGY-
* else T /*
* J if in -DGE-, -DGI- or -DGY- else T
*/ */
case 'D': case 'D':
if (Next_Letter == 'G' && if (Next_Letter == 'G' &&
MAKESOFT(After_Next_Letter) ) { MAKESOFT(After_Next_Letter))
{
Phonize('J'); Phonize('J');
skip_letter++; skip_letter++;
} }
else else
Phonize('T'); Phonize('T');
break; break;
/* F if in -GH and not B--GH, D--GH, -H--GH, -H---GH
* else dropped if -GNED, -GN, /*
* else dropped if -DGE-, -DGI- or -DGY- (handled in D) * F if in -GH and not B--GH, D--GH, -H--GH, -H---GH else
* else J if in -GE-, -GI, -GY and not GG * dropped if -GNED, -GN, else dropped if -DGE-, -DGI- or
* else K * -DGY- (handled in D) else J if in -GE-, -GI, -GY and
* not GG else K
*/ */
case 'G': case 'G':
if( Next_Letter == 'H' ) { if (Next_Letter == 'H')
{
if (!(NOGHTOF(Look_Back_Letter(3)) || if (!(NOGHTOF(Look_Back_Letter(3)) ||
Look_Back_Letter(4) == 'H' ) ) { Look_Back_Letter(4) == 'H'))
{
Phonize('F'); Phonize('F');
skip_letter++; skip_letter++;
} }
else { else
{
/* silent */ /* silent */
} }
} }
else if( Next_Letter == 'N' ) { else if (Next_Letter == 'N')
{
if (Isbreak(After_Next_Letter) || if (Isbreak(After_Next_Letter) ||
(After_Next_Letter == 'E' && (After_Next_Letter == 'E' &&
Look_Ahead_Letter(3) == 'D' ) ) { Look_Ahead_Letter(3) == 'D'))
{
/* dropped */ /* dropped */
} }
else else
Phonize('K'); Phonize('K');
} }
else if (MAKESOFT(Next_Letter) && else if (MAKESOFT(Next_Letter) &&
Prev_Letter != 'G' ) { Prev_Letter != 'G')
Phonize('J'); Phonize('J');
} else
else {
Phonize('K'); Phonize('K');
}
break; break;
/* H if before a vowel and not after C,G,P,S,T */ /* H if before a vowel and not after C,G,P,S,T */
case 'H': case 'H':
@ -519,71 +548,73 @@ int _metaphone (
!AFFECTH(Prev_Letter)) !AFFECTH(Prev_Letter))
Phonize('H'); Phonize('H');
break; break;
/* dropped if after C
* else K /*
* dropped if after C else K
*/ */
case 'K': case 'K':
if (Prev_Letter != 'C') if (Prev_Letter != 'C')
Phonize('K'); Phonize('K');
break; break;
/* F if before H
* else P /*
* F if before H else P
*/ */
case 'P': case 'P':
if( Next_Letter == 'H' ) { if (Next_Letter == 'H')
Phonize('F'); Phonize('F');
} else
else {
Phonize('P'); Phonize('P');
}
break; break;
/* K
/*
* K
*/ */
case 'Q': case 'Q':
Phonize('K'); Phonize('K');
break; break;
/* 'sh' in -SH-, -SIO- or -SIA- or -SCHW-
* else S /*
* 'sh' in -SH-, -SIO- or -SIA- or -SCHW- else S
*/ */
case 'S': case 'S':
if (Next_Letter == 'I' && if (Next_Letter == 'I' &&
(After_Next_Letter == 'O' || (After_Next_Letter == 'O' ||
After_Next_Letter == 'A' ) ) { After_Next_Letter == 'A'))
Phonize(SH); Phonize(SH);
} else if (Next_Letter == 'H')
else if ( Next_Letter == 'H' ) { {
Phonize(SH); Phonize(SH);
skip_letter++; skip_letter++;
} }
#ifndef USE_TRADITIONAL_METAPHONE #ifndef USE_TRADITIONAL_METAPHONE
else if (Next_Letter == 'C' && else if (Next_Letter == 'C' &&
Look_Ahead_Letter(2) == 'H' && Look_Ahead_Letter(2) == 'H' &&
Look_Ahead_Letter(3) == 'W' ) { Look_Ahead_Letter(3) == 'W')
{
Phonize(SH); Phonize(SH);
skip_letter += 2; skip_letter += 2;
} }
#endif #endif
else { else
Phonize('S'); Phonize('S');
}
break; break;
/* 'sh' in -TIA- or -TIO-
* else 'th' before H /*
* else T * 'sh' in -TIA- or -TIO- else 'th' before H else T
*/ */
case 'T': case 'T':
if (Next_Letter == 'I' && if (Next_Letter == 'I' &&
(After_Next_Letter == 'O' || (After_Next_Letter == 'O' ||
After_Next_Letter == 'A' ) ) { After_Next_Letter == 'A'))
Phonize(SH); Phonize(SH);
} else if (Next_Letter == 'H')
else if ( Next_Letter == 'H' ) { {
Phonize(TH); Phonize(TH);
skip_letter++; skip_letter++;
} }
else { else
Phonize('T'); Phonize('T');
}
break; break;
/* F */ /* F */
case 'V': case 'V':

View File

@ -133,7 +133,8 @@ static const char *soundex_table = "01230120022455012623010202";
#define TH '0' #define TH '0'
char Lookahead(char *word, int how_far); char Lookahead(char *word, int how_far);
int _metaphone ( int
_metaphone(
/* IN */ /* IN */
char *word, char *word,
int max_phonemes, int max_phonemes,
@ -168,5 +169,4 @@ char _codes[26] = {
/* These prevent GH from becoming F */ /* These prevent GH from becoming F */
#define NOGHTOF(c) (ENCODE(c) & 16) /* BDH */ #define NOGHTOF(c) (ENCODE(c) & 16) /* BDH */
#endif /* FUZZYSTRMATCH_H */ #endif /* FUZZYSTRMATCH_H */

View File

@ -1,7 +1,7 @@
/* /*
* PostgreSQL type definitions for managed LargeObjects. * PostgreSQL type definitions for managed LargeObjects.
* *
* $Header: /cvsroot/pgsql/contrib/lo/lo.c,v 1.8 2001/03/22 03:59:09 momjian Exp $ * $Header: /cvsroot/pgsql/contrib/lo/lo.c,v 1.9 2001/10/25 05:49:19 momjian Exp $
* *
*/ */
@ -64,7 +64,6 @@ lo_in(char *str)
} }
else else
{ {
/* /*
* There is no Oid passed, so create a new one * There is no Oid passed, so create a new one
*/ */

View File

@ -6,5 +6,4 @@ int unlisten(char *relname);
int max(int x, int y); int max(int x, int y);
int min(int x, int y); int min(int x, int y);
int active_listeners(text *relname); int active_listeners(text *relname);
#endif #endif

View File

@ -6,7 +6,7 @@
* copyright (c) Oliver Elphick <olly@lfix.co.uk>, 2001; * copyright (c) Oliver Elphick <olly@lfix.co.uk>, 2001;
* licence: BSD * licence: BSD
* *
* $Header: /cvsroot/pgsql/contrib/pg_controldata/Attic/pg_controldata.c,v 1.4 2001/09/06 10:49:29 petere Exp $ * $Header: /cvsroot/pgsql/contrib/pg_controldata/Attic/pg_controldata.c,v 1.5 2001/10/25 05:49:19 momjian Exp $
*/ */
#include "postgres.h" #include "postgres.h"

View File

@ -1,7 +1,7 @@
/* ------------------------------------------------------------------------- /* -------------------------------------------------------------------------
* pg_dumplo * pg_dumplo
* *
* $Header: /cvsroot/pgsql/contrib/pg_dumplo/Attic/lo_export.c,v 1.7 2001/03/22 06:16:06 momjian Exp $ * $Header: /cvsroot/pgsql/contrib/pg_dumplo/Attic/lo_export.c,v 1.8 2001/10/25 05:49:19 momjian Exp $
* *
* Karel Zak 1999-2000 * Karel Zak 1999-2000
* ------------------------------------------------------------------------- * -------------------------------------------------------------------------
@ -38,8 +38,8 @@ load_lolist(LODumpMaster * pgLO)
* NOTE: System tables including pg_largeobject will be ignored. * NOTE: System tables including pg_largeobject will be ignored.
* Otherwise we'd end up dumping all LOs, referenced or not. * Otherwise we'd end up dumping all LOs, referenced or not.
* *
* NOTE: the system oid column is ignored, as it has attnum < 1. * NOTE: the system oid column is ignored, as it has attnum < 1. This
* This shouldn't matter for correctness, but it saves time. * shouldn't matter for correctness, but it saves time.
*/ */
pgLO->res = PQexec(pgLO->conn, pgLO->res = PQexec(pgLO->conn,
"SELECT c.relname, a.attname " "SELECT c.relname, a.attname "
@ -107,7 +107,6 @@ pglo_export(LODumpMaster * pgLO)
for (ll = pgLO->lolist; ll->lo_table != NULL; ll++) for (ll = pgLO->lolist; ll->lo_table != NULL; ll++)
{ {
/* /*
* Query: find the LOs referenced by this column * Query: find the LOs referenced by this column
*/ */

View File

@ -1,7 +1,7 @@
/* ------------------------------------------------------------------------- /* -------------------------------------------------------------------------
* pg_dumplo * pg_dumplo
* *
* $Header: /cvsroot/pgsql/contrib/pg_dumplo/Attic/lo_import.c,v 1.5 2001/03/22 06:16:06 momjian Exp $ * $Header: /cvsroot/pgsql/contrib/pg_dumplo/Attic/lo_import.c,v 1.6 2001/10/25 05:49:19 momjian Exp $
* *
* Karel Zak 1999-2000 * Karel Zak 1999-2000
* ------------------------------------------------------------------------- * -------------------------------------------------------------------------

View File

@ -1,7 +1,7 @@
/* ------------------------------------------------------------------------- /* -------------------------------------------------------------------------
* pg_dumplo * pg_dumplo
* *
* $Header: /cvsroot/pgsql/contrib/pg_dumplo/Attic/main.c,v 1.8 2001/03/22 06:16:06 momjian Exp $ * $Header: /cvsroot/pgsql/contrib/pg_dumplo/Attic/main.c,v 1.9 2001/10/25 05:49:19 momjian Exp $
* *
* Karel Zak 1999-2000 * Karel Zak 1999-2000
* ------------------------------------------------------------------------- * -------------------------------------------------------------------------
@ -304,7 +304,6 @@ usage()
"-q run quietly\n" "-q run quietly\n"
"-w not dump, but show all LO in DB\n" "-w not dump, but show all LO in DB\n"
); /* puts() */ ); /* puts() */
#endif #endif
puts( puts(

View File

@ -1,7 +1,7 @@
/* ------------------------------------------------------------------------- /* -------------------------------------------------------------------------
* pg_dumplo * pg_dumplo
* *
* $Header: /cvsroot/pgsql/contrib/pg_dumplo/Attic/pg_dumplo.h,v 1.4 2001/03/22 03:59:10 momjian Exp $ * $Header: /cvsroot/pgsql/contrib/pg_dumplo/Attic/pg_dumplo.h,v 1.5 2001/10/25 05:49:19 momjian Exp $
* *
* Karel Zak 1999-2000 * Karel Zak 1999-2000
* ------------------------------------------------------------------------- * -------------------------------------------------------------------------
@ -78,5 +78,4 @@ extern void index_file(LODumpMaster * pgLO);
extern void load_lolist(LODumpMaster * pgLO); extern void load_lolist(LODumpMaster * pgLO);
extern void pglo_export(LODumpMaster * pgLO); extern void pglo_export(LODumpMaster * pgLO);
extern void pglo_import(LODumpMaster * pgLO); extern void pglo_import(LODumpMaster * pgLO);
#endif /* PG_DUMPLO_H */ #endif /* PG_DUMPLO_H */

View File

@ -23,7 +23,7 @@
* Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group * Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California * Portions Copyright (c) 1994, Regents of the University of California
* *
* $Header: /cvsroot/pgsql/contrib/pg_resetxlog/Attic/pg_resetxlog.c,v 1.7 2001/10/25 00:55:48 momjian Exp $ * $Header: /cvsroot/pgsql/contrib/pg_resetxlog/Attic/pg_resetxlog.c,v 1.8 2001/10/25 05:49:19 momjian Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
@ -147,7 +147,6 @@ ReadControlFile(void)
if ((fd = open(ControlFilePath, O_RDONLY)) < 0) if ((fd = open(ControlFilePath, O_RDONLY)) < 0)
{ {
/* /*
* If pg_control is not there at all, or we can't read it, the * If pg_control is not there at all, or we can't read it, the
* odds are we've been handed a bad DataDir path, so give up. User * odds are we've been handed a bad DataDir path, so give up. User
@ -412,7 +411,6 @@ CheckControlVersion0(char *buffer, int len)
(char *) malloc(_INTL_MAXLOGRECSZ)); (char *) malloc(_INTL_MAXLOGRECSZ));
if (record == NULL) if (record == NULL)
{ {
/* /*
* We have to guess at the checkpoint contents. * We have to guess at the checkpoint contents.
*/ */
@ -617,7 +615,6 @@ GuessControlValues(void)
{ {
#ifdef USE_LOCALE #ifdef USE_LOCALE
char *localeptr; char *localeptr;
#endif #endif
/* /*

View File

@ -1,5 +1,5 @@
/* /*
* $Header: /cvsroot/pgsql/contrib/pgbench/pgbench.c,v 1.11 2001/10/24 08:07:22 ishii Exp $ * $Header: /cvsroot/pgsql/contrib/pgbench/pgbench.c,v 1.12 2001/10/25 05:49:19 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
@ -39,7 +39,6 @@
/* for getrlimit */ /* for getrlimit */
#include <sys/resource.h> #include <sys/resource.h>
#endif /* WIN32 */ #endif /* WIN32 */
/******************************************************************** /********************************************************************
@ -67,7 +66,8 @@ int tps = 1;
int remains; /* number of remained clients */ int remains; /* number of remained clients */
int is_connect; /* establish connection for each transactoin */ int is_connect; /* establish connection for each
* transactoin */
char *pghost = ""; char *pghost = "";
char *pgport = NULL; char *pgport = NULL;
@ -107,7 +107,8 @@ getrand(int min, int max)
} }
/* set up a connection to the backend */ /* set up a connection to the backend */
static PGconn *doConnect() static PGconn *
doConnect()
{ {
PGconn *con; PGconn *con;
@ -532,8 +533,8 @@ init()
if (j % 10000 == 0) if (j % 10000 == 0)
{ {
/* /*
* every 10000 tuples, we commit the copy command. * every 10000 tuples, we commit the copy command. this should
* this should avoid generating too much WAL logs * avoid generating too much WAL logs
*/ */
fprintf(stderr, "%d tuples done.\n", j); fprintf(stderr, "%d tuples done.\n", j);
if (PQputline(con, "\\.\n")) if (PQputline(con, "\\.\n"))
@ -547,6 +548,7 @@ init()
fprintf(stderr, "PQendcopy failed\n"); fprintf(stderr, "PQendcopy failed\n");
exit(1); exit(1);
} }
/* /*
* do a checkpoint to purge the old WAL logs * do a checkpoint to purge the old WAL logs
*/ */
@ -634,7 +636,6 @@ main(int argc, char **argv)
#ifndef __CYGWIN__ #ifndef __CYGWIN__
struct rlimit rlim; struct rlimit rlim;
#endif #endif
PGconn *con; PGconn *con;

View File

@ -71,14 +71,22 @@ Blowfish_encipher(blf_ctx *c, uint32 *x)
Xr = x[1]; Xr = x[1];
Xl ^= p[0]; Xl ^= p[0];
BLFRND(s, p, Xr, Xl, 1); BLFRND(s, p, Xl, Xr, 2); BLFRND(s, p, Xr, Xl, 1);
BLFRND(s, p, Xr, Xl, 3); BLFRND(s, p, Xl, Xr, 4); BLFRND(s, p, Xl, Xr, 2);
BLFRND(s, p, Xr, Xl, 5); BLFRND(s, p, Xl, Xr, 6); BLFRND(s, p, Xr, Xl, 3);
BLFRND(s, p, Xr, Xl, 7); BLFRND(s, p, Xl, Xr, 8); BLFRND(s, p, Xl, Xr, 4);
BLFRND(s, p, Xr, Xl, 9); BLFRND(s, p, Xl, Xr, 10); BLFRND(s, p, Xr, Xl, 5);
BLFRND(s, p, Xr, Xl, 11); BLFRND(s, p, Xl, Xr, 12); BLFRND(s, p, Xl, Xr, 6);
BLFRND(s, p, Xr, Xl, 13); BLFRND(s, p, Xl, Xr, 14); BLFRND(s, p, Xr, Xl, 7);
BLFRND(s, p, Xr, Xl, 15); BLFRND(s, p, Xl, Xr, 16); BLFRND(s, p, Xl, Xr, 8);
BLFRND(s, p, Xr, Xl, 9);
BLFRND(s, p, Xl, Xr, 10);
BLFRND(s, p, Xr, Xl, 11);
BLFRND(s, p, Xl, Xr, 12);
BLFRND(s, p, Xr, Xl, 13);
BLFRND(s, p, Xl, Xr, 14);
BLFRND(s, p, Xr, Xl, 15);
BLFRND(s, p, Xl, Xr, 16);
x[0] = Xr ^ p[17]; x[0] = Xr ^ p[17];
x[1] = Xl; x[1] = Xl;
@ -96,14 +104,22 @@ Blowfish_decipher(blf_ctx *c, uint32 *x)
Xr = x[1]; Xr = x[1];
Xl ^= p[17]; Xl ^= p[17];
BLFRND(s, p, Xr, Xl, 16); BLFRND(s, p, Xl, Xr, 15); BLFRND(s, p, Xr, Xl, 16);
BLFRND(s, p, Xr, Xl, 14); BLFRND(s, p, Xl, Xr, 13); BLFRND(s, p, Xl, Xr, 15);
BLFRND(s, p, Xr, Xl, 12); BLFRND(s, p, Xl, Xr, 11); BLFRND(s, p, Xr, Xl, 14);
BLFRND(s, p, Xr, Xl, 10); BLFRND(s, p, Xl, Xr, 9); BLFRND(s, p, Xl, Xr, 13);
BLFRND(s, p, Xr, Xl, 8); BLFRND(s, p, Xl, Xr, 7); BLFRND(s, p, Xr, Xl, 12);
BLFRND(s, p, Xr, Xl, 6); BLFRND(s, p, Xl, Xr, 5); BLFRND(s, p, Xl, Xr, 11);
BLFRND(s, p, Xr, Xl, 4); BLFRND(s, p, Xl, Xr, 3); BLFRND(s, p, Xr, Xl, 10);
BLFRND(s, p, Xr, Xl, 2); BLFRND(s, p, Xl, Xr, 1); BLFRND(s, p, Xl, Xr, 9);
BLFRND(s, p, Xr, Xl, 8);
BLFRND(s, p, Xl, Xr, 7);
BLFRND(s, p, Xr, Xl, 6);
BLFRND(s, p, Xl, Xr, 5);
BLFRND(s, p, Xr, Xl, 4);
BLFRND(s, p, Xl, Xr, 3);
BLFRND(s, p, Xr, Xl, 2);
BLFRND(s, p, Xl, Xr, 1);
x[0] = Xr ^ p[0]; x[0] = Xr ^ p[0];
x[1] = Xl; x[1] = Xl;
@ -401,7 +417,8 @@ Blowfish_stream2word(const uint8 *data, uint16 databytes, uint16 *current)
temp = 0x00000000; temp = 0x00000000;
j = *current; j = *current;
for (i = 0; i < 4; i++, j++) { for (i = 0; i < 4; i++, j++)
{
if (j >= databytes) if (j >= databytes)
j = 0; j = 0;
temp = (temp << 8) | data[j]; temp = (temp << 8) | data[j];
@ -421,7 +438,8 @@ Blowfish_expand0state(blf_ctx *c, const uint8 *key, uint16 keybytes)
uint32 data[2]; uint32 data[2];
j = 0; j = 0;
for (i = 0; i < BLF_N + 2; i++) { for (i = 0; i < BLF_N + 2; i++)
{
/* Extract 4 int8 to 1 int32 from keystream */ /* Extract 4 int8 to 1 int32 from keystream */
temp = Blowfish_stream2word(key, keybytes, &j); temp = Blowfish_stream2word(key, keybytes, &j);
c->P[i] = c->P[i] ^ temp; c->P[i] = c->P[i] ^ temp;
@ -430,15 +448,18 @@ Blowfish_expand0state(blf_ctx *c, const uint8 *key, uint16 keybytes)
j = 0; j = 0;
data[0] = 0x00000000; data[0] = 0x00000000;
data[1] = 0x00000000; data[1] = 0x00000000;
for (i = 0; i < BLF_N + 2; i += 2) { for (i = 0; i < BLF_N + 2; i += 2)
{
Blowfish_encipher(c, data); Blowfish_encipher(c, data);
c->P[i] = data[0]; c->P[i] = data[0];
c->P[i + 1] = data[1]; c->P[i + 1] = data[1];
} }
for (i = 0; i < 4; i++) { for (i = 0; i < 4; i++)
for (k = 0; k < 256; k += 2) { {
for (k = 0; k < 256; k += 2)
{
Blowfish_encipher(c, data); Blowfish_encipher(c, data);
c->S[i][k] = data[0]; c->S[i][k] = data[0];
@ -459,7 +480,8 @@ Blowfish_expandstate(blf_ctx *c, const uint8 *data, uint16 databytes,
uint32 d[2]; uint32 d[2];
j = 0; j = 0;
for (i = 0; i < BLF_N + 2; i++) { for (i = 0; i < BLF_N + 2; i++)
{
/* Extract 4 int8 to 1 int32 from keystream */ /* Extract 4 int8 to 1 int32 from keystream */
temp = Blowfish_stream2word(key, keybytes, &j); temp = Blowfish_stream2word(key, keybytes, &j);
c->P[i] = c->P[i] ^ temp; c->P[i] = c->P[i] ^ temp;
@ -468,7 +490,8 @@ Blowfish_expandstate(blf_ctx *c, const uint8 *data, uint16 databytes,
j = 0; j = 0;
d[0] = 0x00000000; d[0] = 0x00000000;
d[1] = 0x00000000; d[1] = 0x00000000;
for (i = 0; i < BLF_N + 2; i += 2) { for (i = 0; i < BLF_N + 2; i += 2)
{
d[0] ^= Blowfish_stream2word(data, databytes, &j); d[0] ^= Blowfish_stream2word(data, databytes, &j);
d[1] ^= Blowfish_stream2word(data, databytes, &j); d[1] ^= Blowfish_stream2word(data, databytes, &j);
Blowfish_encipher(c, d); Blowfish_encipher(c, d);
@ -477,8 +500,10 @@ Blowfish_expandstate(blf_ctx *c, const uint8 *data, uint16 databytes,
c->P[i + 1] = d[1]; c->P[i + 1] = d[1];
} }
for (i = 0; i < 4; i++) { for (i = 0; i < 4; i++)
for (k = 0; k < 256; k += 2) { {
for (k = 0; k < 256; k += 2)
{
d[0] ^= Blowfish_stream2word(data, databytes, &j); d[0] ^= Blowfish_stream2word(data, databytes, &j);
d[1] ^= Blowfish_stream2word(data, databytes, &j); d[1] ^= Blowfish_stream2word(data, databytes, &j);
Blowfish_encipher(c, d); Blowfish_encipher(c, d);
@ -507,7 +532,8 @@ blf_enc(blf_ctx *c, uint32 *data, uint16 blocks)
uint16 i; uint16 i;
d = data; d = data;
for (i = 0; i < blocks; i++) { for (i = 0; i < blocks; i++)
{
Blowfish_encipher(c, d); Blowfish_encipher(c, d);
d += 2; d += 2;
} }
@ -520,7 +546,8 @@ blf_dec(blf_ctx *c, uint32 *data, uint16 blocks)
uint16 i; uint16 i;
d = data; d = data;
for (i = 0; i < blocks; i++) { for (i = 0; i < blocks; i++)
{
Blowfish_decipher(c, d); Blowfish_decipher(c, d);
d += 2; d += 2;
} }
@ -529,10 +556,13 @@ blf_dec(blf_ctx *c, uint32 *data, uint16 blocks)
void void
blf_ecb_encrypt(blf_ctx * c, uint8 *data, uint32 len) blf_ecb_encrypt(blf_ctx * c, uint8 *data, uint32 len)
{ {
uint32 l, r, d[2]; uint32 l,
r,
d[2];
uint32 i; uint32 i;
for (i = 0; i < len; i += 8) { for (i = 0; i < len; i += 8)
{
l = data[0] << 24 | data[1] << 16 | data[2] << 8 | data[3]; l = data[0] << 24 | data[1] << 16 | data[2] << 8 | data[3];
r = data[4] << 24 | data[5] << 16 | data[6] << 8 | data[7]; r = data[4] << 24 | data[5] << 16 | data[6] << 8 | data[7];
d[0] = l; d[0] = l;
@ -555,10 +585,13 @@ blf_ecb_encrypt(blf_ctx *c, uint8 *data, uint32 len)
void void
blf_ecb_decrypt(blf_ctx * c, uint8 *data, uint32 len) blf_ecb_decrypt(blf_ctx * c, uint8 *data, uint32 len)
{ {
uint32 l, r, d[2]; uint32 l,
r,
d[2];
uint32 i; uint32 i;
for (i = 0; i < len; i += 8) { for (i = 0; i < len; i += 8)
{
l = data[0] << 24 | data[1] << 16 | data[2] << 8 | data[3]; l = data[0] << 24 | data[1] << 16 | data[2] << 8 | data[3];
r = data[4] << 24 | data[5] << 16 | data[6] << 8 | data[7]; r = data[4] << 24 | data[5] << 16 | data[6] << 8 | data[7];
d[0] = l; d[0] = l;
@ -581,10 +614,14 @@ blf_ecb_decrypt(blf_ctx *c, uint8 *data, uint32 len)
void void
blf_cbc_encrypt(blf_ctx * c, uint8 *iv, uint8 *data, uint32 len) blf_cbc_encrypt(blf_ctx * c, uint8 *iv, uint8 *data, uint32 len)
{ {
uint32 l, r, d[2]; uint32 l,
uint32 i, j; r,
d[2];
uint32 i,
j;
for (i = 0; i < len; i += 8) { for (i = 0; i < len; i += 8)
{
for (j = 0; j < 8; j++) for (j = 0; j < 8; j++)
data[j] ^= iv[j]; data[j] ^= iv[j];
l = data[0] << 24 | data[1] << 16 | data[2] << 8 | data[3]; l = data[0] << 24 | data[1] << 16 | data[2] << 8 | data[3];
@ -610,13 +647,17 @@ blf_cbc_encrypt(blf_ctx *c, uint8 *iv, uint8 *data, uint32 len)
void void
blf_cbc_decrypt(blf_ctx * c, uint8 *iva, uint8 *data, uint32 len) blf_cbc_decrypt(blf_ctx * c, uint8 *iva, uint8 *data, uint32 len)
{ {
uint32 l, r, d[2]; uint32 l,
r,
d[2];
uint8 *iv; uint8 *iv;
uint32 i, j; uint32 i,
j;
iv = data + len - 16; iv = data + len - 16;
data = data + len - 8; data = data + len - 8;
for (i = len - 8; i >= 8; i -= 8) { for (i = len - 8; i >= 8; i -= 8)
{
l = data[0] << 24 | data[1] << 16 | data[2] << 8 | data[3]; l = data[0] << 24 | data[1] << 16 | data[2] << 8 | data[3];
r = data[4] << 24 | data[5] << 16 | data[6] << 8 | data[7]; r = data[4] << 24 | data[5] << 16 | data[6] << 8 | data[7];
d[0] = l; d[0] = l;

View File

@ -46,7 +46,8 @@
#define BLF_MAXKEYLEN ((BLF_N-2)*4) /* 448 bits */ #define BLF_MAXKEYLEN ((BLF_N-2)*4) /* 448 bits */
/* Blowfish context */ /* Blowfish context */
typedef struct BlowfishContext { typedef struct BlowfishContext
{
uint32 S[4][256]; /* S-Boxes */ uint32 S[4][256]; /* S-Boxes */
uint32 P[BLF_N + 2]; /* Subkeys */ uint32 P[BLF_N + 2]; /* Subkeys */
} blf_ctx; } blf_ctx;
@ -78,5 +79,4 @@ void blf_ecb_decrypt (blf_ctx *, uint8 *, uint32);
void blf_cbc_encrypt(blf_ctx *, uint8 *, uint8 *, uint32); void blf_cbc_encrypt(blf_ctx *, uint8 *, uint8 *, uint32);
void blf_cbc_decrypt(blf_ctx *, uint8 *, uint8 *, uint32); void blf_cbc_decrypt(blf_ctx *, uint8 *, uint8 *, uint32);
#endif #endif

View File

@ -57,7 +57,8 @@ typedef unsigned int BF_word;
typedef BF_word BF_key[BF_N + 2]; typedef BF_word BF_key[BF_N + 2];
typedef struct { typedef struct
{
BF_word S[4][0x100]; BF_word S[4][0x100];
BF_key P; BF_key P;
} BF_ctx; } BF_ctx;
@ -367,22 +368,30 @@ do { \
(dst) = tmp; \ (dst) = tmp; \
} while (0) } while (0)
static int BF_decode(BF_word *dst, const char *src, int size) static int
BF_decode(BF_word * dst, const char *src, int size)
{ {
unsigned char *dptr = (unsigned char *) dst; unsigned char *dptr = (unsigned char *) dst;
unsigned char *end = dptr + size; unsigned char *end = dptr + size;
unsigned char *sptr = (unsigned char *) src; unsigned char *sptr = (unsigned char *) src;
unsigned int tmp, c1, c2, c3, c4; unsigned int tmp,
c1,
c2,
c3,
c4;
do { do
{
BF_safe_atoi64(c1, *sptr++); BF_safe_atoi64(c1, *sptr++);
BF_safe_atoi64(c2, *sptr++); BF_safe_atoi64(c2, *sptr++);
*dptr++ = (c1 << 2) | ((c2 & 0x30) >> 4); *dptr++ = (c1 << 2) | ((c2 & 0x30) >> 4);
if (dptr >= end) break; if (dptr >= end)
break;
BF_safe_atoi64(c3, *sptr++); BF_safe_atoi64(c3, *sptr++);
*dptr++ = ((c2 & 0x0F) << 4) | ((c3 & 0x3C) >> 2); *dptr++ = ((c2 & 0x0F) << 4) | ((c3 & 0x3C) >> 2);
if (dptr >= end) break; if (dptr >= end)
break;
BF_safe_atoi64(c4, *sptr++); BF_safe_atoi64(c4, *sptr++);
*dptr++ = ((c3 & 0x03) << 6) | c4; *dptr++ = ((c3 & 0x03) << 6) | c4;
@ -391,18 +400,22 @@ static int BF_decode(BF_word *dst, const char *src, int size)
return 0; return 0;
} }
static void BF_encode(char *dst, const BF_word *src, int size) static void
BF_encode(char *dst, const BF_word * src, int size)
{ {
unsigned char *sptr = (unsigned char *) src; unsigned char *sptr = (unsigned char *) src;
unsigned char *end = sptr + size; unsigned char *end = sptr + size;
unsigned char *dptr = (unsigned char *) dst; unsigned char *dptr = (unsigned char *) dst;
unsigned int c1, c2; unsigned int c1,
c2;
do { do
{
c1 = *sptr++; c1 = *sptr++;
*dptr++ = BF_itoa64[c1 >> 2]; *dptr++ = BF_itoa64[c1 >> 2];
c1 = (c1 & 0x03) << 4; c1 = (c1 & 0x03) << 4;
if (sptr >= end) { if (sptr >= end)
{
*dptr++ = BF_itoa64[c1]; *dptr++ = BF_itoa64[c1];
break; break;
} }
@ -411,7 +424,8 @@ static void BF_encode(char *dst, const BF_word *src, int size)
c1 |= c2 >> 4; c1 |= c2 >> 4;
*dptr++ = BF_itoa64[c1]; *dptr++ = BF_itoa64[c1];
c1 = (c2 & 0x0f) << 2; c1 = (c2 & 0x0f) << 2;
if (sptr >= end) { if (sptr >= end)
{
*dptr++ = BF_itoa64[c1]; *dptr++ = BF_itoa64[c1];
break; break;
} }
@ -423,14 +437,16 @@ static void BF_encode(char *dst, const BF_word *src, int size)
} while (sptr < end); } while (sptr < end);
} }
static void BF_swap(BF_word *x, int count) static void
BF_swap(BF_word * x, int count)
{ {
static int endianness_check = 1; static int endianness_check = 1;
char *is_little_endian = (char *) &endianness_check; char *is_little_endian = (char *) &endianness_check;
BF_word tmp; BF_word tmp;
if (*is_little_endian) if (*is_little_endian)
do { do
{
tmp = *x; tmp = *x;
tmp = (tmp << 16) | (tmp >> 16); tmp = (tmp << 16) | (tmp >> 16);
*x++ = ((tmp & 0x00FF00FF) << 8) | ((tmp >> 8) & 0x00FF00FF); *x++ = ((tmp & 0x00FF00FF) << 8) | ((tmp >> 8) & 0x00FF00FF);
@ -505,6 +521,7 @@ static void BF_swap(BF_word *x, int count)
#if BF_ASM #if BF_ASM
extern void _BF_body_r(BF_ctx * ctx); extern void _BF_body_r(BF_ctx * ctx);
#define BF_body() \ #define BF_body() \
_BF_body_r(&data.ctx); _BF_body_r(&data.ctx);
@ -527,22 +544,28 @@ extern void _BF_body_r(BF_ctx *ctx);
*(ptr - 2) = L; \ *(ptr - 2) = L; \
*(ptr - 1) = R; \ *(ptr - 1) = R; \
} while (ptr < &data.ctx.S[3][0xFF]); } while (ptr < &data.ctx.S[3][0xFF]);
#endif #endif
static void BF_set_key(const char *key, BF_key expanded, BF_key initial) static void
BF_set_key(const char *key, BF_key expanded, BF_key initial)
{ {
const char *ptr = key; const char *ptr = key;
int i, j; int i,
j;
BF_word tmp; BF_word tmp;
for (i = 0; i < BF_N + 2; i++) { for (i = 0; i < BF_N + 2; i++)
{
tmp = 0; tmp = 0;
for (j = 0; j < 4; j++) { for (j = 0; j < 4; j++)
{
tmp <<= 8; tmp <<= 8;
tmp |= *ptr; tmp |= *ptr;
if (!*ptr) ptr = key; else ptr++; if (!*ptr)
ptr = key;
else
ptr++;
} }
expanded[i] = tmp; expanded[i] = tmp;
@ -550,24 +573,32 @@ static void BF_set_key(const char *key, BF_key expanded, BF_key initial)
} }
} }
char *_crypt_blowfish_rn(const char *key, const char *setting, char *
_crypt_blowfish_rn(const char *key, const char *setting,
char *output, int size) char *output, int size)
{ {
struct { struct
{
BF_ctx ctx; BF_ctx ctx;
BF_key expanded_key; BF_key expanded_key;
union { union
{
BF_word salt[4]; BF_word salt[4];
BF_word output[6]; BF_word output[6];
} binary; } binary;
} data; } data;
BF_word L, R; BF_word L,
BF_word tmp1, tmp2, tmp3, tmp4; R;
BF_word tmp1,
tmp2,
tmp3,
tmp4;
BF_word *ptr; BF_word *ptr;
BF_word count; BF_word count;
int i; int i;
if (size < 7 + 22 + 31 + 1) { if (size < 7 + 22 + 31 + 1)
{
__set_errno(ERANGE); __set_errno(ERANGE);
return NULL; return NULL;
} }
@ -578,13 +609,15 @@ char *_crypt_blowfish_rn(const char *key, const char *setting,
setting[3] != '$' || setting[3] != '$' ||
setting[4] < '0' || setting[4] > '3' || setting[4] < '0' || setting[4] > '3' ||
setting[5] < '0' || setting[5] > '9' || setting[5] < '0' || setting[5] > '9' ||
setting[6] != '$') { setting[6] != '$')
{
__set_errno(EINVAL); __set_errno(EINVAL);
return NULL; return NULL;
} }
count = (BF_word) 1 << ((setting[4] - '0') * 10 + (setting[5] - '0')); count = (BF_word) 1 << ((setting[4] - '0') * 10 + (setting[5] - '0'));
if (count < 16 || BF_decode(data.binary.salt, &setting[7], 16)) { if (count < 16 || BF_decode(data.binary.salt, &setting[7], 16))
{
memset(data.binary.salt, 0, sizeof(data.binary.salt)); memset(data.binary.salt, 0, sizeof(data.binary.salt));
__set_errno(EINVAL); __set_errno(EINVAL);
return NULL; return NULL;
@ -596,7 +629,8 @@ char *_crypt_blowfish_rn(const char *key, const char *setting,
memcpy(data.ctx.S, BF_init_state.S, sizeof(data.ctx.S)); memcpy(data.ctx.S, BF_init_state.S, sizeof(data.ctx.S));
L = R = 0; L = R = 0;
for (i = 0; i < BF_N + 2; i += 2) { for (i = 0; i < BF_N + 2; i += 2)
{
L ^= data.binary.salt[i & 2]; L ^= data.binary.salt[i & 2];
R ^= data.binary.salt[(i & 2) + 1]; R ^= data.binary.salt[(i & 2) + 1];
BF_ENCRYPT; BF_ENCRYPT;
@ -605,7 +639,8 @@ char *_crypt_blowfish_rn(const char *key, const char *setting,
} }
ptr = data.ctx.S[0]; ptr = data.ctx.S[0];
do { do
{
ptr += 4; ptr += 4;
L ^= data.binary.salt[(BF_N + 2) & 3]; L ^= data.binary.salt[(BF_N + 2) & 3];
R ^= data.binary.salt[(BF_N + 3) & 3]; R ^= data.binary.salt[(BF_N + 3) & 3];
@ -620,7 +655,8 @@ char *_crypt_blowfish_rn(const char *key, const char *setting,
*(ptr - 1) = R; *(ptr - 1) = R;
} while (ptr < &data.ctx.S[3][0xFF]); } while (ptr < &data.ctx.S[3][0xFF]);
do { do
{
data.ctx.P[0] ^= data.expanded_key[0]; data.ctx.P[0] ^= data.expanded_key[0];
data.ctx.P[1] ^= data.expanded_key[1]; data.ctx.P[1] ^= data.expanded_key[1];
data.ctx.P[2] ^= data.expanded_key[2]; data.ctx.P[2] ^= data.expanded_key[2];
@ -668,12 +704,14 @@ char *_crypt_blowfish_rn(const char *key, const char *setting,
BF_body(); BF_body();
} while (--count); } while (--count);
for (i = 0; i < 6; i += 2) { for (i = 0; i < 6; i += 2)
{
L = BF_magic_w[i]; L = BF_magic_w[i];
R = BF_magic_w[i + 1]; R = BF_magic_w[i + 1];
count = 64; count = 64;
do { do
{
BF_ENCRYPT; BF_ENCRYPT;
} while (--count); } while (--count);
@ -698,4 +736,3 @@ char *_crypt_blowfish_rn(const char *key, const char *setting,
return output; return output;
} }

View File

@ -244,8 +244,8 @@ des_init()
} }
/* /*
* Convert the inverted S-boxes into 4 arrays of 8 bits. * Convert the inverted S-boxes into 4 arrays of 8 bits. Each will
* Each will handle 12 bits of the S-box input. * handle 12 bits of the S-box input.
*/ */
for (b = 0; b < 4; b++) for (b = 0; b < 4; b++)
for (i = 0; i < 64; i++) for (i = 0; i < 64; i++)
@ -409,10 +409,9 @@ des_setkey(const char *key)
&& rawkey1 == old_rawkey1) && rawkey1 == old_rawkey1)
{ {
/* /*
* Already setup for this key. * Already setup for this key. This optimisation fails on a zero
* This optimisation fails on a zero key (which is weak and * key (which is weak and has bad parity anyway) in order to
* has bad parity anyway) in order to simplify the starting * simplify the starting conditions.
* conditions.
*/ */
return (0); return (0);
} }
@ -438,6 +437,7 @@ des_setkey(const char *key)
| key_perm_maskr[5][(rawkey1 >> 17) & 0x7f] | key_perm_maskr[5][(rawkey1 >> 17) & 0x7f]
| key_perm_maskr[6][(rawkey1 >> 9) & 0x7f] | key_perm_maskr[6][(rawkey1 >> 9) & 0x7f]
| key_perm_maskr[7][(rawkey1 >> 1) & 0x7f]; | key_perm_maskr[7][(rawkey1 >> 1) & 0x7f];
/* /*
* Rotate subkeys and do compression permutation. * Rotate subkeys and do compression permutation.
*/ */
@ -556,21 +556,24 @@ do_des(uint32 l_in, uint32 r_in, uint32 * l_out, uint32 * r_out, int count)
| ((r & 0x000001f8) << 3) | ((r & 0x000001f8) << 3)
| ((r & 0x0000001f) << 1) | ((r & 0x0000001f) << 1)
| ((r & 0x80000000) >> 31); | ((r & 0x80000000) >> 31);
/* /*
* Do salting for crypt() and friends, and * Do salting for crypt() and friends, and XOR with the
* XOR with the permuted key. * permuted key.
*/ */
f = (r48l ^ r48r) & saltbits; f = (r48l ^ r48r) & saltbits;
r48l ^= f ^ *kl++; r48l ^= f ^ *kl++;
r48r ^= f ^ *kr++; r48r ^= f ^ *kr++;
/* /*
* Do sbox lookups (which shrink it back to 32 bits) * Do sbox lookups (which shrink it back to 32 bits) and do
* and do the pbox permutation at the same time. * the pbox permutation at the same time.
*/ */
f = psbox[0][m_sbox[0][r48l >> 12]] f = psbox[0][m_sbox[0][r48l >> 12]]
| psbox[1][m_sbox[1][r48l & 0xfff]] | psbox[1][m_sbox[1][r48l & 0xfff]]
| psbox[2][m_sbox[2][r48r >> 12]] | psbox[2][m_sbox[2][r48r >> 12]]
| psbox[3][m_sbox[3][r48r & 0xfff]]; | psbox[3][m_sbox[3][r48r & 0xfff]];
/* /*
* Now that we've permuted things, complete f(). * Now that we've permuted things, complete f().
*/ */
@ -581,6 +584,7 @@ do_des(uint32 l_in, uint32 r_in, uint32 * l_out, uint32 * r_out, int count)
r = l; r = l;
l = f; l = f;
} }
/* /*
* Do final permutation (inverse of IP). * Do final permutation (inverse of IP).
*/ */
@ -654,8 +658,8 @@ px_crypt_des(const char *key, const char *setting)
/* /*
* Copy the key, shifting each character up by one bit * Copy the key, shifting each character up by one bit and padding
* and padding with zeros. * with zeros.
*/ */
q = (uint8 *) keybuf; q = (uint8 *) keybuf;
while (q - (uint8 *) keybuf - 8) while (q - (uint8 *) keybuf - 8)
@ -670,9 +674,8 @@ px_crypt_des(const char *key, const char *setting)
if (*setting == _PASSWORD_EFMT1) if (*setting == _PASSWORD_EFMT1)
{ {
/* /*
* "new"-style: * "new"-style: setting - underscore, 4 bytes of count, 4 bytes of
* setting - underscore, 4 bytes of count, 4 bytes of salt * salt key - unlimited characters
* key - unlimited characters
*/ */
for (i = 1, count = 0L; i < 5; i++) for (i = 1, count = 0L; i < 5; i++)
count |= ascii_to_bin(setting[i]) << (i - 1) * 6; count |= ascii_to_bin(setting[i]) << (i - 1) * 6;
@ -687,6 +690,7 @@ px_crypt_des(const char *key, const char *setting)
*/ */
if (des_cipher((uint8 *) keybuf, (uint8 *) keybuf, 0L, 1)) if (des_cipher((uint8 *) keybuf, (uint8 *) keybuf, 0L, 1))
return (NULL); return (NULL);
/* /*
* And XOR with the next 8 characters of the key. * And XOR with the next 8 characters of the key.
*/ */
@ -700,11 +704,10 @@ px_crypt_des(const char *key, const char *setting)
strncpy(output, setting, 9); strncpy(output, setting, 9);
/* /*
* Double check that we weren't given a short setting. * Double check that we weren't given a short setting. If we were,
* If we were, the above code will probably have created * the above code will probably have created wierd values for
* wierd values for count and salt, but we don't really care. * count and salt, but we don't really care. Just make sure the
* Just make sure the output string doesn't have an extra * output string doesn't have an extra NUL in it.
* NUL in it.
*/ */
output[9] = '\0'; output[9] = '\0';
p = output + strlen(output); p = output + strlen(output);
@ -713,9 +716,7 @@ px_crypt_des(const char *key, const char *setting)
#endif /* !DISABLE_XDES */ #endif /* !DISABLE_XDES */
{ {
/* /*
* "old"-style: * "old"-style: setting - 2 bytes of salt key - up to 8 characters
* setting - 2 bytes of salt
* key - up to 8 characters
*/ */
count = 25; count = 25;
@ -723,22 +724,24 @@ px_crypt_des(const char *key, const char *setting)
| ascii_to_bin(setting[0]); | ascii_to_bin(setting[0]);
output[0] = setting[0]; output[0] = setting[0];
/* /*
* If the encrypted password that the salt was extracted from * If the encrypted password that the salt was extracted from is
* is only 1 character long, the salt will be corrupted. We * only 1 character long, the salt will be corrupted. We need to
* need to ensure that the output string doesn't have an extra * ensure that the output string doesn't have an extra NUL in it!
* NUL in it!
*/ */
output[1] = setting[1] ? setting[1] : output[0]; output[1] = setting[1] ? setting[1] : output[0];
p = output + 2; p = output + 2;
} }
setup_salt(salt); setup_salt(salt);
/* /*
* Do it. * Do it.
*/ */
if (do_des(0L, 0L, &r0, &r1, count)) if (do_des(0L, 0L, &r0, &r1, count))
return (NULL); return (NULL);
/* /*
* Now encode the result... * Now encode the result...
*/ */

View File

@ -24,11 +24,14 @@ typedef unsigned int BF_word;
unsigned char _crypt_itoa64[64 + 1] = unsigned char _crypt_itoa64[64 + 1] =
"./0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"; "./0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
char *_crypt_gensalt_traditional_rn(unsigned long count, char *
_crypt_gensalt_traditional_rn(unsigned long count,
const char *input, int size, char *output, int output_size) const char *input, int size, char *output, int output_size)
{ {
if (size < 2 || output_size < 2 + 1 || (count && count != 25)) { if (size < 2 || output_size < 2 + 1 || (count && count != 25))
if (output_size > 0) output[0] = '\0'; {
if (output_size > 0)
output[0] = '\0';
__set_errno((output_size < 2 + 1) ? ERANGE : EINVAL); __set_errno((output_size < 2 + 1) ? ERANGE : EINVAL);
return NULL; return NULL;
} }
@ -40,7 +43,8 @@ char *_crypt_gensalt_traditional_rn(unsigned long count,
return output; return output;
} }
char *_crypt_gensalt_extended_rn(unsigned long count, char *
_crypt_gensalt_extended_rn(unsigned long count,
const char *input, int size, char *output, int output_size) const char *input, int size, char *output, int output_size)
{ {
unsigned long value; unsigned long value;
@ -48,13 +52,16 @@ char *_crypt_gensalt_extended_rn(unsigned long count,
/* Even iteration counts make it easier to detect weak DES keys from a look /* Even iteration counts make it easier to detect weak DES keys from a look
* at the hash, so they should be avoided */ * at the hash, so they should be avoided */
if (size < 3 || output_size < 1 + 4 + 4 + 1 || if (size < 3 || output_size < 1 + 4 + 4 + 1 ||
(count && (count > 0xffffff || !(count & 1)))) { (count && (count > 0xffffff || !(count & 1))))
if (output_size > 0) output[0] = '\0'; {
if (output_size > 0)
output[0] = '\0';
__set_errno((output_size < 1 + 4 + 4 + 1) ? ERANGE : EINVAL); __set_errno((output_size < 1 + 4 + 4 + 1) ? ERANGE : EINVAL);
return NULL; return NULL;
} }
if (!count) count = 725; if (!count)
count = 725;
output[0] = '_'; output[0] = '_';
output[1] = _crypt_itoa64[count & 0x3f]; output[1] = _crypt_itoa64[count & 0x3f];
@ -73,13 +80,16 @@ char *_crypt_gensalt_extended_rn(unsigned long count,
return output; return output;
} }
char *_crypt_gensalt_md5_rn(unsigned long count, char *
_crypt_gensalt_md5_rn(unsigned long count,
const char *input, int size, char *output, int output_size) const char *input, int size, char *output, int output_size)
{ {
unsigned long value; unsigned long value;
if (size < 3 || output_size < 3 + 4 + 1 || (count && count != 1000)) { if (size < 3 || output_size < 3 + 4 + 1 || (count && count != 1000))
if (output_size > 0) output[0] = '\0'; {
if (output_size > 0)
output[0] = '\0';
__set_errno((output_size < 3 + 4 + 1) ? ERANGE : EINVAL); __set_errno((output_size < 3 + 4 + 1) ? ERANGE : EINVAL);
return NULL; return NULL;
} }
@ -96,7 +106,8 @@ char *_crypt_gensalt_md5_rn(unsigned long count,
output[6] = _crypt_itoa64[(value >> 18) & 0x3f]; output[6] = _crypt_itoa64[(value >> 18) & 0x3f];
output[7] = '\0'; output[7] = '\0';
if (size >= 6 && output_size >= 3 + 4 + 4 + 1) { if (size >= 6 && output_size >= 3 + 4 + 4 + 1)
{
value = (unsigned long) input[3] | value = (unsigned long) input[3] |
((unsigned long) input[4] << 8) | ((unsigned long) input[4] << 8) |
((unsigned long) input[5] << 16); ((unsigned long) input[5] << 16);
@ -115,18 +126,22 @@ char *_crypt_gensalt_md5_rn(unsigned long count,
static unsigned char BF_itoa64[64 + 1] = static unsigned char BF_itoa64[64 + 1] =
"./ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"; "./ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
static void BF_encode(char *dst, const BF_word *src, int size) static void
BF_encode(char *dst, const BF_word * src, int size)
{ {
unsigned char *sptr = (unsigned char *) src; unsigned char *sptr = (unsigned char *) src;
unsigned char *end = sptr + size; unsigned char *end = sptr + size;
unsigned char *dptr = (unsigned char *) dst; unsigned char *dptr = (unsigned char *) dst;
unsigned int c1, c2; unsigned int c1,
c2;
do { do
{
c1 = *sptr++; c1 = *sptr++;
*dptr++ = BF_itoa64[c1 >> 2]; *dptr++ = BF_itoa64[c1 >> 2];
c1 = (c1 & 0x03) << 4; c1 = (c1 & 0x03) << 4;
if (sptr >= end) { if (sptr >= end)
{
*dptr++ = BF_itoa64[c1]; *dptr++ = BF_itoa64[c1];
break; break;
} }
@ -135,7 +150,8 @@ static void BF_encode(char *dst, const BF_word *src, int size)
c1 |= c2 >> 4; c1 |= c2 >> 4;
*dptr++ = BF_itoa64[c1]; *dptr++ = BF_itoa64[c1];
c1 = (c2 & 0x0f) << 2; c1 = (c2 & 0x0f) << 2;
if (sptr >= end) { if (sptr >= end)
{
*dptr++ = BF_itoa64[c1]; *dptr++ = BF_itoa64[c1];
break; break;
} }
@ -147,17 +163,21 @@ static void BF_encode(char *dst, const BF_word *src, int size)
} while (sptr < end); } while (sptr < end);
} }
char *_crypt_gensalt_blowfish_rn(unsigned long count, char *
_crypt_gensalt_blowfish_rn(unsigned long count,
const char *input, int size, char *output, int output_size) const char *input, int size, char *output, int output_size)
{ {
if (size < 16 || output_size < 7 + 22 + 1 || if (size < 16 || output_size < 7 + 22 + 1 ||
(count && (count < 4 || count > 31))) { (count && (count < 4 || count > 31)))
if (output_size > 0) output[0] = '\0'; {
if (output_size > 0)
output[0] = '\0';
__set_errno((output_size < 7 + 22 + 1) ? ERANGE : EINVAL); __set_errno((output_size < 7 + 22 + 1) ? ERANGE : EINVAL);
return NULL; return NULL;
} }
if (!count) count = 5; if (!count)
count = 5;
output[0] = '$'; output[0] = '$';
output[1] = '2'; output[1] = '2';
@ -172,4 +192,3 @@ char *_crypt_gensalt_blowfish_rn(unsigned long count,
return output; return output;
} }

View File

@ -9,7 +9,7 @@
* $FreeBSD: src/lib/libcrypt/crypt-md5.c,v 1.5 1999/12/17 20:21:45 peter Exp $ * $FreeBSD: src/lib/libcrypt/crypt-md5.c,v 1.5 1999/12/17 20:21:45 peter Exp $
* *
*/ */
/* $Id: crypt-md5.c,v 1.1 2001/08/21 01:32:01 momjian Exp $ */ /* $Id: crypt-md5.c,v 1.2 2001/10/25 05:49:19 momjian Exp $ */
#include <postgres.h> #include <postgres.h>
#include "px.h" #include "px.h"
@ -23,12 +23,9 @@
char * char *
px_crypt_md5(const char *pw, const char *salt, char *passwd, unsigned dstlen) px_crypt_md5(const char *pw, const char *salt, char *passwd, unsigned dstlen)
{ {
static char *magic = "$1$"; /* static char *magic = "$1$"; /* This string is magic for this
* This string is magic for * algorithm. Having it this way, we can
* this algorithm. Having * get get better later on */
* it this way, we can get
* get better later on
*/
static char *p; static char *p;
static const char *sp, static const char *sp,
*ep; *ep;
@ -99,9 +96,9 @@ px_crypt_md5(const char *pw, const char *salt, char *passwd, unsigned dstlen)
px_md_finish(ctx, final); px_md_finish(ctx, final);
/* /*
* and now, just to make sure things don't run too fast * and now, just to make sure things don't run too fast On a 60 Mhz
* On a 60 Mhz Pentium this takes 34 msec, so you would * Pentium this takes 34 msec, so you would need 30 seconds to build a
* need 30 seconds to build a 1000 entry dictionary... * 1000 entry dictionary...
*/ */
for (i = 0; i < 1000; i++) for (i = 0; i < 1000; i++)
{ {

View File

@ -26,7 +26,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE. * SUCH DAMAGE.
* *
* $Id: internal.c,v 1.5 2001/10/15 19:12:48 tgl Exp $ * $Id: internal.c,v 1.6 2001/10/25 05:49:19 momjian Exp $
*/ */
@ -62,10 +62,17 @@ static struct int_digest
char *name; char *name;
void (*init) (PX_MD * h); void (*init) (PX_MD * h);
} int_digest_list[] = } int_digest_list[] =
{ {
{ "md5", init_md5 }, {
{ "sha1", init_sha1 }, "md5", init_md5
{ NULL, NULL } },
{
"sha1", init_sha1
},
{
NULL, NULL
}
}; };
/* MD5 */ /* MD5 */
@ -209,10 +216,12 @@ init_sha1(PX_MD * md)
#define INT_MAX_KEY (512/8) #define INT_MAX_KEY (512/8)
#define INT_MAX_IV (128/8) #define INT_MAX_IV (128/8)
struct int_ctx { struct int_ctx
{
uint8 keybuf[INT_MAX_KEY]; uint8 keybuf[INT_MAX_KEY];
uint8 iv[INT_MAX_IV]; uint8 iv[INT_MAX_IV];
union { union
{
blf_ctx bf; blf_ctx bf;
rijndael_ctx rj; rijndael_ctx rj;
} ctx; } ctx;
@ -221,10 +230,13 @@ struct int_ctx {
int mode; int mode;
}; };
static void intctx_free(PX_Cipher *c) static void
intctx_free(PX_Cipher * c)
{ {
struct int_ctx *cx = (struct int_ctx *) c->ptr; struct int_ctx *cx = (struct int_ctx *) c->ptr;
if (cx) {
if (cx)
{
memset(cx, 0, sizeof *cx); memset(cx, 0, sizeof *cx);
px_free(cx); px_free(cx);
} }
@ -238,22 +250,26 @@ static void intctx_free(PX_Cipher *c)
#define MODE_ECB 0 #define MODE_ECB 0
#define MODE_CBC 1 #define MODE_CBC 1
static uint rj_block_size(PX_Cipher *c) static uint
rj_block_size(PX_Cipher * c)
{ {
return 128 / 8; return 128 / 8;
} }
static uint rj_key_size(PX_Cipher *c) static uint
rj_key_size(PX_Cipher * c)
{ {
return 256 / 8; return 256 / 8;
} }
static uint rj_iv_size(PX_Cipher *c) static uint
rj_iv_size(PX_Cipher * c)
{ {
return 128 / 8; return 128 / 8;
} }
static int rj_init(PX_Cipher *c, const uint8 *key, uint klen, const uint8 *iv) static int
rj_init(PX_Cipher * c, const uint8 *key, uint klen, const uint8 *iv)
{ {
struct int_ctx *cx = (struct int_ctx *) c->ptr; struct int_ctx *cx = (struct int_ctx *) c->ptr;
@ -274,17 +290,20 @@ static int rj_init(PX_Cipher *c, const uint8 *key, uint klen, const uint8 *iv)
return 0; return 0;
} }
static int rj_real_init(struct int_ctx *cx, int dir) static int
rj_real_init(struct int_ctx * cx, int dir)
{ {
aes_set_key(&cx->ctx.rj, cx->keybuf, cx->keylen * 8, dir); aes_set_key(&cx->ctx.rj, cx->keybuf, cx->keylen * 8, dir);
return 0; return 0;
} }
static int rj_encrypt(PX_Cipher *c, const uint8 *data, uint dlen, uint8 *res) static int
rj_encrypt(PX_Cipher * c, const uint8 *data, uint dlen, uint8 *res)
{ {
struct int_ctx *cx = (struct int_ctx *) c->ptr; struct int_ctx *cx = (struct int_ctx *) c->ptr;
if (!cx->is_init) { if (!cx->is_init)
{
if (rj_real_init(cx, 1)) if (rj_real_init(cx, 1))
return -1; return -1;
} }
@ -297,16 +316,19 @@ static int rj_encrypt(PX_Cipher *c, const uint8 *data, uint dlen, uint8 *res)
memcpy(res, data, dlen); memcpy(res, data, dlen);
if (cx->mode == MODE_CBC) { if (cx->mode == MODE_CBC)
{
aes_cbc_encrypt(&cx->ctx.rj, cx->iv, res, dlen); aes_cbc_encrypt(&cx->ctx.rj, cx->iv, res, dlen);
memcpy(cx->iv, res + dlen - 16, 16); memcpy(cx->iv, res + dlen - 16, 16);
} else }
else
aes_ecb_encrypt(&cx->ctx.rj, res, dlen); aes_ecb_encrypt(&cx->ctx.rj, res, dlen);
return 0; return 0;
} }
static int rj_decrypt(PX_Cipher *c, const uint8 *data, uint dlen, uint8 *res) static int
rj_decrypt(PX_Cipher * c, const uint8 *data, uint dlen, uint8 *res)
{ {
struct int_ctx *cx = (struct int_ctx *) c->ptr; struct int_ctx *cx = (struct int_ctx *) c->ptr;
@ -322,10 +344,12 @@ static int rj_decrypt(PX_Cipher *c, const uint8 *data, uint dlen, uint8 *res)
memcpy(res, data, dlen); memcpy(res, data, dlen);
if (cx->mode == MODE_CBC) { if (cx->mode == MODE_CBC)
{
aes_cbc_decrypt(&cx->ctx.rj, cx->iv, res, dlen); aes_cbc_decrypt(&cx->ctx.rj, cx->iv, res, dlen);
memcpy(cx->iv, data + dlen - 16, 16); memcpy(cx->iv, data + dlen - 16, 16);
} else }
else
aes_ecb_decrypt(&cx->ctx.rj, res, dlen); aes_ecb_decrypt(&cx->ctx.rj, res, dlen);
return 0; return 0;
@ -335,7 +359,8 @@ static int rj_decrypt(PX_Cipher *c, const uint8 *data, uint dlen, uint8 *res)
* initializers * initializers
*/ */
static PX_Cipher * rj_load(int mode) static PX_Cipher *
rj_load(int mode)
{ {
PX_Cipher *c; PX_Cipher *c;
struct int_ctx *cx; struct int_ctx *cx;
@ -363,22 +388,26 @@ static PX_Cipher * rj_load(int mode)
* blowfish * blowfish
*/ */
static uint bf_block_size(PX_Cipher *c) static uint
bf_block_size(PX_Cipher * c)
{ {
return 8; return 8;
} }
static uint bf_key_size(PX_Cipher *c) static uint
bf_key_size(PX_Cipher * c)
{ {
return BLF_MAXKEYLEN; return BLF_MAXKEYLEN;
} }
static uint bf_iv_size(PX_Cipher *c) static uint
bf_iv_size(PX_Cipher * c)
{ {
return 8; return 8;
} }
static int bf_init(PX_Cipher *c, const uint8 *key, uint klen, const uint8 *iv) static int
bf_init(PX_Cipher * c, const uint8 *key, uint klen, const uint8 *iv)
{ {
struct int_ctx *cx = (struct int_ctx *) c->ptr; struct int_ctx *cx = (struct int_ctx *) c->ptr;
@ -389,7 +418,8 @@ static int bf_init(PX_Cipher *c, const uint8 *key, uint klen, const uint8 *iv)
return 0; return 0;
} }
static int bf_encrypt(PX_Cipher *c, const uint8 *data, uint dlen, uint8 *res) static int
bf_encrypt(PX_Cipher * c, const uint8 *data, uint dlen, uint8 *res)
{ {
struct int_ctx *cx = (struct int_ctx *) c->ptr; struct int_ctx *cx = (struct int_ctx *) c->ptr;
@ -400,7 +430,8 @@ static int bf_encrypt(PX_Cipher *c, const uint8 *data, uint dlen, uint8 *res)
return -1; return -1;
memcpy(res, data, dlen); memcpy(res, data, dlen);
switch (cx->mode) { switch (cx->mode)
{
case MODE_ECB: case MODE_ECB:
blf_ecb_encrypt(&cx->ctx.bf, res, dlen); blf_ecb_encrypt(&cx->ctx.bf, res, dlen);
break; break;
@ -411,7 +442,8 @@ static int bf_encrypt(PX_Cipher *c, const uint8 *data, uint dlen, uint8 *res)
return 0; return 0;
} }
static int bf_decrypt(PX_Cipher *c, const uint8 *data, uint dlen, uint8 *res) static int
bf_decrypt(PX_Cipher * c, const uint8 *data, uint dlen, uint8 *res)
{ {
struct int_ctx *cx = (struct int_ctx *) c->ptr; struct int_ctx *cx = (struct int_ctx *) c->ptr;
@ -422,7 +454,8 @@ static int bf_decrypt(PX_Cipher *c, const uint8 *data, uint dlen, uint8 *res)
return -1; return -1;
memcpy(res, data, dlen); memcpy(res, data, dlen);
switch (cx->mode) { switch (cx->mode)
{
case MODE_ECB: case MODE_ECB:
blf_ecb_decrypt(&cx->ctx.bf, res, dlen); blf_ecb_decrypt(&cx->ctx.bf, res, dlen);
break; break;
@ -433,7 +466,8 @@ static int bf_decrypt(PX_Cipher *c, const uint8 *data, uint dlen, uint8 *res)
return 0; return 0;
} }
static PX_Cipher * bf_load(int mode) static PX_Cipher *
bf_load(int mode)
{ {
PX_Cipher *c; PX_Cipher *c;
struct int_ctx *cx; struct int_ctx *cx;
@ -458,35 +492,52 @@ static PX_Cipher * bf_load(int mode)
/* ciphers */ /* ciphers */
static PX_Cipher * rj_128_ecb() static PX_Cipher *
rj_128_ecb()
{ {
return rj_load(MODE_ECB); return rj_load(MODE_ECB);
} }
static PX_Cipher * rj_128_cbc() static PX_Cipher *
rj_128_cbc()
{ {
return rj_load(MODE_CBC); return rj_load(MODE_CBC);
} }
static PX_Cipher * bf_ecb_load() static PX_Cipher *
bf_ecb_load()
{ {
return bf_load(MODE_ECB); return bf_load(MODE_ECB);
} }
static PX_Cipher * bf_cbc_load() static PX_Cipher *
bf_cbc_load()
{ {
return bf_load(MODE_CBC); return bf_load(MODE_CBC);
} }
static struct { static struct
{
char *name; char *name;
PX_Cipher *(*load) (void); PX_Cipher *(*load) (void);
} int_ciphers [] = { } int_ciphers[] =
{ "bf-cbc", bf_cbc_load },
{ "bf-ecb", bf_ecb_load }, {
{ "aes-128-cbc", rj_128_cbc }, {
{ "aes-128-ecb", rj_128_ecb }, "bf-cbc", bf_cbc_load
{ NULL, NULL } },
{
"bf-ecb", bf_ecb_load
},
{
"aes-128-cbc", rj_128_cbc
},
{
"aes-128-ecb", rj_128_ecb
},
{
NULL, NULL
}
}; };
static PX_Alias int_aliases[] = { static PX_Alias int_aliases[] = {
@ -531,7 +582,8 @@ px_find_cipher(const char *name, PX_Cipher **res)
name = px_resolve_alias(int_aliases, name); name = px_resolve_alias(int_aliases, name);
for (i = 0; int_ciphers[i].name; i++) for (i = 0; int_ciphers[i].name; i++)
if (!strcmp(int_ciphers[i].name, name)) { if (!strcmp(int_ciphers[i].name, name))
{
c = int_ciphers[i].load(); c = int_ciphers[i].load();
break; break;
} }
@ -542,5 +594,3 @@ px_find_cipher(const char *name, PX_Cipher **res)
*res = c; *res = c;
return 0; return 0;
} }

View File

@ -1,4 +1,4 @@
/* $Id: md5.c,v 1.7 2001/10/25 01:29:37 momjian Exp $ */ /* $Id: md5.c,v 1.8 2001/10/25 05:49:19 momjian Exp $ */
/* $KAME: md5.c,v 1.3 2000/02/22 14:01:17 itojun Exp $ */ /* $KAME: md5.c,v 1.3 2000/02/22 14:01:17 itojun Exp $ */
/* /*

View File

@ -26,7 +26,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE. * SUCH DAMAGE.
* *
* $Id: mhash.c,v 1.4 2001/08/21 00:42:41 momjian Exp $ * $Id: mhash.c,v 1.5 2001/10/25 05:49:19 momjian Exp $
*/ */
#include <postgres.h> #include <postgres.h>
@ -114,6 +114,7 @@ static uint
cipher_block_size(PX_Cipher * c) cipher_block_size(PX_Cipher * c)
{ {
MCRYPT ctx = (MCRYPT) c->ptr; MCRYPT ctx = (MCRYPT) c->ptr;
return mcrypt_enc_get_block_size(ctx); return mcrypt_enc_get_block_size(ctx);
} }
@ -121,6 +122,7 @@ static uint
cipher_key_size(PX_Cipher * c) cipher_key_size(PX_Cipher * c)
{ {
MCRYPT ctx = (MCRYPT) c->ptr; MCRYPT ctx = (MCRYPT) c->ptr;
return mcrypt_enc_get_key_size(ctx); return mcrypt_enc_get_key_size(ctx);
} }
@ -128,6 +130,7 @@ static uint
cipher_iv_size(PX_Cipher * c) cipher_iv_size(PX_Cipher * c)
{ {
MCRYPT ctx = (MCRYPT) c->ptr; MCRYPT ctx = (MCRYPT) c->ptr;
return mcrypt_enc_mode_has_iv(ctx) return mcrypt_enc_mode_has_iv(ctx)
? mcrypt_enc_get_iv_size(ctx) : 0; ? mcrypt_enc_get_iv_size(ctx) : 0;
} }
@ -246,7 +249,8 @@ static PX_Alias mode_aliases[] = {
{NULL, NULL} {NULL, NULL}
}; };
static int is_mode(char *s) static int
is_mode(char *s)
{ {
char **p; char **p;
@ -301,8 +305,10 @@ px_find_cipher(const char *name, PX_Cipher **res)
strcpy(nbuf, name); strcpy(nbuf, name);
if ((p = strrchr(nbuf, '-')) != NULL) { if ((p = strrchr(nbuf, '-')) != NULL)
if (is_mode(p + 1)) { {
if (is_mode(p + 1))
{
mode = p + 1; mode = p + 1;
*p = 0; *p = 0;
} }
@ -310,13 +316,13 @@ px_find_cipher(const char *name, PX_Cipher **res)
name = px_resolve_alias(aliases, nbuf); name = px_resolve_alias(aliases, nbuf);
if (!mode) { if (!mode)
{
mode = "cbc"; mode = "cbc";
/* /*
if (mcrypt_module_is_block_algorithm(name, NULL)) * if (mcrypt_module_is_block_algorithm(name, NULL)) mode = "cbc";
mode = "cbc"; * else mode = "stream";
else
mode = "stream";
*/ */
} }
mode = px_resolve_alias(mode_aliases, mode); mode = px_resolve_alias(mode_aliases, mode);
@ -339,4 +345,3 @@ px_find_cipher(const char *name, PX_Cipher **res)
*res = c; *res = c;
return 0; return 0;
} }

View File

@ -26,7 +26,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE. * SUCH DAMAGE.
* *
* $Id: openssl.c,v 1.5 2001/09/23 04:12:44 momjian Exp $ * $Id: openssl.c,v 1.6 2001/10/25 05:49:19 momjian Exp $
*/ */
#include <postgres.h> #include <postgres.h>
@ -94,9 +94,12 @@ digest_free(PX_MD * h)
*/ */
typedef struct { typedef struct
union { {
struct { union
{
struct
{
BF_KEY key; BF_KEY key;
int num; int num;
} bf; } bf;
@ -115,6 +118,7 @@ static uint
gen_evp_block_size(PX_Cipher * c) gen_evp_block_size(PX_Cipher * c)
{ {
ossldata *od = (ossldata *) c->ptr; ossldata *od = (ossldata *) c->ptr;
return EVP_CIPHER_block_size(od->evp_ciph); return EVP_CIPHER_block_size(od->evp_ciph);
} }
@ -122,6 +126,7 @@ static uint
gen_evp_key_size(PX_Cipher * c) gen_evp_key_size(PX_Cipher * c)
{ {
ossldata *od = (ossldata *) c->ptr; ossldata *od = (ossldata *) c->ptr;
return EVP_CIPHER_key_length(od->evp_ciph); return EVP_CIPHER_key_length(od->evp_ciph);
} }
@ -130,6 +135,7 @@ gen_evp_iv_size(PX_Cipher *c)
{ {
uint ivlen; uint ivlen;
ossldata *od = (ossldata *) c->ptr; ossldata *od = (ossldata *) c->ptr;
ivlen = EVP_CIPHER_iv_length(od->evp_ciph); ivlen = EVP_CIPHER_iv_length(od->evp_ciph);
return ivlen; return ivlen;
} }
@ -138,6 +144,7 @@ static void
gen_evp_free(PX_Cipher * c) gen_evp_free(PX_Cipher * c)
{ {
ossldata *od = (ossldata *) c->ptr; ossldata *od = (ossldata *) c->ptr;
memset(od, 0, sizeof(*od)); memset(od, 0, sizeof(*od));
pfree(od); pfree(od);
pfree(c); pfree(c);
@ -150,9 +157,10 @@ gen_evp_init(PX_Cipher *c, const uint8 *key, uint klen, const uint8 *iv)
{ {
ossldata *od = (ossldata *) c->ptr; ossldata *od = (ossldata *) c->ptr;
uint bs = gen_evp_block_size(c); uint bs = gen_evp_block_size(c);
if (iv) {
if (iv)
memcpy(od->iv, iv, bs); memcpy(od->iv, iv, bs);
} else else
memset(od->iv, 0, bs); memset(od->iv, 0, bs);
memcpy(od->key, key, klen); memcpy(od->key, key, klen);
od->klen = klen; od->klen = klen;
@ -174,6 +182,7 @@ static int
gen_evp_encrypt(PX_Cipher * c, const uint8 *data, uint dlen, uint8 *res) gen_evp_encrypt(PX_Cipher * c, const uint8 *data, uint dlen, uint8 *res)
{ {
ossldata *od = c->ptr; ossldata *od = c->ptr;
if (!od->init) if (!od->init)
_gen_init(c, 1); _gen_init(c, 1);
od->evp_ciph->do_cipher(&od->u.evp_ctx, res, data, dlen); od->evp_ciph->do_cipher(&od->u.evp_ctx, res, data, dlen);
@ -184,6 +193,7 @@ static int
gen_evp_decrypt(PX_Cipher * c, const uint8 *data, uint dlen, uint8 *res) gen_evp_decrypt(PX_Cipher * c, const uint8 *data, uint dlen, uint8 *res)
{ {
ossldata *od = c->ptr; ossldata *od = c->ptr;
if (!od->init) if (!od->init)
_gen_init(c, 0); _gen_init(c, 0);
od->evp_ciph->do_cipher(&od->u.evp_ctx, res, data, dlen); od->evp_ciph->do_cipher(&od->u.evp_ctx, res, data, dlen);
@ -196,10 +206,11 @@ static int
bf_init(PX_Cipher * c, const uint8 *key, uint klen, const uint8 *iv) bf_init(PX_Cipher * c, const uint8 *key, uint klen, const uint8 *iv)
{ {
ossldata *od = c->ptr; ossldata *od = c->ptr;
BF_set_key(&od->u.bf.key, klen, key); BF_set_key(&od->u.bf.key, klen, key);
if (iv) { if (iv)
memcpy(od->iv, iv, BF_BLOCK); memcpy(od->iv, iv, BF_BLOCK);
} else else
memset(od->iv, 0, BF_BLOCK); memset(od->iv, 0, BF_BLOCK);
od->u.bf.num = 0; od->u.bf.num = 0;
return 0; return 0;
@ -208,8 +219,10 @@ bf_init(PX_Cipher *c, const uint8 *key, uint klen, const uint8 *iv)
static int static int
bf_ecb_encrypt(PX_Cipher * c, const uint8 *data, uint dlen, uint8 *res) bf_ecb_encrypt(PX_Cipher * c, const uint8 *data, uint dlen, uint8 *res)
{ {
uint bs = gen_evp_block_size(c), i; uint bs = gen_evp_block_size(c),
i;
ossldata *od = c->ptr; ossldata *od = c->ptr;
for (i = 0; i < dlen / bs; i++) for (i = 0; i < dlen / bs; i++)
BF_ecb_encrypt(data + i * bs, res + i * bs, &od->u.bf.key, BF_ENCRYPT); BF_ecb_encrypt(data + i * bs, res + i * bs, &od->u.bf.key, BF_ENCRYPT);
return 0; return 0;
@ -218,8 +231,10 @@ bf_ecb_encrypt(PX_Cipher *c, const uint8 *data, uint dlen, uint8 *res)
static int static int
bf_ecb_decrypt(PX_Cipher * c, const uint8 *data, uint dlen, uint8 *res) bf_ecb_decrypt(PX_Cipher * c, const uint8 *data, uint dlen, uint8 *res)
{ {
uint bs = gen_evp_block_size(c), i; uint bs = gen_evp_block_size(c),
i;
ossldata *od = c->ptr; ossldata *od = c->ptr;
for (i = 0; i < dlen / bs; i++) for (i = 0; i < dlen / bs; i++)
BF_ecb_encrypt(data + i * bs, res + i * bs, &od->u.bf.key, BF_DECRYPT); BF_ecb_encrypt(data + i * bs, res + i * bs, &od->u.bf.key, BF_DECRYPT);
return 0; return 0;
@ -229,6 +244,7 @@ static int
bf_cbc_encrypt(PX_Cipher * c, const uint8 *data, uint dlen, uint8 *res) bf_cbc_encrypt(PX_Cipher * c, const uint8 *data, uint dlen, uint8 *res)
{ {
ossldata *od = c->ptr; ossldata *od = c->ptr;
BF_cbc_encrypt(data, res, dlen, &od->u.bf.key, od->iv, BF_ENCRYPT); BF_cbc_encrypt(data, res, dlen, &od->u.bf.key, od->iv, BF_ENCRYPT);
return 0; return 0;
} }
@ -237,6 +253,7 @@ static int
bf_cbc_decrypt(PX_Cipher * c, const uint8 *data, uint dlen, uint8 *res) bf_cbc_decrypt(PX_Cipher * c, const uint8 *data, uint dlen, uint8 *res)
{ {
ossldata *od = c->ptr; ossldata *od = c->ptr;
BF_cbc_encrypt(data, res, dlen, &od->u.bf.key, od->iv, BF_DECRYPT); BF_cbc_encrypt(data, res, dlen, &od->u.bf.key, od->iv, BF_DECRYPT);
return 0; return 0;
} }
@ -245,6 +262,7 @@ static int
bf_cfb64_encrypt(PX_Cipher * c, const uint8 *data, uint dlen, uint8 *res) bf_cfb64_encrypt(PX_Cipher * c, const uint8 *data, uint dlen, uint8 *res)
{ {
ossldata *od = c->ptr; ossldata *od = c->ptr;
BF_cfb64_encrypt(data, res, dlen, &od->u.bf.key, od->iv, BF_cfb64_encrypt(data, res, dlen, &od->u.bf.key, od->iv,
&od->u.bf.num, BF_ENCRYPT); &od->u.bf.num, BF_ENCRYPT);
return 0; return 0;
@ -254,6 +272,7 @@ static int
bf_cfb64_decrypt(PX_Cipher * c, const uint8 *data, uint dlen, uint8 *res) bf_cfb64_decrypt(PX_Cipher * c, const uint8 *data, uint dlen, uint8 *res)
{ {
ossldata *od = c->ptr; ossldata *od = c->ptr;
BF_cfb64_encrypt(data, res, dlen, &od->u.bf.key, od->iv, BF_cfb64_encrypt(data, res, dlen, &od->u.bf.key, od->iv,
&od->u.bf.num, BF_DECRYPT); &od->u.bf.num, BF_DECRYPT);
return 0; return 0;
@ -263,6 +282,7 @@ static int
bf_ofb64_encrypt(PX_Cipher * c, const uint8 *data, uint dlen, uint8 *res) bf_ofb64_encrypt(PX_Cipher * c, const uint8 *data, uint dlen, uint8 *res)
{ {
ossldata *od = c->ptr; ossldata *od = c->ptr;
BF_ofb64_encrypt(data, res, dlen, &od->u.bf.key, od->iv, &od->u.bf.num); BF_ofb64_encrypt(data, res, dlen, &od->u.bf.key, od->iv, &od->u.bf.num);
return 0; return 0;
} }
@ -271,6 +291,7 @@ static int
bf_ofb64_decrypt(PX_Cipher * c, const uint8 *data, uint dlen, uint8 *res) bf_ofb64_decrypt(PX_Cipher * c, const uint8 *data, uint dlen, uint8 *res)
{ {
ossldata *od = c->ptr; ossldata *od = c->ptr;
BF_ofb64_encrypt(data, res, dlen, &od->u.bf.key, od->iv, &od->u.bf.num); BF_ofb64_encrypt(data, res, dlen, &od->u.bf.key, od->iv, &od->u.bf.num);
return 0; return 0;
} }
@ -299,19 +320,44 @@ static PX_Alias ossl_mode_aliases [] = {
/* /*
* Special handlers * Special handlers
*/ */
struct { struct
{
char *name; char *name;
PX_Cipher cf; PX_Cipher cf;
} spec_types [] = { } spec_types[] =
{ "bf-cbc", { gen_evp_block_size, gen_evp_key_size, gen_evp_iv_size,
bf_init, bf_cbc_encrypt, bf_cbc_decrypt, gen_evp_free}}, {
{ "bf-ecb", { gen_evp_block_size, gen_evp_key_size, gen_evp_iv_size, {
bf_init, bf_ecb_encrypt, bf_ecb_decrypt, gen_evp_free}}, "bf-cbc",
{ "bf-cfb", { gen_evp_block_size, gen_evp_key_size, gen_evp_iv_size, {
bf_init, bf_cfb64_encrypt, bf_cfb64_decrypt, gen_evp_free}}, gen_evp_block_size, gen_evp_key_size, gen_evp_iv_size,
{ "bf-ofb", { gen_evp_block_size, gen_evp_key_size, gen_evp_iv_size, bf_init, bf_cbc_encrypt, bf_cbc_decrypt, gen_evp_free
bf_init, bf_ofb64_encrypt, bf_ofb64_decrypt, gen_evp_free}}, }
{ NULL } },
{
"bf-ecb",
{
gen_evp_block_size, gen_evp_key_size, gen_evp_iv_size,
bf_init, bf_ecb_encrypt, bf_ecb_decrypt, gen_evp_free
}
},
{
"bf-cfb",
{
gen_evp_block_size, gen_evp_key_size, gen_evp_iv_size,
bf_init, bf_cfb64_encrypt, bf_cfb64_decrypt, gen_evp_free
}
},
{
"bf-ofb",
{
gen_evp_block_size, gen_evp_key_size, gen_evp_iv_size,
bf_init, bf_ofb64_encrypt, bf_ofb64_decrypt, gen_evp_free
}
},
{
NULL
}
}; };
/* /*
@ -371,12 +417,14 @@ int
px_find_cipher(const char *name, PX_Cipher ** res) px_find_cipher(const char *name, PX_Cipher ** res)
{ {
uint i; uint i;
PX_Cipher *c = NULL, *csrc; PX_Cipher *c = NULL,
*csrc;
ossldata *od; ossldata *od;
const EVP_CIPHER *evp_c; const EVP_CIPHER *evp_c;
if (!px_openssl_initialized) { if (!px_openssl_initialized)
{
px_openssl_initialized = 1; px_openssl_initialized = 1;
/* CRYPTO_set_mem_functions(o_alloc, o_realloc, o_free); */ /* CRYPTO_set_mem_functions(o_alloc, o_realloc, o_free); */
OpenSSL_add_all_algorithms(); OpenSSL_add_all_algorithms();
@ -394,7 +442,8 @@ px_find_cipher(const char *name, PX_Cipher **res)
csrc = NULL; csrc = NULL;
for (i = 0; spec_types[i].name; i++) for (i = 0; spec_types[i].name; i++)
if (!strcmp(name, spec_types[i].name)) { if (!strcmp(name, spec_types[i].name))
{
csrc = &spec_types[i].cf; csrc = &spec_types[i].cf;
break; break;
} }
@ -409,4 +458,3 @@ px_find_cipher(const char *name, PX_Cipher **res)
*res = c; *res = c;
return 0; return 0;
} }

View File

@ -26,7 +26,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE. * SUCH DAMAGE.
* *
* $Id: pgcrypto.c,v 1.9 2001/09/23 04:12:44 momjian Exp $ * $Id: pgcrypto.c,v 1.10 2001/10/25 05:49:19 momjian Exp $
*/ */
#include <postgres.h> #include <postgres.h>
@ -314,10 +314,14 @@ Datum
pg_encrypt(PG_FUNCTION_ARGS) pg_encrypt(PG_FUNCTION_ARGS)
{ {
int err; int err;
bytea *data, *key, *res; bytea *data,
*key,
*res;
text *type; text *type;
PX_Combo *c; PX_Combo *c;
uint dlen, klen, rlen; uint dlen,
klen,
rlen;
if (PG_ARGISNULL(0) || PG_ARGISNULL(1) || PG_ARGISNULL(2)) if (PG_ARGISNULL(0) || PG_ARGISNULL(1) || PG_ARGISNULL(2))
PG_RETURN_NULL(); PG_RETURN_NULL();
@ -342,7 +346,8 @@ pg_encrypt(PG_FUNCTION_ARGS)
PG_FREE_IF_COPY(key, 1); PG_FREE_IF_COPY(key, 1);
PG_FREE_IF_COPY(type, 2); PG_FREE_IF_COPY(type, 2);
if (err) { if (err)
{
pfree(res); pfree(res);
elog(ERROR, "encrypt error: %d", err); elog(ERROR, "encrypt error: %d", err);
} }
@ -358,10 +363,14 @@ Datum
pg_decrypt(PG_FUNCTION_ARGS) pg_decrypt(PG_FUNCTION_ARGS)
{ {
int err; int err;
bytea *data, *key, *res; bytea *data,
*key,
*res;
text *type; text *type;
PX_Combo *c; PX_Combo *c;
uint dlen, klen, rlen; uint dlen,
klen,
rlen;
if (PG_ARGISNULL(0) || PG_ARGISNULL(1) || PG_ARGISNULL(2)) if (PG_ARGISNULL(0) || PG_ARGISNULL(1) || PG_ARGISNULL(2))
PG_RETURN_NULL(); PG_RETURN_NULL();
@ -402,10 +411,16 @@ Datum
pg_encrypt_iv(PG_FUNCTION_ARGS) pg_encrypt_iv(PG_FUNCTION_ARGS)
{ {
int err; int err;
bytea *data, *key, *iv, *res; bytea *data,
*key,
*iv,
*res;
text *type; text *type;
PX_Combo *c; PX_Combo *c;
uint dlen, klen, ivlen, rlen; uint dlen,
klen,
ivlen,
rlen;
if (PG_ARGISNULL(0) || PG_ARGISNULL(1) if (PG_ARGISNULL(0) || PG_ARGISNULL(1)
|| PG_ARGISNULL(2) || PG_ARGISNULL(3)) || PG_ARGISNULL(2) || PG_ARGISNULL(3))
@ -450,10 +465,16 @@ Datum
pg_decrypt_iv(PG_FUNCTION_ARGS) pg_decrypt_iv(PG_FUNCTION_ARGS)
{ {
int err; int err;
bytea *data, *key, *iv, *res; bytea *data,
*key,
*iv,
*res;
text *type; text *type;
PX_Combo *c; PX_Combo *c;
uint dlen, klen, rlen, ivlen; uint dlen,
klen,
rlen,
ivlen;
if (PG_ARGISNULL(0) || PG_ARGISNULL(1) if (PG_ARGISNULL(0) || PG_ARGISNULL(1)
|| PG_ARGISNULL(2) || PG_ARGISNULL(3)) || PG_ARGISNULL(2) || PG_ARGISNULL(3))

View File

@ -26,7 +26,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE. * SUCH DAMAGE.
* *
* $Id: pgcrypto.h,v 1.5 2001/09/23 04:12:44 momjian Exp $ * $Id: pgcrypto.h,v 1.6 2001/10/25 05:49:20 momjian Exp $
*/ */
#ifndef _PG_CRYPTO_H #ifndef _PG_CRYPTO_H
@ -45,6 +45,4 @@ Datum pg_decrypt(PG_FUNCTION_ARGS);
Datum pg_encrypt_iv(PG_FUNCTION_ARGS); Datum pg_encrypt_iv(PG_FUNCTION_ARGS);
Datum pg_decrypt_iv(PG_FUNCTION_ARGS); Datum pg_decrypt_iv(PG_FUNCTION_ARGS);
Datum pg_cipher_exists(PG_FUNCTION_ARGS); Datum pg_cipher_exists(PG_FUNCTION_ARGS);
#endif #endif

View File

@ -26,7 +26,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE. * SUCH DAMAGE.
* *
* $Id: px-crypt.c,v 1.2 2001/09/23 04:12:44 momjian Exp $ * $Id: px-crypt.c,v 1.3 2001/10/25 05:49:20 momjian Exp $
*/ */
#include <postgres.h> #include <postgres.h>
@ -54,6 +54,7 @@ run_crypt_md5(const char *psw, const char *salt,
char *buf, unsigned len) char *buf, unsigned len)
{ {
char *res; char *res;
res = px_crypt_md5(psw, salt, buf, len); res = px_crypt_md5(psw, salt, buf, len);
return res; return res;
} }
@ -63,6 +64,7 @@ run_crypt_bf(const char *psw, const char *salt,
char *buf, unsigned len) char *buf, unsigned len)
{ {
char *res; char *res;
res = _crypt_blowfish_rn(psw, salt, buf, len); res = _crypt_blowfish_rn(psw, salt, buf, len);
return res; return res;
} }
@ -76,12 +78,24 @@ static struct
} px_crypt_list[] = } px_crypt_list[] =
{ {
{ "$2a$", 4, run_crypt_bf }, {
{ "$2$", 3, NULL }, /* N/A */ "$2a$", 4, run_crypt_bf
{ "$1$", 3, run_crypt_md5 }, },
{ "_", 1, run_crypt_des }, {
{ "", 0, run_crypt_des }, "$2$", 3, NULL
{ NULL, 0, NULL } }, /* N/A */
{
"$1$", 3, run_crypt_md5
},
{
"_", 1, run_crypt_des
},
{
"", 0, run_crypt_des
},
{
NULL, 0, NULL
}
}; };
char * char *
@ -125,7 +139,8 @@ px_crypt(const char *psw, const char *salt,
* salt generators * salt generators
*/ */
struct generator { struct generator
{
char *name; char *name;
char *(*gen) (unsigned long count, const char *input, int size, char *(*gen) (unsigned long count, const char *input, int size,
char *output, int output_size); char *output, int output_size);
@ -146,17 +161,20 @@ static struct generator gen_list [] = {
uint uint
px_gen_salt(const char *salt_type, char *buf, int rounds) px_gen_salt(const char *salt_type, char *buf, int rounds)
{ {
int i, res; int i,
res;
struct generator *g; struct generator *g;
char *p; char *p;
char rbuf[16]; char rbuf[16];
for (i = 0; gen_list[i].name; i++) { for (i = 0; gen_list[i].name; i++)
{
g = &gen_list[i]; g = &gen_list[i];
if (strcasecmp(g->name, salt_type) != 0) if (strcasecmp(g->name, salt_type) != 0)
continue; continue;
if (g->def_rounds) { if (g->def_rounds)
{
if (rounds == 0) if (rounds == 0)
rounds = g->def_rounds; rounds = g->def_rounds;
@ -176,4 +194,3 @@ px_gen_salt(const char *salt_type, char *buf, int rounds)
return 0; return 0;
} }

View File

@ -26,7 +26,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE. * SUCH DAMAGE.
* *
* $Id: px-crypt.h,v 1.2 2001/09/23 04:12:44 momjian Exp $ * $Id: px-crypt.h,v 1.3 2001/10/25 05:49:20 momjian Exp $
*/ */
#ifndef _PX_CRYPT_H #ifndef _PX_CRYPT_H
@ -58,6 +58,7 @@ unsigned px_gen_salt(const char *salt_type, char *dst, int rounds);
/* misc.c */ /* misc.c */
extern void px_crypt_to64(char *s, unsigned long v, int n); extern void px_crypt_to64(char *s, unsigned long v, int n);
extern char px_crypt_a64[]; extern char px_crypt_a64[];
/* avoid conflicts with system libs */ /* avoid conflicts with system libs */
#define _crypt_to64 px_crypt_to64 #define _crypt_to64 px_crypt_to64
#define _crypt_a64 px_crypt_a64 #define _crypt_a64 px_crypt_a64
@ -87,6 +88,5 @@ char *px_crypt_des(const char *key, const char *setting);
/* crypt-md5.c */ /* crypt-md5.c */
char *px_crypt_md5(const char *pw, const char *salt, char *px_crypt_md5(const char *pw, const char *salt,
char *dst, unsigned dstlen); char *dst, unsigned dstlen);
#endif /* !PX_SYSTEM_CRYPT */ #endif /* !PX_SYSTEM_CRYPT */
#endif /* _PX_CRYPT_H */ #endif /* _PX_CRYPT_H */

View File

@ -26,7 +26,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE. * SUCH DAMAGE.
* *
* $Id: px-hmac.c,v 1.1 2001/08/21 01:32:01 momjian Exp $ * $Id: px-hmac.c,v 1.2 2001/10/25 05:49:20 momjian Exp $
*/ */

View File

@ -26,7 +26,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE. * SUCH DAMAGE.
* *
* $Id: px.c,v 1.2 2001/09/06 03:21:39 momjian Exp $ * $Id: px.c,v 1.3 2001/10/25 05:49:20 momjian Exp $
*/ */
#include <postgres.h> #include <postgres.h>
@ -37,7 +37,8 @@
const char * const char *
px_resolve_alias(const PX_Alias * list, const char *name) px_resolve_alias(const PX_Alias * list, const char *name)
{ {
while (list->name) { while (list->name)
{
if (!strcasecmp(list->alias, name)) if (!strcasecmp(list->alias, name))
return list->name; return list->name;
list++; list++;
@ -66,7 +67,9 @@ combo_init(PX_Combo *cx, const uint8 *key, uint klen,
const uint8 *iv, uint ivlen) const uint8 *iv, uint ivlen)
{ {
int err; int err;
uint bs, ks, ivs; uint bs,
ks,
ivs;
PX_Cipher *c = cx->cipher; PX_Cipher *c = cx->cipher;
uint8 *ivbuf = NULL; uint8 *ivbuf = NULL;
uint8 *keybuf; uint8 *keybuf;
@ -75,7 +78,8 @@ combo_init(PX_Combo *cx, const uint8 *key, uint klen,
ks = px_cipher_key_size(c); ks = px_cipher_key_size(c);
ivs = px_cipher_iv_size(c); ivs = px_cipher_iv_size(c);
if (ivs > 0) { if (ivs > 0)
{
ivbuf = px_alloc(ivs); ivbuf = px_alloc(ivs);
memset(ivbuf, 0, ivs); memset(ivbuf, 0, ivs);
if (ivlen > ivs) if (ivlen > ivs)
@ -102,7 +106,11 @@ combo_encrypt(PX_Combo *cx, const uint8 *data, uint dlen,
{ {
int err = 0; int err = 0;
uint8 *bbuf; uint8 *bbuf;
uint bs, maxlen, bpos, i, pad; uint bs,
maxlen,
bpos,
i,
pad;
PX_Cipher *c = cx->cipher; PX_Cipher *c = cx->cipher;
@ -111,25 +119,30 @@ combo_encrypt(PX_Combo *cx, const uint8 *data, uint dlen,
bs = px_cipher_block_size(c); bs = px_cipher_block_size(c);
/* encrypt */ /* encrypt */
if (bs > 1) { if (bs > 1)
{
bbuf = px_alloc(bs * 4); bbuf = px_alloc(bs * 4);
bpos = dlen % bs; bpos = dlen % bs;
*rlen = dlen - bpos; *rlen = dlen - bpos;
memcpy(bbuf, data + *rlen, bpos); memcpy(bbuf, data + *rlen, bpos);
/* encrypt full-block data */ /* encrypt full-block data */
if (*rlen) { if (*rlen)
{
err = px_cipher_encrypt(c, data, *rlen, res); err = px_cipher_encrypt(c, data, *rlen, res);
if (err) if (err)
goto out; goto out;
} }
/* bbuf has now bpos bytes of stuff */ /* bbuf has now bpos bytes of stuff */
if (cx->padding) { if (cx->padding)
{
pad = bs - (bpos % bs); pad = bs - (bpos % bs);
for (i = 0; i < pad; i++) for (i = 0; i < pad; i++)
bbuf[bpos++] = pad; bbuf[bpos++] = pad;
} else if (bpos % bs) { }
else if (bpos % bs)
{
/* ERROR? */ /* ERROR? */
pad = bs - (bpos % bs); pad = bs - (bpos % bs);
for (i = 0; i < pad; i++) for (i = 0; i < pad; i++)
@ -137,11 +150,14 @@ combo_encrypt(PX_Combo *cx, const uint8 *data, uint dlen,
} }
/* encrypt the rest - pad */ /* encrypt the rest - pad */
if (bpos) { if (bpos)
{
err = px_cipher_encrypt(c, bbuf, bpos, res + *rlen); err = px_cipher_encrypt(c, bbuf, bpos, res + *rlen);
*rlen += bpos; *rlen += bpos;
} }
} else { }
else
{
/* stream cipher/mode - no pad needed */ /* stream cipher/mode - no pad needed */
err = px_cipher_encrypt(c, data, dlen, res); err = px_cipher_encrypt(c, data, dlen, res);
if (err) if (err)
@ -149,7 +165,8 @@ combo_encrypt(PX_Combo *cx, const uint8 *data, uint dlen,
*rlen = dlen; *rlen = dlen;
} }
out: out:
if (bbuf) px_free(bbuf); if (bbuf)
px_free(bbuf);
return err; return err;
} }
@ -158,28 +175,32 @@ static int
combo_decrypt(PX_Combo * cx, const uint8 *data, uint dlen, combo_decrypt(PX_Combo * cx, const uint8 *data, uint dlen,
uint8 *res, uint *rlen) uint8 *res, uint *rlen)
{ {
uint bs, i, pad; uint bs,
i,
pad;
uint pad_ok; uint pad_ok;
PX_Cipher *c = cx->cipher; PX_Cipher *c = cx->cipher;
bs = px_cipher_block_size(c); bs = px_cipher_block_size(c);
if (bs > 1 && (dlen % bs) != 0) { if (bs > 1 && (dlen % bs) != 0)
goto block_error; goto block_error;
}
/* decrypt */ /* decrypt */
*rlen = dlen; *rlen = dlen;
px_cipher_decrypt(c, data, dlen, res); px_cipher_decrypt(c, data, dlen, res);
/* unpad */ /* unpad */
if (bs > 1 && cx->padding) { if (bs > 1 && cx->padding)
{
pad = res[*rlen - 1]; pad = res[*rlen - 1];
pad_ok = 0; pad_ok = 0;
if (pad > 0 && pad <= bs && pad <= *rlen) { if (pad > 0 && pad <= bs && pad <= *rlen)
{
pad_ok = 1; pad_ok = 1;
for (i = *rlen - pad; i < *rlen; i++) for (i = *rlen - pad; i < *rlen; i++)
if (res[i] != pad) { if (res[i] != pad)
{
pad_ok = 0; pad_ok = 0;
break; break;
} }
@ -211,29 +232,36 @@ combo_free(PX_Combo *cx)
static int static int
parse_cipher_name(char *full, char **cipher, char **pad) parse_cipher_name(char *full, char **cipher, char **pad)
{ {
char *p, *p2, *q; char *p,
*p2,
*q;
*cipher = full; *cipher = full;
*pad = NULL; *pad = NULL;
p = strchr(full, '/'); p = strchr(full, '/');
if (p != NULL) if (p != NULL)
*p++ = 0; *p++ = 0;
while (p != NULL) { while (p != NULL)
{
if ((q = strchr(p, '/')) != NULL) if ((q = strchr(p, '/')) != NULL)
*q++ = 0; *q++ = 0;
if (!*p) { if (!*p)
{
p = q; p = q;
continue; continue;
} }
p2 = strchr(p, ':'); p2 = strchr(p, ':');
if (p2 != NULL) { if (p2 != NULL)
{
*p2++ = 0; *p2++ = 0;
if (!strcmp(p, "pad")) if (!strcmp(p, "pad"))
*pad = p2; *pad = p2;
else else
return -1; return -1;
} else }
else
return -1; return -1;
p = q; p = q;
@ -247,7 +275,9 @@ int
px_find_combo(const char *name, PX_Combo ** res) px_find_combo(const char *name, PX_Combo ** res)
{ {
int err; int err;
char *buf, *s_cipher, *s_pad; char *buf,
*s_cipher,
*s_pad;
PX_Combo *cx; PX_Combo *cx;
@ -258,7 +288,8 @@ px_find_combo(const char *name, PX_Combo **res)
strcpy(buf, name); strcpy(buf, name);
err = parse_cipher_name(buf, &s_cipher, &s_pad); err = parse_cipher_name(buf, &s_cipher, &s_pad);
if (err) { if (err)
{
px_free(buf); px_free(buf);
px_free(cx); px_free(cx);
return err; return err;
@ -268,14 +299,16 @@ px_find_combo(const char *name, PX_Combo **res)
if (err) if (err)
goto err1; goto err1;
if (s_pad != NULL) { if (s_pad != NULL)
{
if (!strcmp(s_pad, "pkcs")) if (!strcmp(s_pad, "pkcs"))
cx->padding = 1; cx->padding = 1;
else if (!strcmp(s_pad, "none")) else if (!strcmp(s_pad, "none"))
cx->padding = 0; cx->padding = 0;
else else
goto err1; goto err1;
} else }
else
cx->padding = 1; cx->padding = 1;
cx->init = combo_init; cx->init = combo_init;
@ -298,4 +331,3 @@ err1:
px_free(buf); px_free(buf);
return -1; return -1;
} }

View File

@ -26,7 +26,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE. * SUCH DAMAGE.
* *
* $Id: px.h,v 1.2 2001/09/23 04:12:44 momjian Exp $ * $Id: px.h,v 1.3 2001/10/25 05:49:20 momjian Exp $
*/ */
#ifndef __PX_H #ifndef __PX_H
@ -47,7 +47,6 @@ void xfree(void *p);
#define px_alloc(s) xalloc(s) #define px_alloc(s) xalloc(s)
#define px_realloc(p, s) xrealloc(p, s) #define px_realloc(p, s) xrealloc(p, s)
#define px_free(p) xfree(p) #define px_free(p) xfree(p)
#endif #endif
/* max len of 'type' parms */ /* max len of 'type' parms */
@ -63,7 +62,8 @@ typedef struct px_hmac PX_HMAC;
typedef struct px_cipher PX_Cipher; typedef struct px_cipher PX_Cipher;
typedef struct px_combo PX_Combo; typedef struct px_combo PX_Combo;
struct px_digest { struct px_digest
{
uint (*result_size) (PX_MD * h); uint (*result_size) (PX_MD * h);
uint (*block_size) (PX_MD * h); uint (*block_size) (PX_MD * h);
void (*reset) (PX_MD * h); void (*reset) (PX_MD * h);
@ -71,18 +71,21 @@ struct px_digest {
void (*finish) (PX_MD * h, uint8 *dst); void (*finish) (PX_MD * h, uint8 *dst);
void (*free) (PX_MD * h); void (*free) (PX_MD * h);
/* private */ /* private */
union { union
{
uint code; uint code;
const void *ptr; const void *ptr;
} p; } p;
}; };
struct px_alias { struct px_alias
{
char *alias; char *alias;
char *name; char *name;
}; };
struct px_hmac { struct px_hmac
{
uint (*result_size) (PX_HMAC * h); uint (*result_size) (PX_HMAC * h);
uint (*block_size) (PX_HMAC * h); uint (*block_size) (PX_HMAC * h);
void (*reset) (PX_HMAC * h); void (*reset) (PX_HMAC * h);
@ -93,13 +96,15 @@ struct px_hmac {
PX_MD *md; PX_MD *md;
/* private */ /* private */
struct { struct
{
uint8 *ipad; uint8 *ipad;
uint8 *opad; uint8 *opad;
} p; } p;
}; };
struct px_cipher { struct px_cipher
{
uint (*block_size) (PX_Cipher * c); uint (*block_size) (PX_Cipher * c);
uint (*key_size) (PX_Cipher * c); /* max key len */ uint (*key_size) (PX_Cipher * c); /* max key len */
uint (*iv_size) (PX_Cipher * c); uint (*iv_size) (PX_Cipher * c);
@ -113,7 +118,8 @@ struct px_cipher {
int pstat; /* mcrypt uses it */ int pstat; /* mcrypt uses it */
}; };
struct px_combo { struct px_combo
{
int (*init) (PX_Combo * cx, const uint8 *key, uint klen, int (*init) (PX_Combo * cx, const uint8 *key, uint klen,
const uint8 *iv, uint ivlen); const uint8 *iv, uint ivlen);
int (*encrypt) (PX_Combo * cx, const uint8 *data, uint dlen, int (*encrypt) (PX_Combo * cx, const uint8 *data, uint dlen,
@ -174,6 +180,4 @@ const char *px_resolve_alias(const PX_Alias *aliases, const char *name);
(c)->decrypt(c, data, dlen, res, rlen) (c)->decrypt(c, data, dlen, res, rlen)
#define px_combo_free(c) (c)->free(c) #define px_combo_free(c) (c)->free(c)
#endif /* __PX_H */ #endif /* __PX_H */

View File

@ -26,7 +26,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE. * SUCH DAMAGE.
* *
* $Id: random.c,v 1.2 2001/09/29 03:12:51 momjian Exp $ * $Id: random.c,v 1.3 2001/10/25 05:49:20 momjian Exp $
*/ */
@ -48,9 +48,11 @@ safe_read(int fd, void *buf, size_t count)
char *p = buf; char *p = buf;
int res; int res;
while (count) { while (count)
{
res = read(fd, p, count); res = read(fd, p, count);
if (res <= 0) { if (res <= 0)
{
if (errno == EINTR) if (errno == EINTR)
continue; continue;
return -1; return -1;
@ -75,20 +77,19 @@ px_get_random_bytes(uint8 *dst, unsigned count)
close(fd); close(fd);
return res; return res;
} }
#endif /* RAND_DEV */ #endif /* RAND_DEV */
#ifdef RAND_SILLY #ifdef RAND_SILLY
int px_get_random_bytes(uint8 *dst, unsigned count) int
px_get_random_bytes(uint8 *dst, unsigned count)
{ {
int i; int i;
for (i = 0; i < count; i++) {
for (i = 0; i < count; i++)
*dst++ = random(); *dst++ = random();
}
return i; return i;
} }
#endif /* RAND_SILLY */ #endif /* RAND_SILLY */
#ifdef RAND_OPENSSL #ifdef RAND_OPENSSL
@ -100,20 +101,21 @@ int px_get_random_bytes(uint8 *dst, unsigned count)
static int openssl_random_init = 0; static int openssl_random_init = 0;
int px_get_random_bytes(uint8 *dst, unsigned count) int
px_get_random_bytes(uint8 *dst, unsigned count)
{ {
int res; int res;
if (!openssl_random_init) { if (!openssl_random_init)
if (RAND_get_rand_method() == NULL) { {
if (RAND_get_rand_method() == NULL)
RAND_set_rand_method(RAND_SSLeay()); RAND_set_rand_method(RAND_SSLeay());
}
openssl_random_init = 1; openssl_random_init = 1;
} }
/* /*
* OpenSSL random should re-feeded occasionally. * OpenSSL random should re-feeded occasionally. From /dev/urandom
* From /dev/urandom preferrably. * preferrably.
*/ */
res = RAND_bytes(dst, count); res = RAND_bytes(dst, count);
@ -122,6 +124,4 @@ int px_get_random_bytes(uint8 *dst, unsigned count)
return -1; return -1;
} }
#endif /* RAND_OPENSSL */ #endif /* RAND_OPENSSL */

View File

@ -152,29 +152,34 @@ static u4byte tab_gen = 0;
rotl(((u4byte)isb_tab[byte(bi[(n + 3) & 3],1)]), 8) ^ \ rotl(((u4byte)isb_tab[byte(bi[(n + 3) & 3],1)]), 8) ^ \
rotl(((u4byte)isb_tab[byte(bi[(n + 2) & 3],2)]), 16) ^ \ rotl(((u4byte)isb_tab[byte(bi[(n + 2) & 3],2)]), 16) ^ \
rotl(((u4byte)isb_tab[byte(bi[(n + 1) & 3],3)]), 24) ^ *(k + n) rotl(((u4byte)isb_tab[byte(bi[(n + 1) & 3],3)]), 24) ^ *(k + n)
#endif #endif
static void static void
gen_tabs(void) gen_tabs(void)
{ {
#ifndef PRE_CALC_TABLES #ifndef PRE_CALC_TABLES
u4byte i, t; u4byte i,
u1byte p, q; t;
u1byte p,
q;
/* log and power tables for GF(2**8) finite field with */ /* log and power tables for GF(2**8) finite field with */
/* 0x11b as modular polynomial - the simplest prmitive */ /* 0x11b as modular polynomial - the simplest prmitive */
/* root is 0x11, used here to generate the tables */ /* root is 0x11, used here to generate the tables */
for(i = 0,p = 1; i < 256; ++i) { for (i = 0, p = 1; i < 256; ++i)
pow_tab[i] = (u1byte)p; log_tab[p] = (u1byte)i; {
pow_tab[i] = (u1byte) p;
log_tab[p] = (u1byte) i;
p = p ^ (p << 1) ^ (p & 0x80 ? 0x01b : 0); p = p ^ (p << 1) ^ (p & 0x80 ? 0x01b : 0);
} }
log_tab[1] = 0; p = 1; log_tab[1] = 0;
p = 1;
for(i = 0; i < 10; ++i) { for (i = 0; i < 10; ++i)
{
rco_tab[i] = p; rco_tab[i] = p;
p = (p << 1) ^ (p & 0x80 ? 0x1b : 0); p = (p << 1) ^ (p & 0x80 ? 0x1b : 0);
@ -186,21 +191,30 @@ gen_tabs(void)
/* of the specification the bits are numbered from the */ /* of the specification the bits are numbered from the */
/* least significant end of a byte. */ /* least significant end of a byte. */
for(i = 0; i < 256; ++i) { for (i = 0; i < 256; ++i)
p = (i ? pow_tab[255 - log_tab[i]] : 0); q = p; {
q = (q >> 7) | (q << 1); p ^= q; p = (i ? pow_tab[255 - log_tab[i]] : 0);
q = (q >> 7) | (q << 1); p ^= q; q = p;
q = (q >> 7) | (q << 1); p ^= q; q = (q >> 7) | (q << 1);
q = (q >> 7) | (q << 1); p ^= q ^ 0x63; p ^= q;
sbx_tab[i] = (u1byte)p; isb_tab[p] = (u1byte)i; q = (q >> 7) | (q << 1);
p ^= q;
q = (q >> 7) | (q << 1);
p ^= q;
q = (q >> 7) | (q << 1);
p ^= q ^ 0x63;
sbx_tab[i] = (u1byte) p;
isb_tab[p] = (u1byte) i;
} }
for(i = 0; i < 256; ++i) { for (i = 0; i < 256; ++i)
{
p = sbx_tab[i]; p = sbx_tab[i];
#ifdef LARGE_TABLES #ifdef LARGE_TABLES
t = p; fl_tab[0][i] = t; t = p;
fl_tab[0][i] = t;
fl_tab[1][i] = rotl(t, 8); fl_tab[1][i] = rotl(t, 8);
fl_tab[2][i] = rotl(t, 16); fl_tab[2][i] = rotl(t, 16);
fl_tab[3][i] = rotl(t, 24); fl_tab[3][i] = rotl(t, 24);
@ -219,7 +233,8 @@ gen_tabs(void)
#ifdef LARGE_TABLES #ifdef LARGE_TABLES
t = p; il_tab[0][i] = t; t = p;
il_tab[0][i] = t;
il_tab[1][i] = rotl(t, 8); il_tab[1][i] = rotl(t, 8);
il_tab[2][i] = rotl(t, 16); il_tab[2][i] = rotl(t, 16);
il_tab[3][i] = rotl(t, 24); il_tab[3][i] = rotl(t, 24);
@ -289,7 +304,11 @@ rijndael_ctx *
rijndael_set_key(rijndael_ctx * ctx, const u4byte * in_key, const u4byte key_len, rijndael_set_key(rijndael_ctx * ctx, const u4byte * in_key, const u4byte key_len,
int encrypt) int encrypt)
{ {
u4byte i, t, u, v, w; u4byte i,
t,
u,
v,
w;
u4byte *e_key = ctx->e_key; u4byte *e_key = ctx->e_key;
u4byte *d_key = ctx->d_key; u4byte *d_key = ctx->d_key;
@ -300,35 +319,46 @@ rijndael_set_key(rijndael_ctx *ctx, const u4byte *in_key, const u4byte key_len,
ctx->k_len = (key_len + 31) / 32; ctx->k_len = (key_len + 31) / 32;
e_key[0] = io_swap(in_key[0]); e_key[1] = io_swap(in_key[1]); e_key[0] = io_swap(in_key[0]);
e_key[2] = io_swap(in_key[2]); e_key[3] = io_swap(in_key[3]); e_key[1] = io_swap(in_key[1]);
e_key[2] = io_swap(in_key[2]);
e_key[3] = io_swap(in_key[3]);
switch(ctx->k_len) { switch (ctx->k_len)
case 4: t = e_key[3]; {
case 4:
t = e_key[3];
for (i = 0; i < 10; ++i) for (i = 0; i < 10; ++i)
loop4(i); loop4(i);
break; break;
case 6: e_key[4] = io_swap(in_key[4]); t = e_key[5] = io_swap(in_key[5]); case 6:
e_key[4] = io_swap(in_key[4]);
t = e_key[5] = io_swap(in_key[5]);
for (i = 0; i < 8; ++i) for (i = 0; i < 8; ++i)
loop6(i); loop6(i);
break; break;
case 8: e_key[4] = io_swap(in_key[4]); e_key[5] = io_swap(in_key[5]); case 8:
e_key[6] = io_swap(in_key[6]); t = e_key[7] = io_swap(in_key[7]); e_key[4] = io_swap(in_key[4]);
e_key[5] = io_swap(in_key[5]);
e_key[6] = io_swap(in_key[6]);
t = e_key[7] = io_swap(in_key[7]);
for (i = 0; i < 7; ++i) for (i = 0; i < 7; ++i)
loop8(i); loop8(i);
break; break;
} }
if (!encrypt) { if (!encrypt)
d_key[0] = e_key[0]; d_key[1] = e_key[1]; {
d_key[2] = e_key[2]; d_key[3] = e_key[3]; d_key[0] = e_key[0];
d_key[1] = e_key[1];
d_key[2] = e_key[2];
d_key[3] = e_key[3];
for(i = 4; i < 4 * ctx->k_len + 24; ++i) { for (i = 4; i < 4 * ctx->k_len + 24; ++i)
imix_col(d_key[i], e_key[i]); imix_col(d_key[i], e_key[i]);
} }
}
return ctx; return ctx;
} }
@ -353,7 +383,9 @@ rijndael_encrypt(rijndael_ctx *ctx, const u4byte *in_blk, u4byte *out_blk)
{ {
u4byte k_len = ctx->k_len; u4byte k_len = ctx->k_len;
u4byte *e_key = ctx->e_key; u4byte *e_key = ctx->e_key;
u4byte b0[4], b1[4], *kp; u4byte b0[4],
b1[4],
*kp;
b0[0] = io_swap(in_blk[0]) ^ e_key[0]; b0[0] = io_swap(in_blk[0]) ^ e_key[0];
b0[1] = io_swap(in_blk[1]) ^ e_key[1]; b0[1] = io_swap(in_blk[1]) ^ e_key[1];
@ -362,22 +394,33 @@ rijndael_encrypt(rijndael_ctx *ctx, const u4byte *in_blk, u4byte *out_blk)
kp = e_key + 4; kp = e_key + 4;
if(k_len > 6) { if (k_len > 6)
f_nround(b1, b0, kp); f_nround(b0, b1, kp); {
f_nround(b1, b0, kp);
f_nround(b0, b1, kp);
} }
if(k_len > 4) { if (k_len > 4)
f_nround(b1, b0, kp); f_nround(b0, b1, kp); {
f_nround(b1, b0, kp);
f_nround(b0, b1, kp);
} }
f_nround(b1, b0, kp); f_nround(b0, b1, kp); f_nround(b1, b0, kp);
f_nround(b1, b0, kp); f_nround(b0, b1, kp); f_nround(b0, b1, kp);
f_nround(b1, b0, kp); f_nround(b0, b1, kp); f_nround(b1, b0, kp);
f_nround(b1, b0, kp); f_nround(b0, b1, kp); f_nround(b0, b1, kp);
f_nround(b1, b0, kp); f_lround(b0, b1, kp); f_nround(b1, b0, kp);
f_nround(b0, b1, kp);
f_nround(b1, b0, kp);
f_nround(b0, b1, kp);
f_nround(b1, b0, kp);
f_lround(b0, b1, kp);
out_blk[0] = io_swap(b0[0]); out_blk[1] = io_swap(b0[1]); out_blk[0] = io_swap(b0[0]);
out_blk[2] = io_swap(b0[2]); out_blk[3] = io_swap(b0[3]); out_blk[1] = io_swap(b0[1]);
out_blk[2] = io_swap(b0[2]);
out_blk[3] = io_swap(b0[3]);
} }
/* decrypt a block of text */ /* decrypt a block of text */
@ -398,7 +441,9 @@ rijndael_encrypt(rijndael_ctx *ctx, const u4byte *in_blk, u4byte *out_blk)
void void
rijndael_decrypt(rijndael_ctx * ctx, const u4byte * in_blk, u4byte * out_blk) rijndael_decrypt(rijndael_ctx * ctx, const u4byte * in_blk, u4byte * out_blk)
{ {
u4byte b0[4], b1[4], *kp; u4byte b0[4],
b1[4],
*kp;
u4byte k_len = ctx->k_len; u4byte k_len = ctx->k_len;
u4byte *e_key = ctx->e_key; u4byte *e_key = ctx->e_key;
u4byte *d_key = ctx->d_key; u4byte *d_key = ctx->d_key;
@ -410,22 +455,33 @@ rijndael_decrypt(rijndael_ctx *ctx, const u4byte *in_blk, u4byte *out_blk)
kp = d_key + 4 * (k_len + 5); kp = d_key + 4 * (k_len + 5);
if(k_len > 6) { if (k_len > 6)
i_nround(b1, b0, kp); i_nround(b0, b1, kp); {
i_nround(b1, b0, kp);
i_nround(b0, b1, kp);
} }
if(k_len > 4) { if (k_len > 4)
i_nround(b1, b0, kp); i_nround(b0, b1, kp); {
i_nround(b1, b0, kp);
i_nround(b0, b1, kp);
} }
i_nround(b1, b0, kp); i_nround(b0, b1, kp); i_nround(b1, b0, kp);
i_nround(b1, b0, kp); i_nround(b0, b1, kp); i_nround(b0, b1, kp);
i_nround(b1, b0, kp); i_nround(b0, b1, kp); i_nround(b1, b0, kp);
i_nround(b1, b0, kp); i_nround(b0, b1, kp); i_nround(b0, b1, kp);
i_nround(b1, b0, kp); i_lround(b0, b1, kp); i_nround(b1, b0, kp);
i_nround(b0, b1, kp);
i_nround(b1, b0, kp);
i_nround(b0, b1, kp);
i_nround(b1, b0, kp);
i_lround(b0, b1, kp);
out_blk[0] = io_swap(b0[0]); out_blk[1] = io_swap(b0[1]); out_blk[0] = io_swap(b0[0]);
out_blk[2] = io_swap(b0[2]); out_blk[3] = io_swap(b0[3]); out_blk[1] = io_swap(b0[1]);
out_blk[2] = io_swap(b0[2]);
out_blk[3] = io_swap(b0[3]);
} }
/* /*
@ -435,18 +491,23 @@ rijndael_decrypt(rijndael_ctx *ctx, const u4byte *in_blk, u4byte *out_blk)
* should be true for PX. -marko * should be true for PX. -marko
*/ */
void aes_set_key(rijndael_ctx * ctx, const uint8 *key, uint keybits, int enc) void
aes_set_key(rijndael_ctx * ctx, const uint8 *key, uint keybits, int enc)
{ {
uint32 *k; uint32 *k;
k = (uint32 *) key; k = (uint32 *) key;
rijndael_set_key(ctx, k, keybits, enc); rijndael_set_key(ctx, k, keybits, enc);
} }
void aes_ecb_encrypt(rijndael_ctx *ctx, uint8 *data, unsigned len) void
aes_ecb_encrypt(rijndael_ctx * ctx, uint8 *data, unsigned len)
{ {
unsigned bs = 16; unsigned bs = 16;
uint32 *d; uint32 *d;
while (len >= bs) {
while (len >= bs)
{
d = (uint32 *) data; d = (uint32 *) data;
rijndael_encrypt(ctx, d, d); rijndael_encrypt(ctx, d, d);
@ -455,11 +516,14 @@ void aes_ecb_encrypt(rijndael_ctx *ctx, uint8 *data, unsigned len)
} }
} }
void aes_ecb_decrypt(rijndael_ctx *ctx, uint8 *data, unsigned len) void
aes_ecb_decrypt(rijndael_ctx * ctx, uint8 *data, unsigned len)
{ {
unsigned bs = 16; unsigned bs = 16;
uint32 *d; uint32 *d;
while (len >= bs) {
while (len >= bs)
{
d = (uint32 *) data; d = (uint32 *) data;
rijndael_decrypt(ctx, d, d); rijndael_decrypt(ctx, d, d);
@ -468,15 +532,19 @@ void aes_ecb_decrypt(rijndael_ctx *ctx, uint8 *data, unsigned len)
} }
} }
void aes_cbc_encrypt(rijndael_ctx *ctx, uint8 *iva, uint8 *data, unsigned len) void
aes_cbc_encrypt(rijndael_ctx * ctx, uint8 *iva, uint8 *data, unsigned len)
{ {
uint32 *iv = (uint32 *) iva; uint32 *iv = (uint32 *) iva;
uint32 *d = (uint32 *) data; uint32 *d = (uint32 *) data;
unsigned bs = 16; unsigned bs = 16;
while (len >= bs) { while (len >= bs)
d[0] ^= iv[0]; d[1] ^= iv[1]; {
d[2] ^= iv[2]; d[3] ^= iv[3]; d[0] ^= iv[0];
d[1] ^= iv[1];
d[2] ^= iv[2];
d[3] ^= iv[3];
rijndael_encrypt(ctx, d, d); rijndael_encrypt(ctx, d, d);
@ -486,24 +554,33 @@ void aes_cbc_encrypt(rijndael_ctx *ctx, uint8 *iva, uint8 *data, unsigned len)
} }
} }
void aes_cbc_decrypt(rijndael_ctx *ctx, uint8 *iva, uint8 *data, unsigned len) void
aes_cbc_decrypt(rijndael_ctx * ctx, uint8 *iva, uint8 *data, unsigned len)
{ {
uint32 *d = (uint32 *) data; uint32 *d = (uint32 *) data;
unsigned bs = 16; unsigned bs = 16;
uint32 buf[4], iv[4]; uint32 buf[4],
iv[4];
memcpy(iv, iva, bs); memcpy(iv, iva, bs);
while (len >= bs) { while (len >= bs)
buf[0] = d[0]; buf[1] = d[1]; {
buf[2] = d[2]; buf[3] = d[3]; buf[0] = d[0];
buf[1] = d[1];
buf[2] = d[2];
buf[3] = d[3];
rijndael_decrypt(ctx, buf, d); rijndael_decrypt(ctx, buf, d);
d[0] ^= iv[0]; d[1] ^= iv[1]; d[0] ^= iv[0];
d[2] ^= iv[2]; d[3] ^= iv[3]; d[1] ^= iv[1];
d[2] ^= iv[2];
d[3] ^= iv[3];
iv[0] = buf[0]; iv[1] = buf[1]; iv[0] = buf[0];
iv[2] = buf[2]; iv[3] = buf[3]; iv[1] = buf[1];
iv[2] = buf[2];
iv[3] = buf[3];
d += 4; d += 4;
len -= bs; len -= bs;
} }
@ -518,11 +595,14 @@ void aes_cbc_decrypt(rijndael_ctx *ctx, uint8 *iva, uint8 *data, unsigned len)
*/ */
#ifdef PRINT_TABS #ifdef PRINT_TABS
static void show256u8(char *name, uint8 *data) static void
show256u8(char *name, uint8 *data)
{ {
int i; int i;
printf("static const u1byte %s[256] = {\n ", name); printf("static const u1byte %s[256] = {\n ", name);
for (i = 0; i < 256; ) { for (i = 0; i < 256;)
{
printf("%u", pow_tab[i++]); printf("%u", pow_tab[i++]);
if (i < 256) if (i < 256)
printf(i % 16 ? ", " : ",\n "); printf(i % 16 ? ", " : ",\n ");
@ -531,12 +611,17 @@ static void show256u8(char *name, uint8 *data)
} }
static void show4x256u32(char *name, uint32 data[4][256]) static void
show4x256u32(char *name, uint32 data[4][256])
{ {
int i, j; int i,
j;
printf("static const u4byte %s[4][256] = {\n{\n ", name); printf("static const u4byte %s[4][256] = {\n{\n ", name);
for (i = 0; i < 4; i++) { for (i = 0; i < 4; i++)
for (j = 0; j < 256; ) { {
for (j = 0; j < 256;)
{
printf("0x%08x", data[i][j]); printf("0x%08x", data[i][j]);
j++; j++;
if (j < 256) if (j < 256)
@ -547,7 +632,8 @@ static void show4x256u32(char *name, uint32 data[4][256])
printf("};\n\n"); printf("};\n\n");
} }
int main() int
main()
{ {
int i; int i;
char *hdr = "/* Generated by rijndael.c */\n\n"; char *hdr = "/* Generated by rijndael.c */\n\n";
@ -567,14 +653,15 @@ int main()
show4x256u32("il_tab", il_tab); show4x256u32("il_tab", il_tab);
#endif #endif
printf("static const u4byte rco_tab[10] = {\n "); printf("static const u4byte rco_tab[10] = {\n ");
for (i = 0; i < 10; i++) { for (i = 0; i < 10; i++)
{
printf("0x%08x", rco_tab[i]); printf("0x%08x", rco_tab[i]);
if (i < 9) printf(", "); if (i < 9)
if (i == 4) printf("\n "); printf(", ");
if (i == 4)
printf("\n ");
} }
printf("\n};\n\n"); printf("\n};\n\n");
return 0; return 0;
} }
#endif #endif

View File

@ -27,7 +27,8 @@ typedef int8 s1byte; /* an 8 bit signed character type */
typedef int16 s2byte; /* a 16 bit signed integer type */ typedef int16 s2byte; /* a 16 bit signed integer type */
typedef int32 s4byte; /* a 32 bit signed integer type */ typedef int32 s4byte; /* a 32 bit signed integer type */
typedef struct _rijndael_ctx { typedef struct _rijndael_ctx
{
u4byte k_len; u4byte k_len;
int decrypt; int decrypt;
u4byte e_key[64]; u4byte e_key[64];
@ -53,5 +54,4 @@ void aes_ecb_decrypt(rijndael_ctx *ctx, uint8 *data, unsigned len);
void aes_cbc_encrypt(rijndael_ctx * ctx, uint8 *iva, uint8 *data, unsigned len); void aes_cbc_encrypt(rijndael_ctx * ctx, uint8 *iva, uint8 *data, unsigned len);
void aes_cbc_decrypt(rijndael_ctx * ctx, uint8 *iva, uint8 *data, unsigned len); void aes_cbc_decrypt(rijndael_ctx * ctx, uint8 *iva, uint8 *data, unsigned len);
#endif /* _RIJNDAEL_H_ */ #endif /* _RIJNDAEL_H_ */

View File

@ -1,4 +1,4 @@
/* $Id: sha1.c,v 1.7 2001/10/25 01:29:37 momjian Exp $ */ /* $Id: sha1.c,v 1.8 2001/10/25 05:49:20 momjian Exp $ */
/* $KAME: sha1.c,v 1.3 2000/02/22 14:01:18 itojun Exp $ */ /* $KAME: sha1.c,v 1.3 2000/02/22 14:01:18 itojun Exp $ */
/* /*

View File

@ -1,4 +1,4 @@
/* $Id: sha1.h,v 1.5 2001/08/21 00:42:41 momjian Exp $ */ /* $Id: sha1.h,v 1.6 2001/10/25 05:49:20 momjian Exp $ */
/* $KAME: sha1.h,v 1.4 2000/02/22 14:01:18 itojun Exp $ */ /* $KAME: sha1.h,v 1.4 2000/02/22 14:01:18 itojun Exp $ */
/* /*
@ -71,5 +71,4 @@ typedef struct sha1_ctxt SHA1_CTX;
#define SHA1Final(x, y) sha1_result((y), (x)) #define SHA1Final(x, y) sha1_result((y), (x))
#define SHA1_RESULTLEN (160/8) #define SHA1_RESULTLEN (160/8)
#endif /* _NETINET6_SHA1_H_ */ #endif /* _NETINET6_SHA1_H_ */

View File

@ -1,5 +1,5 @@
/* /*
* $Header: /cvsroot/pgsql/contrib/pgstattuple/pgstattuple.c,v 1.1 2001/10/01 01:52:38 ishii Exp $ * $Header: /cvsroot/pgsql/contrib/pgstattuple/pgstattuple.c,v 1.2 2001/10/25 05:49:20 momjian Exp $
* *
* Copyright (c) 2001 Tatsuo Ishii * Copyright (c) 2001 Tatsuo Ishii
* *
@ -117,7 +117,8 @@ pgstattuple(PG_FUNCTION_ARGS)
(double) dead_tuple_len / 1024 / 1024, /* dead tuples in MB */ (double) dead_tuple_len / 1024 / 1024, /* dead tuples in MB */
dead_tuple_percent, /* dead tuples in % */ dead_tuple_percent, /* dead tuples in % */
(double)free_space/1024/1024, /* free/available space in MB */ (double) free_space / 1024 / 1024, /* free/available space in
* MB */
free_percent, /* free/available space in % */ free_percent, /* free/available space in % */

View File

@ -24,7 +24,6 @@ Datum _rserv_debug_(PG_FUNCTION_ARGS);
HeapTuple _rserv_log_(void); HeapTuple _rserv_log_(void);
int32 _rserv_sync_(int32); int32 _rserv_sync_(int32);
int32 _rserv_debug_(int32); int32 _rserv_debug_(int32);
#endif #endif
static int debug = 0; static int debug = 0;
@ -88,6 +87,7 @@ _rserv_log_()
newtuple = CurrentTriggerData->tg_newtuple; newtuple = CurrentTriggerData->tg_newtuple;
#ifndef PG_FUNCTION_INFO_V1 #ifndef PG_FUNCTION_INFO_V1
/* /*
* Setting CurrentTriggerData to NULL prevents direct calls to trigger * Setting CurrentTriggerData to NULL prevents direct calls to trigger
* functions in queries. Normally, trigger functions have to be called * functions in queries. Normally, trigger functions have to be called
@ -207,7 +207,6 @@ _rserv_sync_(int32 server)
{ {
#ifdef PG_FUNCTION_INFO_V1 #ifdef PG_FUNCTION_INFO_V1
int32 server = PG_GETARG_INT32(0); int32 server = PG_GETARG_INT32(0);
#endif #endif
char sql[8192]; char sql[8192];
char buf[8192]; char buf[8192];
@ -253,7 +252,6 @@ _rserv_debug_(int32 newval)
{ {
#ifdef PG_FUNCTION_INFO_V1 #ifdef PG_FUNCTION_INFO_V1
int32 newval = PG_GETARG_INT32(0); int32 newval = PG_GETARG_INT32(0);
#endif #endif
int32 oldval = debug; int32 oldval = debug;

View File

@ -7,7 +7,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $Header: /cvsroot/pgsql/contrib/rtree_gist/Attic/rtree_gist.c,v 1.3 2001/10/01 17:53:11 tgl Exp $ * $Header: /cvsroot/pgsql/contrib/rtree_gist/Attic/rtree_gist.c,v 1.4 2001/10/25 05:49:20 momjian Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
@ -80,8 +80,8 @@ gbox_consistent(PG_FUNCTION_ARGS)
StrategyNumber strategy = (StrategyNumber) PG_GETARG_UINT16(2); StrategyNumber strategy = (StrategyNumber) PG_GETARG_UINT16(2);
/* /*
** if entry is not leaf, use gbox_internal_consistent, * * if entry is not leaf, use gbox_internal_consistent, * else use
** else use gbox_leaf_consistent * gbox_leaf_consistent
*/ */
if (!(DatumGetPointer(entry->key) != NULL && query)) if (!(DatumGetPointer(entry->key) != NULL && query))
PG_RETURN_BOOL(FALSE); PG_RETURN_BOOL(FALSE);
@ -102,15 +102,18 @@ gbox_union(PG_FUNCTION_ARGS)
{ {
bytea *entryvec = (bytea *) PG_GETARG_POINTER(0); bytea *entryvec = (bytea *) PG_GETARG_POINTER(0);
int *sizep = (int *) PG_GETARG_POINTER(1); int *sizep = (int *) PG_GETARG_POINTER(1);
int numranges, i; int numranges,
BOX *cur, *pageunion; i;
BOX *cur,
*pageunion;
numranges = (VARSIZE(entryvec) - VARHDRSZ) / sizeof(GISTENTRY); numranges = (VARSIZE(entryvec) - VARHDRSZ) / sizeof(GISTENTRY);
pageunion = (BOX *) palloc(sizeof(BOX)); pageunion = (BOX *) palloc(sizeof(BOX));
cur = DatumGetBoxP(((GISTENTRY *) VARDATA(entryvec))[0].key); cur = DatumGetBoxP(((GISTENTRY *) VARDATA(entryvec))[0].key);
memcpy((void *) pageunion, (void *) cur, sizeof(BOX)); memcpy((void *) pageunion, (void *) cur, sizeof(BOX));
for (i = 1; i < numranges; i++) { for (i = 1; i < numranges; i++)
{
cur = DatumGetBoxP(((GISTENTRY *) VARDATA(entryvec))[i].key); cur = DatumGetBoxP(((GISTENTRY *) VARDATA(entryvec))[i].key);
if (pageunion->high.x < cur->high.x) if (pageunion->high.x < cur->high.x)
pageunion->high.x = cur->high.x; pageunion->high.x = cur->high.x;
@ -151,7 +154,8 @@ gbox_penalty(PG_FUNCTION_ARGS)
ud = DirectFunctionCall2(rt_box_union, origentry->key, newentry->key); ud = DirectFunctionCall2(rt_box_union, origentry->key, newentry->key);
tmp1 = size_box(ud); tmp1 = size_box(ud);
if (DatumGetPointer(ud) != NULL) pfree(DatumGetPointer(ud)); if (DatumGetPointer(ud) != NULL)
pfree(DatumGetPointer(ud));
*result = tmp1 - size_box(origentry->key); *result = tmp1 - size_box(origentry->key);
PG_RETURN_POINTER(result); PG_RETURN_POINTER(result);
@ -168,9 +172,18 @@ gbox_picksplit(PG_FUNCTION_ARGS)
bytea *entryvec = (bytea *) PG_GETARG_POINTER(0); bytea *entryvec = (bytea *) PG_GETARG_POINTER(0);
GIST_SPLITVEC *v = (GIST_SPLITVEC *) PG_GETARG_POINTER(1); GIST_SPLITVEC *v = (GIST_SPLITVEC *) PG_GETARG_POINTER(1);
OffsetNumber i; OffsetNumber i;
OffsetNumber *listL, *listR, *listB, *listT; OffsetNumber *listL,
BOX *unionL,*unionR,*unionB,*unionT; *listR,
int posL, posR, posB, posT; *listB,
*listT;
BOX *unionL,
*unionR,
*unionB,
*unionT;
int posL,
posR,
posB,
posT;
BOX pageunion; BOX pageunion;
BOX *cur; BOX *cur;
char direction = ' '; char direction = ' ';
@ -185,16 +198,29 @@ gbox_picksplit(PG_FUNCTION_ARGS)
memcpy((void *) &pageunion, (void *) cur, sizeof(BOX)); memcpy((void *) &pageunion, (void *) cur, sizeof(BOX));
/* find MBR */ /* find MBR */
for (i = OffsetNumberNext(FirstOffsetNumber); i <= maxoff; i = OffsetNumberNext(i)) { for (i = OffsetNumberNext(FirstOffsetNumber); i <= maxoff; i = OffsetNumberNext(i))
{
cur = DatumGetBoxP(((GISTENTRY *) VARDATA(entryvec))[i].key); cur = DatumGetBoxP(((GISTENTRY *) VARDATA(entryvec))[i].key);
if (pageunion.high.x < cur->high.x) if (pageunion.high.x < cur->high.x)
{ allisequal=false; pageunion.high.x = cur->high.x; } {
allisequal = false;
pageunion.high.x = cur->high.x;
}
if (pageunion.low.x > cur->low.x) if (pageunion.low.x > cur->low.x)
{ allisequal=false; pageunion.low.x = cur->low.x; } {
allisequal = false;
pageunion.low.x = cur->low.x;
}
if (pageunion.high.y < cur->high.y) if (pageunion.high.y < cur->high.y)
{ allisequal=false; pageunion.high.y = cur->high.y; } {
allisequal = false;
pageunion.high.y = cur->high.y;
}
if (pageunion.low.y > cur->low.y) if (pageunion.low.y > cur->low.y)
{ allisequal=false; pageunion.low.y = cur->low.y; } {
allisequal = false;
pageunion.low.y = cur->low.y;
}
} }
nbytes = (maxoff + 2) * sizeof(OffsetNumber); nbytes = (maxoff + 2) * sizeof(OffsetNumber);
@ -202,20 +228,26 @@ gbox_picksplit(PG_FUNCTION_ARGS)
listR = (OffsetNumber *) palloc(nbytes); listR = (OffsetNumber *) palloc(nbytes);
unionL = (BOX *) palloc(sizeof(BOX)); unionL = (BOX *) palloc(sizeof(BOX));
unionR = (BOX *) palloc(sizeof(BOX)); unionR = (BOX *) palloc(sizeof(BOX));
if ( allisequal ) { if (allisequal)
{
cur = DatumGetBoxP(((GISTENTRY *) VARDATA(entryvec))[OffsetNumberNext(FirstOffsetNumber)].key); cur = DatumGetBoxP(((GISTENTRY *) VARDATA(entryvec))[OffsetNumberNext(FirstOffsetNumber)].key);
if ( memcmp( (void*)cur, (void*)&pageunion, sizeof( BOX ) ) == 0 ) { if (memcmp((void *) cur, (void *) &pageunion, sizeof(BOX)) == 0)
{
v->spl_left = listL; v->spl_left = listL;
v->spl_right = listR; v->spl_right = listR;
v->spl_nleft = v->spl_nright = 0; v->spl_nleft = v->spl_nright = 0;
memcpy((void *) unionL, (void *) &pageunion, sizeof(BOX)); memcpy((void *) unionL, (void *) &pageunion, sizeof(BOX));
memcpy((void *) unionR, (void *) &pageunion, sizeof(BOX)); memcpy((void *) unionR, (void *) &pageunion, sizeof(BOX));
for (i = FirstOffsetNumber; i <= maxoff; i = OffsetNumberNext(i)) { for (i = FirstOffsetNumber; i <= maxoff; i = OffsetNumberNext(i))
if (i <= (maxoff - FirstOffsetNumber + 1)/2) { {
if (i <= (maxoff - FirstOffsetNumber + 1) / 2)
{
v->spl_left[v->spl_nleft] = i; v->spl_left[v->spl_nleft] = i;
v->spl_nleft++; v->spl_nleft++;
} else { }
else
{
v->spl_right[v->spl_nright] = i; v->spl_right[v->spl_nright] = i;
v->spl_nright++; v->spl_nright++;
} }
@ -245,7 +277,8 @@ gbox_picksplit(PG_FUNCTION_ARGS)
(pos)++; \ (pos)++; \
} while(0) } while(0)
for (i = FirstOffsetNumber; i <= maxoff; i = OffsetNumberNext(i)) { for (i = FirstOffsetNumber; i <= maxoff; i = OffsetNumberNext(i))
{
cur = DatumGetBoxP(((GISTENTRY *) VARDATA(entryvec))[i].key); cur = DatumGetBoxP(((GISTENTRY *) VARDATA(entryvec))[i].key);
if (cur->low.x - pageunion.low.x < pageunion.high.x - cur->high.x) if (cur->low.x - pageunion.low.x < pageunion.high.x - cur->high.x)
ADDLIST(listL, unionL, posL); ADDLIST(listL, unionL, posL);
@ -259,18 +292,20 @@ gbox_picksplit(PG_FUNCTION_ARGS)
/* which split more optimal? */ /* which split more optimal? */
if ( Max( posL, posR ) < Max( posB, posT ) ) { if (Max(posL, posR) < Max(posB, posT))
direction = 'x'; direction = 'x';
} else if ( Max( posL, posR ) > Max( posB, posT ) ) { else if (Max(posL, posR) > Max(posB, posT))
direction = 'y'; direction = 'y';
} else { else
{
Datum interLR = DirectFunctionCall2(rt_box_inter, Datum interLR = DirectFunctionCall2(rt_box_inter,
BoxPGetDatum(unionL), BoxPGetDatum(unionL),
BoxPGetDatum(unionR)); BoxPGetDatum(unionR));
Datum interBT = DirectFunctionCall2(rt_box_inter, Datum interBT = DirectFunctionCall2(rt_box_inter,
BoxPGetDatum(unionB), BoxPGetDatum(unionB),
BoxPGetDatum(unionT)); BoxPGetDatum(unionT));
float sizeLR, sizeBT; float sizeLR,
sizeBT;
sizeLR = size_box(interLR); sizeLR = size_box(interLR);
sizeBT = size_box(interBT); sizeBT = size_box(interBT);
@ -281,9 +316,12 @@ gbox_picksplit(PG_FUNCTION_ARGS)
direction = 'y'; direction = 'y';
} }
if ( direction == 'x' ) { if (direction == 'x')
pfree( unionB ); pfree( listB ); {
pfree( unionT ); pfree( listT ); pfree(unionB);
pfree(listB);
pfree(unionT);
pfree(listT);
v->spl_left = listL; v->spl_left = listL;
v->spl_right = listR; v->spl_right = listR;
@ -291,9 +329,13 @@ gbox_picksplit(PG_FUNCTION_ARGS)
v->spl_nright = posR; v->spl_nright = posR;
v->spl_ldatum = BoxPGetDatum(unionL); v->spl_ldatum = BoxPGetDatum(unionL);
v->spl_rdatum = BoxPGetDatum(unionR); v->spl_rdatum = BoxPGetDatum(unionR);
} else { }
pfree( unionR ); pfree( listR ); else
pfree( unionL ); pfree( listL ); {
pfree(unionR);
pfree(listR);
pfree(unionL);
pfree(listL);
v->spl_left = listB; v->spl_left = listB;
v->spl_right = listT; v->spl_right = listT;
@ -315,6 +357,7 @@ gbox_same(PG_FUNCTION_ARGS)
BOX *b1 = (BOX *) PG_GETARG_POINTER(0); BOX *b1 = (BOX *) PG_GETARG_POINTER(0);
BOX *b2 = (BOX *) PG_GETARG_POINTER(1); BOX *b2 = (BOX *) PG_GETARG_POINTER(1);
bool *result = (bool *) PG_GETARG_POINTER(2); bool *result = (bool *) PG_GETARG_POINTER(2);
if (b1 && b2) if (b1 && b2)
*result = DatumGetBool(DirectFunctionCall2(box_same, PointerGetDatum(b1), PointerGetDatum(b2))); *result = DatumGetBool(DirectFunctionCall2(box_same, PointerGetDatum(b1), PointerGetDatum(b2)));
else else
@ -332,7 +375,8 @@ gbox_leaf_consistent(BOX *key,
{ {
bool retval; bool retval;
switch(strategy) { switch (strategy)
{
case RTLeftStrategyNumber: case RTLeftStrategyNumber:
retval = DatumGetBool(DirectFunctionCall2(box_left, PointerGetDatum(key), PointerGetDatum(query))); retval = DatumGetBool(DirectFunctionCall2(box_left, PointerGetDatum(key), PointerGetDatum(query)));
break; break;
@ -364,14 +408,17 @@ gbox_leaf_consistent(BOX *key,
} }
static float static float
size_box( Datum box ) { size_box(Datum box)
if ( DatumGetPointer(box) != NULL ) { {
if (DatumGetPointer(box) != NULL)
{
float size; float size;
DirectFunctionCall2(rt_box_size, DirectFunctionCall2(rt_box_size,
box, PointerGetDatum(&size)); box, PointerGetDatum(&size));
return size; return size;
} else }
else
return 0.0; return 0.0;
} }
@ -385,11 +432,14 @@ gpoly_compress(PG_FUNCTION_ARGS)
GISTENTRY *entry = (GISTENTRY *) PG_GETARG_POINTER(0); GISTENTRY *entry = (GISTENTRY *) PG_GETARG_POINTER(0);
GISTENTRY *retval; GISTENTRY *retval;
if ( entry->leafkey) { if (entry->leafkey)
{
retval = palloc(sizeof(GISTENTRY)); retval = palloc(sizeof(GISTENTRY));
if ( DatumGetPointer(entry->key) != NULL ) { if (DatumGetPointer(entry->key) != NULL)
{
POLYGON *in; POLYGON *in;
BOX *r; BOX *r;
in = (POLYGON *) PG_DETOAST_DATUM(entry->key); in = (POLYGON *) PG_DETOAST_DATUM(entry->key);
r = (BOX *) palloc(sizeof(BOX)); r = (BOX *) palloc(sizeof(BOX));
memcpy((void *) r, (void *) &(in->boundbox), sizeof(BOX)); memcpy((void *) r, (void *) &(in->boundbox), sizeof(BOX));
@ -400,14 +450,16 @@ gpoly_compress(PG_FUNCTION_ARGS)
entry->rel, entry->page, entry->rel, entry->page,
entry->offset, sizeof(BOX), FALSE); entry->offset, sizeof(BOX), FALSE);
} else { }
else
{
gistentryinit(*retval, (Datum) 0, gistentryinit(*retval, (Datum) 0,
entry->rel, entry->page, entry->rel, entry->page,
entry->offset, 0, FALSE); entry->offset, 0, FALSE);
} }
} else {
retval = entry;
} }
else
retval = entry;
PG_RETURN_POINTER(retval); PG_RETURN_POINTER(retval);
} }
@ -420,8 +472,8 @@ gpoly_consistent(PG_FUNCTION_ARGS)
bool result; bool result;
/* /*
** if entry is not leaf, use gbox_internal_consistent, * * if entry is not leaf, use gbox_internal_consistent, * else use
** else use gbox_leaf_consistent * gbox_leaf_consistent
*/ */
if (!(DatumGetPointer(entry->key) != NULL && query)) if (!(DatumGetPointer(entry->key) != NULL && query))
PG_RETURN_BOOL(FALSE); PG_RETURN_BOOL(FALSE);
@ -444,7 +496,8 @@ rtree_internal_consistent(BOX *key,
{ {
bool retval; bool retval;
switch(strategy) { switch (strategy)
{
case RTLeftStrategyNumber: case RTLeftStrategyNumber:
case RTOverLeftStrategyNumber: case RTOverLeftStrategyNumber:
retval = DatumGetBool(DirectFunctionCall2(box_overleft, PointerGetDatum(key), PointerGetDatum(query))); retval = DatumGetBool(DirectFunctionCall2(box_overleft, PointerGetDatum(key), PointerGetDatum(query)));

View File

@ -138,7 +138,6 @@ seg_out(SEG * seg)
if (seg->lower == seg->upper && seg->l_ext == seg->u_ext) if (seg->lower == seg->upper && seg->l_ext == seg->u_ext)
{ {
/* /*
* indicates that this interval was built by seg_in off a single * indicates that this interval was built by seg_in off a single
* point * point
@ -219,7 +218,6 @@ gseg_consistent(GISTENTRY *entry,
SEG * query, SEG * query,
StrategyNumber strategy) StrategyNumber strategy)
{ {
/* /*
* * if entry is not leaf, use gseg_internal_consistent, * else use * * if entry is not leaf, use gseg_internal_consistent, * else use
* gseg_leaf_consistent * gseg_leaf_consistent
@ -415,7 +413,6 @@ gseg_picksplit(bytea *entryvec,
maxoff = OffsetNumberNext(maxoff); maxoff = OffsetNumberNext(maxoff);
for (i = FirstOffsetNumber; i <= maxoff; i = OffsetNumberNext(i)) for (i = FirstOffsetNumber; i <= maxoff; i = OffsetNumberNext(i))
{ {
/* /*
* If we've already decided where to place this item, just put it * If we've already decided where to place this item, just put it
* on the right list. Otherwise, we need to figure out which page * on the right list. Otherwise, we need to figure out which page
@ -757,7 +754,6 @@ seg_size(SEG * a)
int32 int32
seg_cmp(SEG * a, SEG * b) seg_cmp(SEG * a, SEG * b)
{ {
/* /*
* First compare on lower boundary position * First compare on lower boundary position
*/ */
@ -968,7 +964,6 @@ restore(char *result, float val, int n)
{ {
if (abs(exp) <= 4) if (abs(exp) <= 4)
{ {
/* /*
* remove the decimal point from the mantyssa and write the * remove the decimal point from the mantyssa and write the
* digits to the buf array * digits to the buf array
@ -989,7 +984,6 @@ restore(char *result, float val, int n)
{ {
if (dp - 10 + exp >= n) if (dp - 10 + exp >= n)
{ {
/* /*
* the decimal point is behind the last significant * the decimal point is behind the last significant
* digit; the digits in between must be converted to * digit; the digits in between must be converted to

View File

@ -537,7 +537,6 @@ check_foreign_key(PG_FUNCTION_ARGS)
*/ */
for (r = 0; r < nrefs; r++) for (r = 0; r < nrefs; r++)
{ {
/* /*
* For 'R'estrict we may to execute plan for one tuple only, for * For 'R'estrict we may to execute plan for one tuple only, for
* other actions - for all tuples. * other actions - for all tuples.

View File

@ -359,7 +359,6 @@ 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

@ -13,7 +13,6 @@ struct varlena *c_textin(unsigned char *str);
int32 * int32 *
c_charin(unsigned char *str) c_charin(unsigned char *str)
#endif #endif
#endif #endif
/* /*

View File

@ -87,15 +87,17 @@ static const unsigned int crc32tab[256] = {
0xb40bbe37, 0xc30c8ea1, 0x5a05df1b, 0x2d02ef8d, 0xb40bbe37, 0xc30c8ea1, 0x5a05df1b, 0x2d02ef8d,
}; };
unsigned int crc32_sz(char * buf, int size){ unsigned int
crc32_sz(char *buf, int size)
{
unsigned int crc = ~0; unsigned int crc = ~0;
char *p; char *p;
int len, nr; int len,
nr;
len = 0; len = 0;
nr = size; nr = size;
for (len += nr, p = buf; nr--; ++p) { for (len += nr, p = buf; nr--; ++p)
_CRC32_(crc, *p); _CRC32_(crc, *p);
}
return ~crc; return ~crc;
} }

View File

@ -6,5 +6,4 @@ extern unsigned int crc32_sz(char * buf, int size);
/* Returns crc32 of null-terminated string */ /* Returns crc32 of null-terminated string */
#define crc32(buf) crc32_sz((buf),strlen(buf)) #define crc32(buf) crc32_sz((buf),strlen(buf))
#endif #endif

View File

@ -25,6 +25,4 @@
#define FILEPATH 19 #define FILEPATH 19
extern const char *descr[]; extern const char *descr[];
#endif #endif

View File

@ -9,7 +9,8 @@
* signature defines * signature defines
*/ */
#define BITBYTE 8 #define BITBYTE 8
#define SIGLENINT 64 /* >121 => key will toast, so it will not work !!! */ #define SIGLENINT 64 /* >121 => key will toast, so it will not
* work !!! */
#define SIGLEN ( sizeof(int4)*SIGLENINT ) #define SIGLEN ( sizeof(int4)*SIGLENINT )
#define SIGLENBIT (SIGLEN*BITBYTE) #define SIGLENBIT (SIGLEN*BITBYTE)
@ -40,7 +41,8 @@ typedef char *BITVECP;
/* /*
* type of index key * type of index key
*/ */
typedef struct { typedef struct
{
int4 len; int4 len;
int4 flag; int4 flag;
char data[1]; char data[1];
@ -61,4 +63,3 @@ typedef struct {
#define GETARR(x) ( (int4*)( (char*)x+GTHDRSIZE ) ) #define GETARR(x) ( (int4*)( (char*)x+GTHDRSIZE ) )
#define ARRNELEM(x) ( ( ((GISTTYPE*)x)->len - GTHDRSIZE )/sizeof(int4) ) #define ARRNELEM(x) ( ( ((GISTTYPE*)x)->len - GTHDRSIZE )/sizeof(int4) )
#endif #endif

View File

@ -23,7 +23,8 @@
* Return value of init must be malloced in other case * Return value of init must be malloced in other case
* it will be free in end of transaction! * it will be free in end of transaction!
*/ */
typedef struct { typedef struct
{
char localename[LOCALE_NAME_BUFLEN]; char localename[LOCALE_NAME_BUFLEN];
/* init dictionary */ /* init dictionary */
void *(*init) (void); void *(*init) (void);
@ -48,10 +49,12 @@ DICT dicts[] = {
} }
#include "dict.h" #include "dict.h"
}; };
#undef DICT_TABLE #undef DICT_TABLE
/* array for storing dictinary's objects (if needed) */ /* array for storing dictinary's objects (if needed) */
void* dictobjs[ lengthof(dicts) ]; void *dictobjs[
lengthof(dicts)];
#define STOPLEXEM -2 #define STOPLEXEM -2
#define BYLOCALE -1 #define BYLOCALE -1
@ -60,6 +63,7 @@ void* dictobjs[ lengthof(dicts) ];
#define MAXNDICT 2 #define MAXNDICT 2
typedef int2 MAPDICT[MAXNDICT]; typedef int2 MAPDICT[MAXNDICT];
#define GETDICT(x,i) *( ((int2*)(x)) + (i) ) #define GETDICT(x,i) *( ((int2*)(x)) + (i) )
/* map dictionaries for lexem type */ /* map dictionaries for lexem type */
@ -88,38 +92,48 @@ static MAPDICT mapdict[] = {
static bool inited = false; static bool inited = false;
void initmorph(void) { void
int i,j,k; initmorph(void)
{
int i,
j,
k;
MAPDICT *md; MAPDICT *md;
bool needinit[lengthof(dicts)]; bool needinit[lengthof(dicts)];
#ifdef USE_LOCALE #ifdef USE_LOCALE
PG_LocaleCategories lc; PG_LocaleCategories lc;
int bylocaledict = NODICT; int bylocaledict = NODICT;
#endif #endif
if ( inited ) return; if (inited)
return;
for (i = 1; i < lengthof(dicts); i++) for (i = 1; i < lengthof(dicts); i++)
needinit[i] = false; needinit[i] = false;
#ifdef USE_LOCALE #ifdef USE_LOCALE
PGLC_current(&lc); PGLC_current(&lc);
for (i = 1; i < lengthof(dicts); i++) for (i = 1; i < lengthof(dicts); i++)
if (strcmp( dicts[i].localename, lc.lang ) == 0) { if (strcmp(dicts[i].localename, lc.lang) == 0)
{
bylocaledict = i; bylocaledict = i;
break; break;
} }
PGLC_free_categories(&lc); PGLC_free_categories(&lc);
#endif #endif
for(i=1; i<lengthof(mapdict);i++) { for (i = 1; i < lengthof(mapdict); i++)
{
k = 0; k = 0;
md = &mapdict[i]; md = &mapdict[i];
for(j=0;j<MAXNDICT;j++) { for (j = 0; j < MAXNDICT; j++)
{
GETDICT(md, k) = GETDICT(md, j); GETDICT(md, k) = GETDICT(md, j);
if ( GETDICT(md,k) == NODICT ) { if (GETDICT(md, k) == NODICT)
break; break;
} else if ( GETDICT(md,k) == BYLOCALE ) { else if (GETDICT(md, k) == BYLOCALE)
{
#ifdef USE_LOCALE #ifdef USE_LOCALE
if (bylocaledict == NODICT) if (bylocaledict == NODICT)
continue; continue;
@ -146,30 +160,42 @@ void initmorph(void) {
return; return;
} }
char* lemmatize( char* word, int *len, int type ) { char *
lemmatize(char *word, int *len, int type)
{
int2 nd; int2 nd;
int i; int i;
DICT *dict; DICT *dict;
for(i=0;i<MAXNDICT;i++) { for (i = 0; i < MAXNDICT; i++)
{
nd = GETDICT(&mapdict[type], i); nd = GETDICT(&mapdict[type], i);
if ( nd == NODICT ) { if (nd == NODICT)
{
/* there is no dictionary */ /* there is no dictionary */
return word; return word;
} else if ( nd == STOPLEXEM ) { }
else if (nd == STOPLEXEM)
{
/* word is stopword */ /* word is stopword */
return NULL; return NULL;
} else { }
else
{
dict = &dicts[nd]; dict = &dicts[nd];
if (dict->is_stoplemm && (*(dict->is_stoplemm)) (dictobjs[nd], word, *len)) if (dict->is_stoplemm && (*(dict->is_stoplemm)) (dictobjs[nd], word, *len))
return NULL; return NULL;
if ( dict->lemmatize ) { if (dict->lemmatize)
{
int oldlen = *len; int oldlen = *len;
char *newword = (*(dict->lemmatize)) (dictobjs[nd], word, len); char *newword = (*(dict->lemmatize)) (dictobjs[nd], word, len);
/* word is recognized by distionary */ /* word is recognized by distionary */
if ( newword != word || *len != oldlen ) { if (newword != word || *len != oldlen)
{
if (dict->is_stemstoplemm && if (dict->is_stemstoplemm &&
(*(dict->is_stemstoplemm))(dictobjs[nd], word, *len) ) { (*(dict->is_stemstoplemm)) (dictobjs[nd], word, *len))
{
if (newword != word && newword) if (newword != word && newword)
pfree(newword); pfree(newword);
return NULL; return NULL;
@ -183,6 +209,8 @@ char* lemmatize( char* word, int *len, int type ) {
return word; return word;
} }
bool is_stoptype(int type) { bool
is_stoptype(int type)
{
return (GETDICT(&mapdict[type], 0) == STOPLEXEM) ? true : false; return (GETDICT(&mapdict[type], 0) == STOPLEXEM) ? true : false;
} }

View File

@ -7,5 +7,4 @@ int tsearch_yylex(void);
void start_parse_str(char *, int); void start_parse_str(char *, int);
void start_parse_fh(FILE *, int); void start_parse_fh(FILE *, int);
void end_parse(void); void end_parse(void);
#endif #endif

View File

@ -32,13 +32,16 @@
PG_FUNCTION_INFO_V1(mqtxt_in); PG_FUNCTION_INFO_V1(mqtxt_in);
Datum mqtxt_in(PG_FUNCTION_ARGS); Datum mqtxt_in(PG_FUNCTION_ARGS);
PG_FUNCTION_INFO_V1(qtxt_in); PG_FUNCTION_INFO_V1(qtxt_in);
Datum qtxt_in(PG_FUNCTION_ARGS); Datum qtxt_in(PG_FUNCTION_ARGS);
PG_FUNCTION_INFO_V1(qtxt_out); PG_FUNCTION_INFO_V1(qtxt_out);
Datum qtxt_out(PG_FUNCTION_ARGS); Datum qtxt_out(PG_FUNCTION_ARGS);
PG_FUNCTION_INFO_V1(execqtxt); PG_FUNCTION_INFO_V1(execqtxt);
Datum execqtxt(PG_FUNCTION_ARGS); Datum execqtxt(PG_FUNCTION_ARGS);
PG_FUNCTION_INFO_V1(rexecqtxt); PG_FUNCTION_INFO_V1(rexecqtxt);
Datum rexecqtxt(PG_FUNCTION_ARGS); Datum rexecqtxt(PG_FUNCTION_ARGS);
@ -62,7 +65,8 @@ Datum querytree(PG_FUNCTION_ARGS);
* node of query tree, also used * node of query tree, also used
* for storing polish notation in parser * for storing polish notation in parser
*/ */
typedef struct NODE { typedef struct NODE
{
int4 type; int4 type;
int4 val; int4 val;
int2 distance; int2 distance;
@ -70,7 +74,8 @@ typedef struct NODE {
struct NODE *next; struct NODE *next;
} NODE; } NODE;
typedef struct { typedef struct
{
char *buf; char *buf;
int4 state; int4 state;
int4 count; int4 count;
@ -93,43 +98,57 @@ typedef struct {
* get token from query string * get token from query string
*/ */
static int4 static int4
gettoken_query( QPRS_STATE* state, int4* val, int4* lenval, char** strval ) { gettoken_query(QPRS_STATE * state, int4 *val, int4 *lenval, char **strval)
while(1) { {
switch(state->state) { while (1)
{
switch (state->state)
{
case WAITOPERAND: case WAITOPERAND:
if ( *(state->buf) == '!' ) { if (*(state->buf) == '!')
{
(state->buf)++; (state->buf)++;
*val = (int4) '!'; *val = (int4) '!';
return OPR; return OPR;
} else if ( *(state->buf) == '(' ) { }
else if (*(state->buf) == '(')
{
state->count++; state->count++;
(state->buf)++; (state->buf)++;
return OPEN; return OPEN;
} else if ( *(state->buf) != ' ' ) { }
else if (*(state->buf) != ' ')
{
state->valstate.prsbuf = state->buf; state->valstate.prsbuf = state->buf;
state->state = WAITOPERATOR; state->state = WAITOPERATOR;
if ( gettoken_txtidx( &(state->valstate) ) ) { if (gettoken_txtidx(&(state->valstate)))
{
*strval = state->valstate.word; *strval = state->valstate.word;
*lenval = state->valstate.curpos - state->valstate.word; *lenval = state->valstate.curpos - state->valstate.word;
state->buf = state->valstate.prsbuf; state->buf = state->valstate.prsbuf;
return VAL; return VAL;
} else }
else
elog(ERROR, "No operand"); elog(ERROR, "No operand");
} }
break; break;
case WAITOPERATOR: case WAITOPERATOR:
if ( *(state->buf) == '&' || *(state->buf) == '|' ) { if (*(state->buf) == '&' || *(state->buf) == '|')
{
state->state = WAITOPERAND; state->state = WAITOPERAND;
*val = (int4) *(state->buf); *val = (int4) *(state->buf);
(state->buf)++; (state->buf)++;
return OPR; return OPR;
} else if ( *(state->buf) == ')' ) { }
else if (*(state->buf) == ')')
{
(state->buf)++; (state->buf)++;
state->count--; state->count--;
return (state->count < 0) ? ERR : CLOSE; return (state->count < 0) ? ERR : CLOSE;
} else if ( *(state->buf) == '\0' ) { }
else if (*(state->buf) == '\0')
return (state->count) ? ERR : END; return (state->count) ? ERR : END;
} else if ( *(state->buf) != ' ' ) else if (*(state->buf) != ' ')
return ERR; return ERR;
break; break;
default: default:
@ -145,8 +164,10 @@ gettoken_query( QPRS_STATE* state, int4* val, int4* lenval, char** strval ) {
* push new one in polish notation reverse view * push new one in polish notation reverse view
*/ */
static void static void
pushquery( QPRS_STATE *state, int4 type, int4 val, int4 distance, int4 lenval) { pushquery(QPRS_STATE * state, int4 type, int4 val, int4 distance, int4 lenval)
{
NODE *tmp = (NODE *) palloc(sizeof(NODE)); NODE *tmp = (NODE *) palloc(sizeof(NODE));
tmp->type = type; tmp->type = type;
tmp->val = val; tmp->val = val;
if (distance > 0xffff) if (distance > 0xffff)
@ -164,15 +185,18 @@ pushquery( QPRS_STATE *state, int4 type, int4 val, int4 distance, int4 lenval) {
* This function is used for query_txt parsing * This function is used for query_txt parsing
*/ */
static void static void
pushval_asis(QPRS_STATE *state, int type, char* strval, int lenval) { pushval_asis(QPRS_STATE * state, int type, char *strval, int lenval)
{
if (lenval > 0xffff) if (lenval > 0xffff)
elog(ERROR, "Word is too long"); elog(ERROR, "Word is too long");
pushquery(state, type, crc32_sz((uint8 *) strval, lenval), pushquery(state, type, crc32_sz((uint8 *) strval, lenval),
state->curop - state->op, lenval); state->curop - state->op, lenval);
while ( state->curop - state->op + lenval + 1 >= state->lenop ) { while (state->curop - state->op + lenval + 1 >= state->lenop)
{
int4 tmp = state->curop - state->op; int4 tmp = state->curop - state->op;
state->lenop *= 2; state->lenop *= 2;
state->op = (char *) repalloc((void *) state->op, state->lenop); state->op = (char *) repalloc((void *) state->op, state->lenop);
state->curop = state->op + tmp; state->curop = state->op + tmp;
@ -189,25 +213,31 @@ pushval_asis(QPRS_STATE *state, int type, char* strval, int lenval) {
* This function is used for mquery_txt parsing * This function is used for mquery_txt parsing
*/ */
static void static void
pushval_morph(QPRS_STATE *state, int typeval, char* strval, int lenval) { pushval_morph(QPRS_STATE * state, int typeval, char *strval, int lenval)
int4 type, lenlemm; {
int4 type,
lenlemm;
int4 count = 0; int4 count = 0;
char *lemm; char *lemm;
start_parse_str(strval, lenval); start_parse_str(strval, lenval);
while( (type=tsearch_yylex()) != 0 ) { while ((type = tsearch_yylex()) != 0)
if ( tokenlen>0xffff ) { {
if (tokenlen > 0xffff)
{
end_parse(); end_parse();
elog(ERROR, "Word is too long"); elog(ERROR, "Word is too long");
} }
lenlemm = tokenlen; lenlemm = tokenlen;
lemm = lemmatize(token, &lenlemm, type); lemm = lemmatize(token, &lenlemm, type);
if ( lemm ) { if (lemm)
{
pushval_asis(state, VAL, lemm, lenlemm); pushval_asis(state, VAL, lemm, lenlemm);
if ( lemm != token ) pfree(lemm); if (lemm != token)
} else { pfree(lemm);
pushval_asis(state,VALTRUE,0,0);
} }
else
pushval_asis(state, VALTRUE, 0, 0);
if (count) if (count)
pushquery(state, OPR, (int4) '&', 0, 0); pushquery(state, OPR, (int4) '&', 0, 0);
count++; count++;
@ -220,27 +250,33 @@ pushval_morph(QPRS_STATE *state, int typeval, char* strval, int lenval) {
* make polish notaion of query * make polish notaion of query
*/ */
static int4 static int4
makepol(QPRS_STATE *state, void (*pushval)(QPRS_STATE*,int,char*,int)) { makepol(QPRS_STATE * state, void (*pushval) (QPRS_STATE *, int, char *, int))
int4 val,type; {
int4 val,
type;
int4 lenval; int4 lenval;
char *strval; char *strval;
int4 stack[STACKDEPTH]; int4 stack[STACKDEPTH];
int4 lenstack = 0; int4 lenstack = 0;
while( (type=gettoken_query(state, &val, &lenval, &strval))!=END ) { while ((type = gettoken_query(state, &val, &lenval, &strval)) != END)
switch(type) { {
switch (type)
{
case VAL: case VAL:
(*pushval) (state, VAL, strval, lenval); (*pushval) (state, VAL, strval, lenval);
while (lenstack && (stack[lenstack - 1] == (int4) '&' || while (lenstack && (stack[lenstack - 1] == (int4) '&' ||
stack[ lenstack-1 ] == (int4)'!') ) { stack[lenstack - 1] == (int4) '!'))
{
lenstack--; lenstack--;
pushquery(state, OPR, stack[lenstack], 0, 0); pushquery(state, OPR, stack[lenstack], 0, 0);
} }
break; break;
case OPR: case OPR:
if ( lenstack && val == (int4) '|' ) { if (lenstack && val == (int4) '|')
pushquery(state, OPR, val, 0, 0); pushquery(state, OPR, val, 0, 0);
} else { else
{
if (lenstack == STACKDEPTH) if (lenstack == STACKDEPTH)
elog(ERROR, "Stack too short"); elog(ERROR, "Stack too short");
stack[lenstack] = val; stack[lenstack] = val;
@ -248,15 +284,18 @@ makepol(QPRS_STATE *state, void (*pushval)(QPRS_STATE*,int,char*,int)) {
} }
break; break;
case OPEN: case OPEN:
if ( makepol( state, pushval ) == ERR ) return ERR; if (makepol(state, pushval) == ERR)
return ERR;
if (lenstack && (stack[lenstack - 1] == (int4) '&' || if (lenstack && (stack[lenstack - 1] == (int4) '&' ||
stack[ lenstack-1 ] == (int4)'!') ) { stack[lenstack - 1] == (int4) '!'))
{
lenstack--; lenstack--;
pushquery(state, OPR, stack[lenstack], 0, 0); pushquery(state, OPR, stack[lenstack], 0, 0);
} }
break; break;
case CLOSE: case CLOSE:
while ( lenstack ) { while (lenstack)
{
lenstack--; lenstack--;
pushquery(state, OPR, stack[lenstack], 0, 0); pushquery(state, OPR, stack[lenstack], 0, 0);
}; };
@ -269,14 +308,16 @@ makepol(QPRS_STATE *state, void (*pushval)(QPRS_STATE*,int,char*,int)) {
} }
} }
while (lenstack) { while (lenstack)
{
lenstack--; lenstack--;
pushquery(state, OPR, stack[lenstack], 0, 0); pushquery(state, OPR, stack[lenstack], 0, 0);
}; };
return END; return END;
} }
typedef struct { typedef struct
{
WordEntry *arrb; WordEntry *arrb;
WordEntry *arre; WordEntry *arre;
char *values; char *values;
@ -287,7 +328,8 @@ typedef struct {
* compare 2 string values * compare 2 string values
*/ */
static int4 static int4
ValCompare( CHKVAL *chkval, WordEntry *ptr, ITEM *item ) { ValCompare(CHKVAL * chkval, WordEntry * ptr, ITEM * item)
{
if (ptr->len == item->length) if (ptr->len == item->length)
return strncmp( return strncmp(
&(chkval->values[ptr->pos]), &(chkval->values[ptr->pos]),
@ -301,7 +343,8 @@ ValCompare( CHKVAL *chkval, WordEntry *ptr, ITEM *item ) {
* is there value 'val' in array or not ? * is there value 'val' in array or not ?
*/ */
static bool static bool
checkcondition_str( void *checkval, ITEM* val ) { checkcondition_str(void *checkval, ITEM * val)
{
WordEntry *StopLow = ((CHKVAL *) checkval)->arrb; WordEntry *StopLow = ((CHKVAL *) checkval)->arrb;
WordEntry *StopHigh = ((CHKVAL *) checkval)->arre; WordEntry *StopHigh = ((CHKVAL *) checkval)->arre;
WordEntry *StopMiddle; WordEntry *StopMiddle;
@ -309,7 +352,8 @@ checkcondition_str( void *checkval, ITEM* val ) {
/* Loop invariant: StopLow <= val < StopHigh */ /* Loop invariant: StopLow <= val < StopHigh */
while (StopLow < StopHigh) { while (StopLow < StopHigh)
{
StopMiddle = StopLow + (StopHigh - StopLow) / 2; StopMiddle = StopLow + (StopHigh - StopLow) / 2;
difference = ValCompare((CHKVAL *) checkval, StopMiddle, val); difference = ValCompare((CHKVAL *) checkval, StopMiddle, val);
if (difference == 0) if (difference == 0)
@ -327,19 +371,25 @@ checkcondition_str( void *checkval, ITEM* val ) {
* check for boolean condition * check for boolean condition
*/ */
bool bool
execute( ITEM* curitem, void *checkval, bool calcnot, bool (*chkcond)(void *checkval, ITEM *val )) { execute(ITEM * curitem, void *checkval, bool calcnot, bool (*chkcond) (void *checkval, ITEM * val))
if ( curitem->type == VAL ) { {
if (curitem->type == VAL)
return (*chkcond) (checkval, curitem); return (*chkcond) (checkval, curitem);
} else if ( curitem->val == (int4)'!' ) { else if (curitem->val == (int4) '!')
{
return (calcnot) ? return (calcnot) ?
((execute(curitem + 1, checkval, calcnot, chkcond)) ? false : true) ((execute(curitem + 1, checkval, calcnot, chkcond)) ? false : true)
: true; : true;
} else if ( curitem->val == (int4)'&' ) { }
else if (curitem->val == (int4) '&')
{
if (execute(curitem + curitem->left, checkval, calcnot, chkcond)) if (execute(curitem + curitem->left, checkval, calcnot, chkcond))
return execute(curitem + 1, checkval, calcnot, chkcond); return execute(curitem + 1, checkval, calcnot, chkcond);
else else
return false; return false;
} else { /* |-operator */ }
else
{ /* |-operator */
if (execute(curitem + curitem->left, checkval, calcnot, chkcond)) if (execute(curitem + curitem->left, checkval, calcnot, chkcond))
return true; return true;
else else
@ -352,7 +402,8 @@ execute( ITEM* curitem, void *checkval, bool calcnot, bool (*chkcond)(void *chec
* boolean operations * boolean operations
*/ */
Datum Datum
rexecqtxt(PG_FUNCTION_ARGS) { rexecqtxt(PG_FUNCTION_ARGS)
{
return DirectFunctionCall2( return DirectFunctionCall2(
execqtxt, execqtxt,
PG_GETARG_DATUM(1), PG_GETARG_DATUM(1),
@ -361,13 +412,15 @@ rexecqtxt(PG_FUNCTION_ARGS) {
} }
Datum Datum
execqtxt(PG_FUNCTION_ARGS) { execqtxt(PG_FUNCTION_ARGS)
{
txtidx *val = (txtidx *) DatumGetPointer(PG_DETOAST_DATUM(PG_GETARG_DATUM(0))); txtidx *val = (txtidx *) DatumGetPointer(PG_DETOAST_DATUM(PG_GETARG_DATUM(0)));
QUERYTYPE *query = (QUERYTYPE *) DatumGetPointer(PG_DETOAST_DATUM(PG_GETARG_DATUM(1))); QUERYTYPE *query = (QUERYTYPE *) DatumGetPointer(PG_DETOAST_DATUM(PG_GETARG_DATUM(1)));
CHKVAL chkval; CHKVAL chkval;
bool result; bool result;
if ( ! val->size ) { if (!val->size)
{
PG_FREE_IF_COPY(val, 0); PG_FREE_IF_COPY(val, 0);
PG_FREE_IF_COPY(query, 1); PG_FREE_IF_COPY(query, 1);
PG_RETURN_BOOL(false); PG_RETURN_BOOL(false);
@ -393,21 +446,28 @@ execqtxt(PG_FUNCTION_ARGS) {
* find left operand in polish notation view * find left operand in polish notation view
*/ */
static void static void
findoprnd( ITEM *ptr, int4 *pos ) { findoprnd(ITEM * ptr, int4 *pos)
{
#ifdef BS_DEBUG #ifdef BS_DEBUG
elog(NOTICE, (ptr[*pos].type == OPR) ? elog(NOTICE, (ptr[*pos].type == OPR) ?
"%d %c" : "%d %d ", *pos, ptr[*pos].val); "%d %c" : "%d %d ", *pos, ptr[*pos].val);
#endif #endif
if ( ptr[*pos].type == VAL || ptr[*pos].type == VALTRUE ) { if (ptr[*pos].type == VAL || ptr[*pos].type == VALTRUE)
{
ptr[*pos].left = 0; ptr[*pos].left = 0;
(*pos)++; (*pos)++;
} else if ( ptr[*pos].val == (int4)'!' ) { }
else if (ptr[*pos].val == (int4) '!')
{
ptr[*pos].left = 1; ptr[*pos].left = 1;
(*pos)++; (*pos)++;
findoprnd(ptr, pos); findoprnd(ptr, pos);
} else { }
else
{
ITEM *curitem = &ptr[*pos]; ITEM *curitem = &ptr[*pos];
int4 tmp = *pos; int4 tmp = *pos;
(*pos)++; (*pos)++;
findoprnd(ptr, pos); findoprnd(ptr, pos);
curitem->left = *pos - tmp; curitem->left = *pos - tmp;
@ -419,7 +479,9 @@ findoprnd( ITEM *ptr, int4 *pos ) {
/* /*
* input * input
*/ */
static QUERYTYPE *queryin(char *buf, void (*pushval)(QPRS_STATE*,int,char*,int) ) { static QUERYTYPE *
queryin(char *buf, void (*pushval) (QPRS_STATE *, int, char *, int))
{
QPRS_STATE state; QPRS_STATE state;
int4 i; int4 i;
QUERYTYPE *query; QUERYTYPE *query;
@ -427,8 +489,10 @@ static QUERYTYPE *queryin(char *buf, void (*pushval)(QPRS_STATE*,int,char*,int)
ITEM *ptr; ITEM *ptr;
NODE *tmp; NODE *tmp;
int4 pos = 0; int4 pos = 0;
#ifdef BS_DEBUG #ifdef BS_DEBUG
char pbuf[16384],*cur; char pbuf[16384],
*cur;
#endif #endif
/* init state */ /* init state */
@ -463,7 +527,8 @@ static QUERYTYPE *queryin(char *buf, void (*pushval)(QPRS_STATE*,int,char*,int)
ptr = GETQUERY(query); ptr = GETQUERY(query);
/* set item in polish notation */ /* set item in polish notation */
for(i=0; i<state.num; i++ ) { for (i = 0; i < state.num; i++)
{
ptr[i].type = state.str->type; ptr[i].type = state.str->type;
ptr[i].val = state.str->val; ptr[i].val = state.str->val;
ptr[i].distance = state.str->distance; ptr[i].distance = state.str->distance;
@ -484,7 +549,8 @@ static QUERYTYPE *queryin(char *buf, void (*pushval)(QPRS_STATE*,int,char*,int)
#ifdef BS_DEBUG #ifdef BS_DEBUG
cur = pbuf; cur = pbuf;
*cur = '\0'; *cur = '\0';
for( i=0;i<query->size;i++ ) { for (i = 0; i < query->size; i++)
{
if (ptr[i].type == OPR) if (ptr[i].type == OPR)
sprintf(cur, "%c(%d) ", ptr[i].val, ptr[i].left); sprintf(cur, "%c(%d) ", ptr[i].val, ptr[i].left);
else else
@ -501,7 +567,8 @@ static QUERYTYPE *queryin(char *buf, void (*pushval)(QPRS_STATE*,int,char*,int)
* in without morphology * in without morphology
*/ */
Datum Datum
qtxt_in(PG_FUNCTION_ARGS) { qtxt_in(PG_FUNCTION_ARGS)
{
PG_RETURN_POINTER(queryin((char *) PG_GETARG_POINTER(0), pushval_asis)); PG_RETURN_POINTER(queryin((char *) PG_GETARG_POINTER(0), pushval_asis));
} }
@ -509,19 +576,23 @@ qtxt_in(PG_FUNCTION_ARGS) {
* in with morphology * in with morphology
*/ */
Datum Datum
mqtxt_in(PG_FUNCTION_ARGS) { mqtxt_in(PG_FUNCTION_ARGS)
{
QUERYTYPE *query; QUERYTYPE *query;
ITEM *res; ITEM *res;
int4 len; int4 len;
#ifdef BS_DEBUG #ifdef BS_DEBUG
ITEM *ptr; ITEM *ptr;
int4 i; int4 i;
char pbuf[16384],*cur; char pbuf[16384],
*cur;
#endif #endif
initmorph(); initmorph();
query = queryin((char *) PG_GETARG_POINTER(0), pushval_morph); query = queryin((char *) PG_GETARG_POINTER(0), pushval_morph);
res = clean_fakeval(GETQUERY(query), &len); res = clean_fakeval(GETQUERY(query), &len);
if ( ! res ) { if (!res)
{
pfree(query); pfree(query);
PG_RETURN_NULL(); PG_RETURN_NULL();
} }
@ -530,7 +601,8 @@ mqtxt_in(PG_FUNCTION_ARGS) {
cur = pbuf; cur = pbuf;
*cur = '\0'; *cur = '\0';
ptr = GETQUERY(query); ptr = GETQUERY(query);
for( i=0;i<len;i++ ) { for (i = 0; i < len; i++)
{
if (ptr[i].type == OPR) if (ptr[i].type == OPR)
sprintf(cur, "%c(%d) ", ptr[i].val, ptr[i].left); sprintf(cur, "%c(%d) ", ptr[i].val, ptr[i].left);
else else
@ -547,7 +619,8 @@ mqtxt_in(PG_FUNCTION_ARGS) {
/* /*
* out function * out function
*/ */
typedef struct { typedef struct
{
ITEM *curpol; ITEM *curpol;
char *buf; char *buf;
char *cur; char *cur;
@ -569,46 +642,63 @@ while( ( inf->cur - inf->buf ) + addsize + 1 >= inf->buflen ) \
* infix (human-readable) view * infix (human-readable) view
*/ */
static void static void
infix(INFIX *in, bool first) { infix(INFIX * in, bool first)
if ( in->curpol->type == VAL ) { {
if (in->curpol->type == VAL)
{
char *op = in->op + in->curpol->distance; char *op = in->op + in->curpol->distance;
RESIZEBUF(in, in->curpol->length * 2 + 2); RESIZEBUF(in, in->curpol->length * 2 + 2);
*(in->cur) = '\''; in->cur++; *(in->cur) = '\'';
while( *op ) { in->cur++;
if ( *op == '\'' ) { while (*op)
*(in->cur) = '\\'; in->cur++; {
if (*op == '\'')
{
*(in->cur) = '\\';
in->cur++;
} }
*(in->cur) = *op; *(in->cur) = *op;
op++; in->cur++; op++;
in->cur++;
} }
*(in->cur) = '\''; in->cur++; *(in->cur) = '\'';
in->cur++;
*(in->cur) = '\0'; *(in->cur) = '\0';
in->curpol++; in->curpol++;
} else if ( in->curpol->val == (int4)'!' ) { }
else if (in->curpol->val == (int4) '!')
{
bool isopr = false; bool isopr = false;
RESIZEBUF(in, 1); RESIZEBUF(in, 1);
*(in->cur) = '!'; *(in->cur) = '!';
in->cur++; in->cur++;
*(in->cur) = '\0'; *(in->cur) = '\0';
in->curpol++; in->curpol++;
if ( in->curpol->type == OPR ) { if (in->curpol->type == OPR)
{
isopr = true; isopr = true;
RESIZEBUF(in, 2); RESIZEBUF(in, 2);
sprintf(in->cur, "( "); sprintf(in->cur, "( ");
in->cur = strchr(in->cur, '\0'); in->cur = strchr(in->cur, '\0');
} }
infix(in, isopr); infix(in, isopr);
if ( isopr ) { if (isopr)
{
RESIZEBUF(in, 2); RESIZEBUF(in, 2);
sprintf(in->cur, " )"); sprintf(in->cur, " )");
in->cur = strchr(in->cur, '\0'); in->cur = strchr(in->cur, '\0');
} }
} else { }
else
{
int4 op = in->curpol->val; int4 op = in->curpol->val;
INFIX nrm; INFIX nrm;
in->curpol++; in->curpol++;
if ( op == (int4)'|' && ! first) { if (op == (int4) '|' && !first)
{
RESIZEBUF(in, 2); RESIZEBUF(in, 2);
sprintf(in->cur, "( "); sprintf(in->cur, "( ");
in->cur = strchr(in->cur, '\0'); in->cur = strchr(in->cur, '\0');
@ -632,7 +722,8 @@ infix(INFIX *in, bool first) {
in->cur = strchr(in->cur, '\0'); in->cur = strchr(in->cur, '\0');
pfree(nrm.buf); pfree(nrm.buf);
if ( op == (int4)'|' && ! first) { if (op == (int4) '|' && !first)
{
RESIZEBUF(in, 2); RESIZEBUF(in, 2);
sprintf(in->cur, " )"); sprintf(in->cur, " )");
in->cur = strchr(in->cur, '\0'); in->cur = strchr(in->cur, '\0');
@ -642,7 +733,8 @@ infix(INFIX *in, bool first) {
Datum Datum
qtxt_out(PG_FUNCTION_ARGS) { qtxt_out(PG_FUNCTION_ARGS)
{
QUERYTYPE *query = (QUERYTYPE *) DatumGetPointer(PG_DETOAST_DATUM(PG_GETARG_DATUM(0))); QUERYTYPE *query = (QUERYTYPE *) DatumGetPointer(PG_DETOAST_DATUM(PG_GETARG_DATUM(0)));
INFIX nrm; INFIX nrm;
@ -664,7 +756,8 @@ qtxt_out(PG_FUNCTION_ARGS) {
* which will be executed in non-leaf pages in index * which will be executed in non-leaf pages in index
*/ */
Datum Datum
querytree(PG_FUNCTION_ARGS) { querytree(PG_FUNCTION_ARGS)
{
QUERYTYPE *query = (QUERYTYPE *) DatumGetPointer(PG_DETOAST_DATUM(PG_GETARG_DATUM(0))); QUERYTYPE *query = (QUERYTYPE *) DatumGetPointer(PG_DETOAST_DATUM(PG_GETARG_DATUM(0)));
INFIX nrm; INFIX nrm;
text *res; text *res;
@ -677,11 +770,14 @@ querytree(PG_FUNCTION_ARGS) {
q = clean_NOT(GETQUERY(query), &len); q = clean_NOT(GETQUERY(query), &len);
if ( ! q ) { if (!q)
{
res = (text *) palloc(1 + VARHDRSZ); res = (text *) palloc(1 + VARHDRSZ);
VARATT_SIZEP(res) = 1 + VARHDRSZ; VARATT_SIZEP(res) = 1 + VARHDRSZ;
*((char *) VARDATA(res)) = 'T'; *((char *) VARDATA(res)) = 'T';
} else { }
else
{
nrm.curpol = q; nrm.curpol = q;
nrm.buflen = 32; nrm.buflen = 32;
nrm.cur = nrm.buf = (char *) palloc(sizeof(char) * nrm.buflen); nrm.cur = nrm.buf = (char *) palloc(sizeof(char) * nrm.buflen);

View File

@ -9,7 +9,8 @@
* item in polish notation with back link * item in polish notation with back link
* to left operand * to left operand
*/ */
typedef struct ITEM { typedef struct ITEM
{
int2 type; int2 type;
int2 left; int2 left;
int4 val; int4 val;
@ -22,7 +23,8 @@ typedef struct ITEM {
*Storage: *Storage:
* (len)(size)(array of ITEM)(array of operand in user-friendly form) * (len)(size)(array of ITEM)(array of operand in user-friendly form)
*/ */
typedef struct { typedef struct
{
int4 len; int4 len;
int4 size; int4 size;
char data[1]; char data[1];

View File

@ -19,7 +19,8 @@
#include "query.h" #include "query.h"
#include "rewrite.h" #include "rewrite.h"
typedef struct NODE { typedef struct NODE
{
struct NODE *left; struct NODE *left;
struct NODE *right; struct NODE *right;
ITEM *valnode; ITEM *valnode;
@ -29,11 +30,14 @@ typedef struct NODE {
* make query tree from plain view of query * make query tree from plain view of query
*/ */
static NODE * static NODE *
maketree(ITEM *in) { maketree(ITEM * in)
{
NODE *node = (NODE *) palloc(sizeof(NODE)); NODE *node = (NODE *) palloc(sizeof(NODE));
node->valnode = in; node->valnode = in;
node->right = node->left = NULL; node->right = node->left = NULL;
if ( in->type == OPR ) { if (in->type == OPR)
{
node->right = maketree(in + 1); node->right = maketree(in + 1);
if (in->val != (int4) '!') if (in->val != (int4) '!')
node->left = maketree(in + in->left); node->left = maketree(in + in->left);
@ -41,27 +45,34 @@ maketree(ITEM *in) {
return node; return node;
} }
typedef struct { typedef struct
{
ITEM *ptr; ITEM *ptr;
int4 len; int4 len;
int4 cur; int4 cur;
} PLAINTREE; } PLAINTREE;
static void static void
plainnode(PLAINTREE *state, NODE* node) { plainnode(PLAINTREE * state, NODE * node)
if ( state->cur == state->len ) { {
if (state->cur == state->len)
{
state->len *= 2; state->len *= 2;
state->ptr = (ITEM *) repalloc((void *) state->ptr, state->len * sizeof(ITEM)); state->ptr = (ITEM *) repalloc((void *) state->ptr, state->len * sizeof(ITEM));
} }
memcpy((void *) &(state->ptr[state->cur]), (void *) node->valnode, sizeof(ITEM)); memcpy((void *) &(state->ptr[state->cur]), (void *) node->valnode, sizeof(ITEM));
if ( node->valnode->type == VAL ) { if (node->valnode->type == VAL)
state->cur++; state->cur++;
} else if ( node->valnode->val == (int4)'!' ) { else if (node->valnode->val == (int4) '!')
{
state->ptr[state->cur].left = 1; state->ptr[state->cur].left = 1;
state->cur++; state->cur++;
plainnode(state, node->right); plainnode(state, node->right);
} else { }
else
{
int4 cur = state->cur; int4 cur = state->cur;
state->cur++; state->cur++;
plainnode(state, node->right); plainnode(state, node->right);
state->ptr[cur].left = state->cur - cur; state->ptr[cur].left = state->cur - cur;
@ -74,25 +85,32 @@ plainnode(PLAINTREE *state, NODE* node) {
* make plain view of tree from 'normal' view of tree * make plain view of tree from 'normal' view of tree
*/ */
static ITEM * static ITEM *
plaintree(NODE *root, int4 *len) { plaintree(NODE * root, int4 *len)
{
PLAINTREE pl; PLAINTREE pl;
pl.cur = 0; pl.cur = 0;
pl.len = 16; pl.len = 16;
if ( root && (root->valnode->type == VAL || root->valnode->type == OPR) ) { if (root && (root->valnode->type == VAL || root->valnode->type == OPR))
{
pl.ptr = (ITEM *) palloc(pl.len * sizeof(ITEM)); pl.ptr = (ITEM *) palloc(pl.len * sizeof(ITEM));
plainnode(&pl, root); plainnode(&pl, root);
} else {
pl.ptr = NULL;
} }
else
pl.ptr = NULL;
*len = pl.cur; *len = pl.cur;
return pl.ptr; return pl.ptr;
} }
static void static void
freetree(NODE *node) { freetree(NODE * node)
if ( !node ) return; {
if ( node->left ) freetree(node->left); if (!node)
if ( node->right ) freetree(node->right); return;
if (node->left)
freetree(node->left);
if (node->right)
freetree(node->right);
pfree(node); pfree(node);
} }
@ -103,33 +121,45 @@ freetree(NODE *node) {
* Operator ! always return TRUE * Operator ! always return TRUE
*/ */
static NODE * static NODE *
clean_NOT_intree( NODE* node ) { clean_NOT_intree(NODE * node)
{
if (node->valnode->type == VAL) if (node->valnode->type == VAL)
return node; return node;
if ( node->valnode->val == (int4)'!' ) { if (node->valnode->val == (int4) '!')
{
freetree(node); freetree(node);
return NULL; return NULL;
} }
/* operator & or | */ /* operator & or | */
if ( node->valnode->val == (int4)'|' ) { if (node->valnode->val == (int4) '|')
{
if ((node->left = clean_NOT_intree(node->left)) == NULL || if ((node->left = clean_NOT_intree(node->left)) == NULL ||
(node->right=clean_NOT_intree(node->right)) == NULL ) { (node->right = clean_NOT_intree(node->right)) == NULL)
{
freetree(node); freetree(node);
return NULL; return NULL;
} }
} else { }
else
{
NODE *res = node; NODE *res = node;
node->left = clean_NOT_intree(node->left); node->left = clean_NOT_intree(node->left);
node->right = clean_NOT_intree(node->right); node->right = clean_NOT_intree(node->right);
if ( node->left == NULL && node->right == NULL ) { if (node->left == NULL && node->right == NULL)
{
pfree(node); pfree(node);
res = NULL; res = NULL;
} else if ( node->left == NULL ) { }
else if (node->left == NULL)
{
res = node->right; res = node->right;
pfree(node); pfree(node);
} else if ( node->right == NULL ) { }
else if (node->right == NULL)
{
res = node->left; res = node->left;
pfree(node); pfree(node);
} }
@ -139,8 +169,10 @@ clean_NOT_intree( NODE* node ) {
} }
ITEM * ITEM *
clean_NOT(ITEM* ptr, int4 *len) { clean_NOT(ITEM * ptr, int4 *len)
{
NODE *root = maketree(ptr); NODE *root = maketree(ptr);
return plaintree(clean_NOT_intree(root), len); return plaintree(clean_NOT_intree(root), len);
} }
@ -153,60 +185,86 @@ clean_NOT(ITEM* ptr, int4 *len) {
* text (stopword) * text (stopword)
*/ */
static NODE * static NODE *
clean_fakeval_intree( NODE* node, char *result ) { clean_fakeval_intree(NODE * node, char *result)
char lresult = V_UNKNOWN, rresult = V_UNKNOWN; {
char lresult = V_UNKNOWN,
rresult = V_UNKNOWN;
if (node->valnode->type == VAL) if (node->valnode->type == VAL)
return node; return node;
else if ( node->valnode->type == VALTRUE ) { else if (node->valnode->type == VALTRUE)
{
pfree(node); pfree(node);
*result = V_TRUE; *result = V_TRUE;
return NULL; return NULL;
} }
if ( node->valnode->val == (int4)'!' ) { if (node->valnode->val == (int4) '!')
{
node->right = clean_fakeval_intree(node->right, &rresult); node->right = clean_fakeval_intree(node->right, &rresult);
if ( ! node->right ) { if (!node->right)
{
*result = (rresult == V_TRUE) ? V_FALSE : V_TRUE; *result = (rresult == V_TRUE) ? V_FALSE : V_TRUE;
freetree(node); freetree(node);
return NULL; return NULL;
} }
} else if ( node->valnode->val == (int4)'|' ) { }
else if (node->valnode->val == (int4) '|')
{
NODE *res = node; NODE *res = node;
node->left = clean_fakeval_intree(node->left, &lresult); node->left = clean_fakeval_intree(node->left, &lresult);
node->right = clean_fakeval_intree(node->right, &rresult); node->right = clean_fakeval_intree(node->right, &rresult);
if ( lresult == V_TRUE || rresult == V_TRUE ) { if (lresult == V_TRUE || rresult == V_TRUE)
{
freetree(node); freetree(node);
*result = V_TRUE; *result = V_TRUE;
return NULL; return NULL;
} else if ( lresult == V_FALSE && rresult == V_FALSE ) { }
else if (lresult == V_FALSE && rresult == V_FALSE)
{
freetree(node); freetree(node);
*result = V_FALSE; *result = V_FALSE;
return NULL; return NULL;
} else if ( lresult == V_FALSE ) { }
else if (lresult == V_FALSE)
{
res = node->right; res = node->right;
pfree(node); pfree(node);
} else if ( rresult == V_FALSE ) { }
else if (rresult == V_FALSE)
{
res = node->left; res = node->left;
pfree(node); pfree(node);
} }
return res; return res;
} else { }
else
{
NODE *res = node; NODE *res = node;
node->left = clean_fakeval_intree(node->left, &lresult); node->left = clean_fakeval_intree(node->left, &lresult);
node->right = clean_fakeval_intree(node->right, &rresult); node->right = clean_fakeval_intree(node->right, &rresult);
if ( lresult == V_FALSE || rresult == V_FALSE ) { if (lresult == V_FALSE || rresult == V_FALSE)
{
freetree(node); freetree(node);
*result = V_FALSE; *result = V_FALSE;
return NULL; return NULL;
} else if ( lresult == V_TRUE && rresult == V_TRUE ) { }
else if (lresult == V_TRUE && rresult == V_TRUE)
{
freetree(node); freetree(node);
*result = V_TRUE; *result = V_TRUE;
return NULL; return NULL;
} else if ( lresult == V_TRUE ) { }
else if (lresult == V_TRUE)
{
res = node->right; res = node->right;
pfree(node); pfree(node);
} else if ( rresult == V_TRUE ) { }
else if (rresult == V_TRUE)
{
res = node->left; res = node->left;
pfree(node); pfree(node);
} }
@ -216,13 +274,15 @@ clean_fakeval_intree( NODE* node, char *result ) {
} }
ITEM * ITEM *
clean_fakeval(ITEM* ptr, int4 *len) { clean_fakeval(ITEM * ptr, int4 *len)
{
NODE *root = maketree(ptr); NODE *root = maketree(ptr);
char result = V_UNKNOWN; char result = V_UNKNOWN;
NODE *resroot; NODE *resroot;
resroot = clean_fakeval_intree(root, &result); resroot = clean_fakeval_intree(root, &result);
if ( result != V_UNKNOWN ) { if (result != V_UNKNOWN)
{
elog(ERROR, "Your query contained only stopword(s), ignored"); elog(ERROR, "Your query contained only stopword(s), ignored");
*len = 0; *len = 0;
return NULL; return NULL;
@ -230,5 +290,3 @@ clean_fakeval(ITEM* ptr, int4 *len) {
return plaintree(resroot, len); return plaintree(resroot, len);
} }

View File

@ -3,5 +3,4 @@
ITEM *clean_NOT(ITEM * ptr, int4 *len); ITEM *clean_NOT(ITEM * ptr, int4 *len);
ITEM *clean_fakeval(ITEM * ptr, int4 *len); ITEM *clean_fakeval(ITEM * ptr, int4 *len);
#endif #endif

View File

@ -28,6 +28,7 @@
PG_FUNCTION_INFO_V1(txtidx_in); PG_FUNCTION_INFO_V1(txtidx_in);
Datum txtidx_in(PG_FUNCTION_ARGS); Datum txtidx_in(PG_FUNCTION_ARGS);
PG_FUNCTION_INFO_V1(txtidx_out); PG_FUNCTION_INFO_V1(txtidx_out);
Datum txtidx_out(PG_FUNCTION_ARGS); Datum txtidx_out(PG_FUNCTION_ARGS);
@ -45,8 +46,10 @@ Datum txtidxsize(PG_FUNCTION_ARGS);
*/ */
static char *BufferStr; static char *BufferStr;
static int static int
compareentry( const void * a, const void * b ) { compareentry(const void *a, const void *b)
if ( ((WordEntry*)a)->len == ((WordEntry*)b)->len ) { {
if (((WordEntry *) a)->len == ((WordEntry *) b)->len)
{
return strncmp( return strncmp(
&BufferStr[((WordEntry *) a)->pos], &BufferStr[((WordEntry *) a)->pos],
&BufferStr[((WordEntry *) b)->pos], &BufferStr[((WordEntry *) b)->pos],
@ -56,8 +59,10 @@ compareentry( const void * a, const void * b ) {
} }
static int static int
uniqueentry( WordEntry* a, int4 l, char *buf, int4 *outbuflen ) { uniqueentry(WordEntry * a, int4 l, char *buf, int4 *outbuflen)
WordEntry *ptr, *res; {
WordEntry *ptr,
*res;
res = a; res = a;
*outbuflen = res->len; *outbuflen = res->len;
@ -69,9 +74,11 @@ uniqueentry( WordEntry* a, int4 l, char *buf, int4 *outbuflen ) {
qsort((void *) a, l, sizeof(int4), compareentry); qsort((void *) a, l, sizeof(int4), compareentry);
*outbuflen = res->len; *outbuflen = res->len;
while (ptr - a < l) { while (ptr - a < l)
{
if (!(ptr->len == res->len && if (!(ptr->len == res->len &&
strncmp(&buf[ ptr->pos ], &buf[ res->pos ],res->len) == 0 ) ) { strncmp(&buf[ptr->pos], &buf[res->pos], res->len) == 0))
{
res++; res++;
res->len = ptr->len; res->len = ptr->len;
res->pos = ptr->pos; res->pos = ptr->pos;
@ -100,73 +107,97 @@ do { \
} while (0) } while (0)
int4 int4
gettoken_txtidx( TI_IN_STATE *state ) { gettoken_txtidx(TI_IN_STATE * state)
{
int4 oldstate = 0; int4 oldstate = 0;
state->curpos = state->word; state->curpos = state->word;
state->state = WAITWORD; state->state = WAITWORD;
while( 1 ) { while (1)
if ( state->state == WAITWORD ) { {
if ( *(state->prsbuf) == '\0' ) { if (state->state == WAITWORD)
{
if (*(state->prsbuf) == '\0')
return 0; return 0;
} else if ( *(state->prsbuf) == '\'' ) { else if (*(state->prsbuf) == '\'')
state->state = WAITENDCMPLX; state->state = WAITENDCMPLX;
} else if ( *(state->prsbuf) == '\\' ) { else if (*(state->prsbuf) == '\\')
{
state->state = WAITNEXTCHAR; state->state = WAITNEXTCHAR;
oldstate = WAITENDWORD; oldstate = WAITENDWORD;
} else if ( state->oprisdelim && ISOPERATOR( *(state->prsbuf) ) ) { }
else if (state->oprisdelim && ISOPERATOR(*(state->prsbuf)))
elog(ERROR, "Syntax error"); elog(ERROR, "Syntax error");
} else if ( *(state->prsbuf) != ' ' ) { else if (*(state->prsbuf) != ' ')
{
*(state->curpos) = *(state->prsbuf); *(state->curpos) = *(state->prsbuf);
state->curpos++; state->curpos++;
state->state = WAITENDWORD; state->state = WAITENDWORD;
} }
} else if ( state->state == WAITNEXTCHAR ) { }
if ( *(state->prsbuf) == '\0' ) { else if (state->state == WAITNEXTCHAR)
{
if (*(state->prsbuf) == '\0')
elog(ERROR, "There is no escaped character"); elog(ERROR, "There is no escaped character");
} else { else
{
RESIZEPRSBUF; RESIZEPRSBUF;
*(state->curpos) = *(state->prsbuf); *(state->curpos) = *(state->prsbuf);
state->curpos++; state->curpos++;
state->state = oldstate; state->state = oldstate;
} }
} else if ( state->state == WAITENDWORD ) { }
if ( *(state->prsbuf) == '\\' ) { else if (state->state == WAITENDWORD)
{
if (*(state->prsbuf) == '\\')
{
state->state = WAITNEXTCHAR; state->state = WAITNEXTCHAR;
oldstate = WAITENDWORD; oldstate = WAITENDWORD;
} else if ( *(state->prsbuf) == ' ' || *(state->prsbuf) == '\0' || }
( state->oprisdelim && ISOPERATOR( *(state->prsbuf) ) ) ) { else if (*(state->prsbuf) == ' ' || *(state->prsbuf) == '\0' ||
(state->oprisdelim && ISOPERATOR(*(state->prsbuf))))
{
RESIZEPRSBUF; RESIZEPRSBUF;
if (state->curpos == state->word) if (state->curpos == state->word)
elog(ERROR, "Syntax error"); elog(ERROR, "Syntax error");
*(state->curpos) = '\0'; *(state->curpos) = '\0';
return 1; return 1;
} else { }
else
{
RESIZEPRSBUF; RESIZEPRSBUF;
*(state->curpos) = *(state->prsbuf); *(state->curpos) = *(state->prsbuf);
state->curpos++; state->curpos++;
} }
} else if ( state->state == WAITENDCMPLX ) { }
if ( *(state->prsbuf) == '\'' ) { else if (state->state == WAITENDCMPLX)
{
if (*(state->prsbuf) == '\'')
{
RESIZEPRSBUF; RESIZEPRSBUF;
*(state->curpos) = '\0'; *(state->curpos) = '\0';
if (state->curpos == state->word) if (state->curpos == state->word)
elog(ERROR, "Syntax error"); elog(ERROR, "Syntax error");
state->prsbuf++; state->prsbuf++;
return 1; return 1;
} else if ( *(state->prsbuf) == '\\' ) { }
else if (*(state->prsbuf) == '\\')
{
state->state = WAITNEXTCHAR; state->state = WAITNEXTCHAR;
oldstate = WAITENDCMPLX; oldstate = WAITENDCMPLX;
} else if ( *(state->prsbuf) == '\0' ) { }
else if (*(state->prsbuf) == '\0')
elog(ERROR, "Syntax error"); elog(ERROR, "Syntax error");
} else { else
{
RESIZEPRSBUF; RESIZEPRSBUF;
*(state->curpos) = *(state->prsbuf); *(state->curpos) = *(state->prsbuf);
state->curpos++; state->curpos++;
} }
} else {
elog(ERROR, "Inner bug :(");
} }
else
elog(ERROR, "Inner bug :(");
state->prsbuf++; state->prsbuf++;
} }
@ -174,14 +205,18 @@ gettoken_txtidx( TI_IN_STATE *state ) {
} }
Datum Datum
txtidx_in(PG_FUNCTION_ARGS) { txtidx_in(PG_FUNCTION_ARGS)
{
char *buf = (char *) PG_GETARG_POINTER(0); char *buf = (char *) PG_GETARG_POINTER(0);
TI_IN_STATE state; TI_IN_STATE state;
WordEntry *arr; WordEntry *arr;
int4 len=0, totallen = 64; int4 len = 0,
totallen = 64;
txtidx *in; txtidx *in;
char *tmpbuf, *cur; char *tmpbuf,
int4 i,buflen = 256; *cur;
int4 i,
buflen = 256;
state.prsbuf = buf; state.prsbuf = buf;
state.len = 32; state.len = 32;
@ -190,13 +225,17 @@ txtidx_in(PG_FUNCTION_ARGS) {
arr = (WordEntry *) palloc(sizeof(WordEntry) * totallen); arr = (WordEntry *) palloc(sizeof(WordEntry) * totallen);
cur = tmpbuf = (char *) palloc(buflen); cur = tmpbuf = (char *) palloc(buflen);
while( gettoken_txtidx( &state ) ) { while (gettoken_txtidx(&state))
if ( len == totallen ) { {
if (len == totallen)
{
totallen *= 2; totallen *= 2;
arr = (WordEntry *) repalloc((void *) arr, sizeof(int4) * totallen); arr = (WordEntry *) repalloc((void *) arr, sizeof(int4) * totallen);
} }
while ( cur-tmpbuf + state.curpos - state.word >= buflen ) { while (cur - tmpbuf + state.curpos - state.word >= buflen)
{
int4 dist = cur - tmpbuf; int4 dist = cur - tmpbuf;
buflen *= 2; buflen *= 2;
tmpbuf = (char *) repalloc((void *) tmpbuf, buflen); tmpbuf = (char *) repalloc((void *) tmpbuf, buflen);
cur = tmpbuf + dist; cur = tmpbuf + dist;
@ -222,7 +261,8 @@ txtidx_in(PG_FUNCTION_ARGS) {
in->len = totallen; in->len = totallen;
in->size = len; in->size = len;
cur = STRPTR(in); cur = STRPTR(in);
for(i=0;i<len;i++) { for (i = 0; i < len; i++)
{
memcpy((void *) cur, (void *) &tmpbuf[arr[i].pos], arr[i].len); memcpy((void *) cur, (void *) &tmpbuf[arr[i].pos], arr[i].len);
arr[i].pos = cur - STRPTR(in); arr[i].pos = cur - STRPTR(in);
cur += arr[i].len; cur += arr[i].len;
@ -234,31 +274,41 @@ txtidx_in(PG_FUNCTION_ARGS) {
} }
Datum Datum
txtidxsize(PG_FUNCTION_ARGS) { txtidxsize(PG_FUNCTION_ARGS)
{
txtidx *in = (txtidx *) DatumGetPointer(PG_DETOAST_DATUM(PG_GETARG_DATUM(0))); txtidx *in = (txtidx *) DatumGetPointer(PG_DETOAST_DATUM(PG_GETARG_DATUM(0)));
int4 ret = in->size; int4 ret = in->size;
PG_FREE_IF_COPY(in, 0); PG_FREE_IF_COPY(in, 0);
PG_RETURN_INT32(ret); PG_RETURN_INT32(ret);
} }
Datum Datum
txtidx_out(PG_FUNCTION_ARGS) { txtidx_out(PG_FUNCTION_ARGS)
{
txtidx *out = (txtidx *) DatumGetPointer(PG_DETOAST_DATUM(PG_GETARG_DATUM(0))); txtidx *out = (txtidx *) DatumGetPointer(PG_DETOAST_DATUM(PG_GETARG_DATUM(0)));
char *outbuf; char *outbuf;
int4 i,j,lenbuf = STRSIZE(out) + 1 /* \0 */ + out->size*2 /* '' */ + out->size - 1 /* space */; int4 i,
j,
lenbuf = STRSIZE(out) + 1 /* \0 */ + out->size * 2 /* '' */ + out->size - 1 /* space */ ;
WordEntry *ptr = ARRPTR(out); WordEntry *ptr = ARRPTR(out);
char *curin, *curout; char *curin,
*curout;
curout = outbuf = (char *) palloc(lenbuf); curout = outbuf = (char *) palloc(lenbuf);
for(i=0;i<out->size;i++) { for (i = 0; i < out->size; i++)
{
curin = STRPTR(out) + ptr->pos; curin = STRPTR(out) + ptr->pos;
if (i != 0) if (i != 0)
*curout++ = ' '; *curout++ = ' ';
*curout++ = '\''; *curout++ = '\'';
j = ptr->len; j = ptr->len;
while( j-- ) { while (j--)
if ( *curin == '\'' ) { {
if (*curin == '\'')
{
int4 pos = curout - outbuf; int4 pos = curout - outbuf;
outbuf = (char *) repalloc((void *) outbuf, ++lenbuf); outbuf = (char *) repalloc((void *) outbuf, ++lenbuf);
curout = outbuf + pos; curout = outbuf + pos;
*curout++ = '\\'; *curout++ = '\\';
@ -273,12 +323,14 @@ txtidx_out(PG_FUNCTION_ARGS) {
PG_RETURN_POINTER(outbuf); PG_RETURN_POINTER(outbuf);
} }
typedef struct { typedef struct
{
uint16 len; uint16 len;
char *word; char *word;
} WORD; } WORD;
typedef struct { typedef struct
{
WORD *words; WORD *words;
int4 lenwords; int4 lenwords;
int4 curwords; int4 curwords;
@ -288,18 +340,24 @@ typedef struct {
* Parse text to lexems * Parse text to lexems
*/ */
static void static void
parsetext( PRSTEXT *prs, char *buf, int4 buflen ) { parsetext(PRSTEXT * prs, char *buf, int4 buflen)
int type,lenlemm; {
char *ptr,*ptrw; int type,
lenlemm;
char *ptr,
*ptrw;
char *lemm; char *lemm;
start_parse_str(buf, buflen); start_parse_str(buf, buflen);
while( (type=tsearch_yylex()) != 0 ) { while ((type = tsearch_yylex()) != 0)
if ( prs->curwords == prs->lenwords ) { {
if (prs->curwords == prs->lenwords)
{
prs->lenwords *= 2; prs->lenwords *= 2;
prs->words = (WORD *) repalloc((void *) prs->words, prs->lenwords * sizeof(WORD)); prs->words = (WORD *) repalloc((void *) prs->words, prs->lenwords * sizeof(WORD));
} }
if ( tokenlen>0xffff ) { if (tokenlen > 0xffff)
{
end_parse(); end_parse();
elog(ERROR, "Word is too long"); elog(ERROR, "Word is too long");
} }
@ -310,16 +368,21 @@ parsetext( PRSTEXT *prs, char *buf, int4 buflen ) {
if (!lemm) if (!lemm)
continue; continue;
if ( lemm != token ) { if (lemm != token)
{
prs->words[prs->curwords].len = lenlemm; prs->words[prs->curwords].len = lenlemm;
prs->words[prs->curwords].word = lemm; prs->words[prs->curwords].word = lemm;
} else { }
else
{
prs->words[prs->curwords].len = lenlemm; prs->words[prs->curwords].len = lenlemm;
ptrw = prs->words[prs->curwords].word = (char *) palloc(lenlemm); ptrw = prs->words[prs->curwords].word = (char *) palloc(lenlemm);
ptr = token; ptr = token;
while( ptr-token < lenlemm ) { while (ptr - token < lenlemm)
{
*ptrw = tolower((unsigned char) *ptr); *ptrw = tolower((unsigned char) *ptr);
ptr++; ptrw++; ptr++;
ptrw++;
} }
} }
prs->curwords++; prs->curwords++;
@ -328,7 +391,8 @@ parsetext( PRSTEXT *prs, char *buf, int4 buflen ) {
} }
static int static int
compareWORD( const void * a, const void * b ) { compareWORD(const void *a, const void *b)
{
if (((WORD *) a)->len == ((WORD *) b)->len) if (((WORD *) a)->len == ((WORD *) b)->len)
return strncmp( return strncmp(
((WORD *) a)->word, ((WORD *) a)->word,
@ -338,8 +402,10 @@ compareWORD( const void * a, const void * b ) {
} }
static int static int
uniqueWORD( WORD* a, int4 l ) { uniqueWORD(WORD * a, int4 l)
WORD *ptr, *res; {
WORD *ptr,
*res;
if (l == 1) if (l == 1)
return l; return l;
@ -349,15 +415,17 @@ uniqueWORD( WORD* a, int4 l ) {
qsort((void *) a, l, sizeof(WORD), compareWORD); qsort((void *) a, l, sizeof(WORD), compareWORD);
while (ptr - a < l) { while (ptr - a < l)
{
if (!(ptr->len == res->len && if (!(ptr->len == res->len &&
strncmp(ptr->word, res->word ,res->len) == 0 ) ) { strncmp(ptr->word, res->word, res->len) == 0))
{
res++; res++;
res->len = ptr->len; res->len = ptr->len;
res->word = ptr->word; res->word = ptr->word;
} else {
pfree(ptr->word);
} }
else
pfree(ptr->word);
ptr++; ptr++;
} }
@ -368,11 +436,15 @@ uniqueWORD( WORD* a, int4 l ) {
* make value of txtidx * make value of txtidx
*/ */
static txtidx * static txtidx *
makevalue( PRSTEXT *prs ) { makevalue(PRSTEXT * prs)
int4 i, lenstr=0, totallen; {
int4 i,
lenstr = 0,
totallen;
txtidx *in; txtidx *in;
WordEntry *ptr; WordEntry *ptr;
char *str,*cur; char *str,
*cur;
prs->curwords = uniqueWORD(prs->words, prs->curwords); prs->curwords = uniqueWORD(prs->words, prs->curwords);
for (i = 0; i < prs->curwords; i++) for (i = 0; i < prs->curwords; i++)
@ -385,7 +457,8 @@ makevalue( PRSTEXT *prs ) {
ptr = ARRPTR(in); ptr = ARRPTR(in);
cur = str = STRPTR(in); cur = str = STRPTR(in);
for(i=0;i<prs->curwords;i++) { for (i = 0; i < prs->curwords; i++)
{
ptr->len = prs->words[i].len; ptr->len = prs->words[i].len;
if (cur - str > 0xffff) if (cur - str > 0xffff)
elog(ERROR, "Value is too big"); elog(ERROR, "Value is too big");
@ -400,7 +473,8 @@ makevalue( PRSTEXT *prs ) {
} }
Datum Datum
txt2txtidx(PG_FUNCTION_ARGS) { txt2txtidx(PG_FUNCTION_ARGS)
{
text *in = (text *) DatumGetPointer(PG_DETOAST_DATUM(PG_GETARG_DATUM(0))); text *in = (text *) DatumGetPointer(PG_DETOAST_DATUM(PG_GETARG_DATUM(0)));
PRSTEXT prs; PRSTEXT prs;
txtidx *out = NULL; txtidx *out = NULL;
@ -413,7 +487,8 @@ txt2txtidx(PG_FUNCTION_ARGS) {
parsetext(&prs, VARDATA(in), VARSIZE(in) - VARHDRSZ); parsetext(&prs, VARDATA(in), VARSIZE(in) - VARHDRSZ);
PG_FREE_IF_COPY(in, 0); PG_FREE_IF_COPY(in, 0);
if ( prs.curwords ) { if (prs.curwords)
{
out = makevalue(&prs); out = makevalue(&prs);
PG_RETURN_POINTER(out); PG_RETURN_POINTER(out);
} }
@ -425,12 +500,14 @@ txt2txtidx(PG_FUNCTION_ARGS) {
* Trigger * Trigger
*/ */
Datum Datum
tsearch(PG_FUNCTION_ARGS) { tsearch(PG_FUNCTION_ARGS)
{
TriggerData *trigdata; TriggerData *trigdata;
Trigger *trigger; Trigger *trigger;
Relation rel; Relation rel;
HeapTuple rettuple = NULL; HeapTuple rettuple = NULL;
int numidxattr,i; int numidxattr,
i;
PRSTEXT prs; PRSTEXT prs;
Datum datum = (Datum) 0; Datum datum = (Datum) 0;
@ -467,15 +544,18 @@ tsearch(PG_FUNCTION_ARGS) {
initmorph(); initmorph();
/* find all words in indexable column */ /* find all words in indexable column */
for(i=1; i<trigger->tgnargs; i++) { for (i = 1; i < trigger->tgnargs; i++)
{
int4 numattr; int4 numattr;
text *txt_toasted, *txt; text *txt_toasted,
*txt;
bool isnull; bool isnull;
Oid oidtype; Oid oidtype;
numattr = SPI_fnumber(rel->rd_att, trigger->tgargs[i]); numattr = SPI_fnumber(rel->rd_att, trigger->tgargs[i]);
oidtype = SPI_gettypeid(rel->rd_att, numattr); oidtype = SPI_gettypeid(rel->rd_att, numattr);
if ( numattr<0 || ( ! ( oidtype==TEXTOID || oidtype==VARCHAROID ) ) ) { if (numattr < 0 || (!(oidtype == TEXTOID || oidtype == VARCHAROID)))
{
elog(NOTICE, "TSearch: can not find field '%s'", trigger->tgargs[i]); elog(NOTICE, "TSearch: can not find field '%s'", trigger->tgargs[i]);
continue; continue;
} }
@ -490,13 +570,17 @@ tsearch(PG_FUNCTION_ARGS) {
} }
/* make txtidx value */ /* make txtidx value */
if (prs.curwords) { if (prs.curwords)
{
datum = PointerGetDatum(makevalue(&prs)); datum = PointerGetDatum(makevalue(&prs));
rettuple = SPI_modifytuple(rel, rettuple, 1, &numidxattr, rettuple = SPI_modifytuple(rel, rettuple, 1, &numidxattr,
&datum, NULL); &datum, NULL);
pfree(DatumGetPointer(datum)); pfree(DatumGetPointer(datum));
} else { }
else
{
char nulls = 'n'; char nulls = 'n';
pfree(prs.words); pfree(prs.words);
rettuple = SPI_modifytuple(rel, rettuple, 1, &numidxattr, rettuple = SPI_modifytuple(rel, rettuple, 1, &numidxattr,
&datum, &nulls); &datum, &nulls);
@ -507,4 +591,3 @@ tsearch(PG_FUNCTION_ARGS) {
return PointerGetDatum(rettuple); return PointerGetDatum(rettuple);
} }

View File

@ -14,12 +14,14 @@
#include "utils/builtins.h" #include "utils/builtins.h"
#include "storage/bufpage.h" #include "storage/bufpage.h"
typedef struct { typedef struct
{
uint16 len; uint16 len;
uint16 pos; uint16 pos;
} WordEntry; } WordEntry;
typedef struct { typedef struct
{
int4 len; int4 len;
int4 size; int4 size;
char data[1]; char data[1];
@ -31,7 +33,8 @@ typedef struct {
#define STRPTR(x) ( (char*)x + DATAHDRSIZE + ( sizeof(WordEntry) * ((txtidx*)x)->size ) ) #define STRPTR(x) ( (char*)x + DATAHDRSIZE + ( sizeof(WordEntry) * ((txtidx*)x)->size ) )
#define STRSIZE(x) ( ((txtidx*)x)->len - DATAHDRSIZE - ( sizeof(WordEntry) * ((txtidx*)x)->size ) ) #define STRSIZE(x) ( ((txtidx*)x)->len - DATAHDRSIZE - ( sizeof(WordEntry) * ((txtidx*)x)->size ) )
typedef struct { typedef struct
{
char *prsbuf; char *prsbuf;
char *word; char *word;
char *curpos; char *curpos;
@ -41,6 +44,4 @@ typedef struct {
} TI_IN_STATE; } TI_IN_STATE;
int4 gettoken_txtidx(TI_IN_STATE * state); int4 gettoken_txtidx(TI_IN_STATE * state);
#endif #endif

View File

@ -8,7 +8,6 @@ int user_write_unlock(unsigned int id1, unsigned int id2);
int user_write_lock_oid(Oid oid); int user_write_lock_oid(Oid oid);
int user_write_unlock_oid(Oid oid); int user_write_unlock_oid(Oid oid);
int user_unlock_all(void); int user_unlock_all(void);
#endif #endif
/* /*

View File

@ -14,32 +14,39 @@ XML_Memory_Handling_Suite mhs;
/* passthrough functions (palloc is a macro) */ /* passthrough functions (palloc is a macro) */
static void *pgxml_palloc(size_t size) static void *
pgxml_palloc(size_t size)
{ {
return palloc(size); return palloc(size);
} }
static void *pgxml_repalloc(void *ptr, size_t size) static void *
pgxml_repalloc(void *ptr, size_t size)
{ {
return repalloc(ptr, size); return repalloc(ptr, size);
} }
static void pgxml_pfree(void *ptr) static void
pgxml_pfree(void *ptr)
{ {
return pfree(ptr); return pfree(ptr);
} }
static void pgxml_mhs_init() static void
pgxml_mhs_init()
{ {
mhs.malloc_fcn = pgxml_palloc; mhs.malloc_fcn = pgxml_palloc;
mhs.realloc_fcn = pgxml_repalloc; mhs.realloc_fcn = pgxml_repalloc;
mhs.free_fcn = pgxml_pfree; mhs.free_fcn = pgxml_pfree;
} }
static void pgxml_handler_init() static void
pgxml_handler_init()
{ {
/* This code should set up the relevant handlers from user-supplied /*
settings. Quite how these settings are made is another matter :) */ * This code should set up the relevant handlers from user-supplied
* settings. Quite how these settings are made is another matter :)
*/
} }
/* Returns true if document is well-formed */ /* Returns true if document is well-formed */
@ -59,15 +66,19 @@ pgxml_parse(PG_FUNCTION_ARGS)
pgxml_handler_init(); pgxml_handler_init();
p = XML_ParserCreate_MM(NULL, &mhs, NULL); p = XML_ParserCreate_MM(NULL, &mhs, NULL);
if (! p) { if (!p)
{
elog(ERROR, "pgxml: Could not create expat parser"); elog(ERROR, "pgxml: Could not create expat parser");
PG_RETURN_NULL(); /* seems appropriate if we couldn't parse */ PG_RETURN_NULL(); /* seems appropriate if we couldn't parse */
} }
if (! XML_Parse(p, (char *)VARDATA(t) , docsize, 1)) { if (!XML_Parse(p, (char *) VARDATA(t), docsize, 1))
/* elog(NOTICE, "Parse error at line %d:%s", {
XML_GetCurrentLineNumber(p), /*
XML_ErrorString(XML_GetErrorCode(p))); */ * elog(NOTICE, "Parse error at line %d:%s",
* XML_GetCurrentLineNumber(p),
* XML_ErrorString(XML_GetErrorCode(p)));
*/
XML_ParserFree(p); XML_ParserFree(p);
PG_RETURN_BOOL(false); PG_RETURN_BOOL(false);
} }
@ -86,7 +97,8 @@ pgxml_parse(PG_FUNCTION_ARGS)
in various ways. in various ways.
*/ */
static XPath_Results *build_xpath_results(text *doc, text *pathstr) static XPath_Results *
build_xpath_results(text *doc, text *pathstr)
{ {
XPath_Results *xpr; XPath_Results *xpr;
char *res; char *res;
@ -127,7 +139,8 @@ static XPath_Results *build_xpath_results(text *doc, text *pathstr)
pgxml_mhs_init(); pgxml_mhs_init();
p = XML_ParserCreate_MM(NULL, &mhs, NULL); p = XML_ParserCreate_MM(NULL, &mhs, NULL);
if (! p) { if (!p)
{
elog(ERROR, "pgxml: Could not create expat parser"); elog(ERROR, "pgxml: Could not create expat parser");
pfree(xpr); pfree(xpr);
pfree(udata->path); pfree(udata->path);
@ -142,10 +155,13 @@ static XPath_Results *build_xpath_results(text *doc, text *pathstr)
XML_SetElementHandler(p, pgxml_starthandler, pgxml_endhandler); XML_SetElementHandler(p, pgxml_starthandler, pgxml_endhandler);
XML_SetCharacterDataHandler(p, pgxml_charhandler); XML_SetCharacterDataHandler(p, pgxml_charhandler);
if (! XML_Parse(p, (char *)VARDATA(doc) , docsize, 1)) { if (!XML_Parse(p, (char *) VARDATA(doc), docsize, 1))
/* elog(NOTICE, "Parse error at line %d:%s", {
XML_GetCurrentLineNumber(p), /*
XML_ErrorString(XML_GetErrorCode(p))); */ * elog(NOTICE, "Parse error at line %d:%s",
* XML_GetCurrentLineNumber(p),
* XML_ErrorString(XML_GetErrorCode(p)));
*/
XML_ParserFree(p); XML_ParserFree(p);
pfree(xpr); pfree(xpr);
pfree(udata->path); pfree(udata->path);
@ -177,18 +193,16 @@ pgxml_xpath(PG_FUNCTION_ARGS)
xpresults = build_xpath_results(t, t2); xpresults = build_xpath_results(t, t2);
/* This needs to be changed depending on the mechanism for returning /*
our set of results. */ * This needs to be changed depending on the mechanism for returning
* our set of results.
*/
if (xpresults == NULL) /* parse error (not WF or parser failure) */ if (xpresults == NULL) /* parse error (not WF or parser failure) */
{
PG_RETURN_NULL(); PG_RETURN_NULL();
}
if (ind >= (xpresults->rescount)) if (ind >= (xpresults->rescount))
{
PG_RETURN_NULL(); PG_RETURN_NULL();
}
restext = (text *) palloc(xpresults->reslens[ind] + VARHDRSZ); restext = (text *) palloc(xpresults->reslens[ind] + VARHDRSZ);
memcpy(VARDATA(restext), xpresults->results[ind], xpresults->reslens[ind]); memcpy(VARDATA(restext), xpresults->results[ind], xpresults->reslens[ind]);
@ -202,99 +216,123 @@ pgxml_xpath(PG_FUNCTION_ARGS)
} }
static void pgxml_pathcompare(void *userData) static void
pgxml_pathcompare(void *userData)
{ {
char *matchpos; char *matchpos;
matchpos = strstr(UD->currentpath, UD->path); matchpos = strstr(UD->currentpath, UD->path);
if (matchpos == NULL) { /* Should we have more logic here ? */ if (matchpos == NULL)
if (UD->textgrab) { { /* Should we have more logic here ? */
if (UD->textgrab)
{
UD->textgrab = 0; UD->textgrab = 0;
pgxml_finalisegrabbedtext(userData); pgxml_finalisegrabbedtext(userData);
} }
return; return;
} }
/* OK, we have a match of some sort. Now we need to check that
our match is anchored to the *end* of the string AND /*
that it is immediately preceded by a '/'*/ * OK, we have a match of some sort. Now we need to check that our
/* This test wouldn't work if strlen (UD->path) overran the length * match is anchored to the *end* of the string AND that it is
of the currentpath, but that's not possible because we got a match! */ * immediately preceded by a '/'
*/
/*
* This test wouldn't work if strlen (UD->path) overran the length of
* the currentpath, but that's not possible because we got a match!
*/
if ((matchpos + strlen(UD->path))[0] == '\0') if ((matchpos + strlen(UD->path))[0] == '\0')
{ {
if ((UD->path)[0]=='/') { if ((UD->path)[0] == '/')
if (matchpos == UD->currentpath) { {
if (matchpos == UD->currentpath)
UD->textgrab = 1; UD->textgrab = 1;
} }
} else { else
if ((matchpos-1)[0]=='/') { {
if ((matchpos - 1)[0] == '/')
UD->textgrab = 1; UD->textgrab = 1;
} }
} }
} }
}
static void pgxml_starthandler(void *userData, const XML_Char *name, static void
pgxml_starthandler(void *userData, const XML_Char * name,
const XML_Char ** atts) const XML_Char ** atts)
{ {
char sepstr[] = "/"; char sepstr[] = "/";
if ((strlen(name)+strlen(UD->currentpath))>MAXPATHLENGTH-2) { if ((strlen(name) + strlen(UD->currentpath)) > MAXPATHLENGTH - 2)
elog(NOTICE, "Path too long"); elog(NOTICE, "Path too long");
} else { else
{
strncat(UD->currentpath, sepstr, 1); strncat(UD->currentpath, sepstr, 1);
strcat(UD->currentpath, name); strcat(UD->currentpath, name);
} }
if (UD->textgrab) if (UD->textgrab)
{ {
/* Depending on user preference, should we "reconstitute" /*
the element into the result text? * Depending on user preference, should we "reconstitute" the
* element into the result text?
*/ */
} else { }
else
pgxml_pathcompare(userData); pgxml_pathcompare(userData);
} }
}
static void pgxml_endhandler(void *userData, const XML_Char *name) static void
pgxml_endhandler(void *userData, const XML_Char * name)
{ {
/* Start by removing the current element off the end of the /*
currentpath */ * Start by removing the current element off the end of the
* currentpath
*/
char *sepptr; char *sepptr;
sepptr = strrchr(UD->currentpath, '/'); sepptr = strrchr(UD->currentpath, '/');
if (sepptr==NULL) { if (sepptr == NULL)
{
elog(ERROR, "There's a problem..."); elog(ERROR, "There's a problem...");
sepptr = UD->currentpath; sepptr = UD->currentpath;
} }
if (strcmp(name, sepptr+1) !=0) { if (strcmp(name, sepptr + 1) != 0)
{
elog(NOTICE, "Wanted [%s], got [%s]", sepptr, name); elog(NOTICE, "Wanted [%s], got [%s]", sepptr, name);
/* unmatched entry, so do nothing */ /* unmatched entry, so do nothing */
} else { }
else
{
sepptr[0] = '\0'; /* Chop that element off the end */ sepptr[0] = '\0'; /* Chop that element off the end */
} }
if (UD->textgrab) { if (UD->textgrab)
pgxml_pathcompare(userData); pgxml_pathcompare(userData);
}
} }
static void pgxml_charhandler(void *userData, const XML_Char *s, int len) static void
pgxml_charhandler(void *userData, const XML_Char * s, int len)
{
if (UD->textgrab)
{
if (len > 0)
{ {
if (UD->textgrab) {
if (len>0) {
memcpy(UD->resptr, s, len); memcpy(UD->resptr, s, len);
UD->resptr += len; UD->resptr += len;
UD->reslen += len; UD->reslen += len;
} }
} }
} }
/* Should I be using PG list types here? */ /* Should I be using PG list types here? */
static void pgxml_finalisegrabbedtext(void *userData) static void
pgxml_finalisegrabbedtext(void *userData)
{ {
/* In res/reslen, we have a single result. */ /* In res/reslen, we have a single result. */
UD->xpres->results[UD->xpres->rescount] = UD->resptr - UD->reslen; UD->xpres->results[UD->xpres->rescount] = UD->resptr - UD->reslen;
@ -302,9 +340,8 @@ static void pgxml_finalisegrabbedtext(void *userData)
UD->reslen = 0; UD->reslen = 0;
UD->xpres->rescount++; UD->xpres->rescount++;
/* This effectively concatenates all the results together but we /*
do know where one ends and the next begins */ * This effectively concatenates all the results together but we do
* know where one ends and the next begins
*/
} }

View File

@ -18,7 +18,8 @@ static void pgxml_finalisegrabbedtext(void *userData);
#define MAXRESULTS 100 #define MAXRESULTS 100
typedef struct { typedef struct
{
int rescount; int rescount;
char *results[MAXRESULTS]; char *results[MAXRESULTS];
int32 reslens[MAXRESULTS]; int32 reslens[MAXRESULTS];
@ -27,7 +28,8 @@ typedef struct {
typedef struct { typedef struct
{
char currentpath[MAXPATHLENGTH]; char currentpath[MAXPATHLENGTH];
char *path; char *path;
int textgrab; int textgrab;
@ -38,23 +40,3 @@ typedef struct {
#define UD ((pgxml_udata *) userData) #define UD ((pgxml_udata *) userData)

View File

@ -32,30 +32,37 @@ Datum pgxml_xpath(PG_FUNCTION_ARGS);
/* memory handling passthrough functions (e.g. palloc, pstrdup are /* memory handling passthrough functions (e.g. palloc, pstrdup are
currently macros, and the others might become so...) */ currently macros, and the others might become so...) */
static void *pgxml_palloc(size_t size) static void *
pgxml_palloc(size_t size)
{ {
return palloc(size); return palloc(size);
} }
static void *pgxml_repalloc(void *ptr, size_t size) static void *
pgxml_repalloc(void *ptr, size_t size)
{ {
return repalloc(ptr, size); return repalloc(ptr, size);
} }
static void pgxml_pfree(void *ptr) static void
pgxml_pfree(void *ptr)
{ {
return pfree(ptr); return pfree(ptr);
} }
static char *pgxml_pstrdup(const char *string) static char *
pgxml_pstrdup(const char *string)
{ {
return pstrdup(string); return pstrdup(string);
} }
static void pgxml_parser_init() static void
pgxml_parser_init()
{ {
/* This code should also set parser settings from user-supplied /*
info. Quite how these settings are made is another matter :) */ * This code should also set parser settings from user-supplied info.
* Quite how these settings are made is another matter :)
*/
xmlMemSetup(pgxml_pfree, pgxml_palloc, pgxml_repalloc, pgxml_pstrdup); xmlMemSetup(pgxml_pfree, pgxml_palloc, pgxml_repalloc, pgxml_pstrdup);
xmlInitParser(); xmlInitParser();
@ -78,7 +85,8 @@ pgxml_parse(PG_FUNCTION_ARGS)
pgxml_parser_init(); pgxml_parser_init();
doctree = xmlParseMemory((char *) VARDATA(t), docsize); doctree = xmlParseMemory((char *) VARDATA(t), docsize);
if (doctree == NULL) { if (doctree == NULL)
{
/* xmlCleanupParser(); */ /* xmlCleanupParser(); */
PG_RETURN_BOOL(false); /* i.e. not well-formed */ PG_RETURN_BOOL(false); /* i.e. not well-formed */
} }
@ -88,15 +96,19 @@ pgxml_parse(PG_FUNCTION_ARGS)
} }
static xmlChar static xmlChar
*pgxmlNodeSetToText(xmlNodeSetPtr nodeset, *
pgxmlNodeSetToText(xmlNodeSetPtr nodeset,
xmlDocPtr doc, xmlDocPtr doc,
xmlChar * toptagname, xmlChar * toptagname,
xmlChar * septagname, xmlChar * septagname,
int format) int format)
{ {
/* Function translates a nodeset into a text representation */ /* Function translates a nodeset into a text representation */
/* iterates over each node in the set and calls xmlNodeDump to write
it to an xmlBuffer -from which an xmlChar * string is returned. */ /*
* iterates over each node in the set and calls xmlNodeDump to write
* it to an xmlBuffer -from which an xmlChar * string is returned.
*/
/* each representation is surrounded by <tagname> ... </tagname> */ /* each representation is surrounded by <tagname> ... </tagname> */
/* if format==0, add a newline between nodes?? */ /* if format==0, add a newline between nodes?? */
@ -106,32 +118,37 @@ static xmlChar
buf = xmlBufferCreate(); buf = xmlBufferCreate();
if ((toptagname != NULL) && (xmlStrlen(toptagname)>0)) { if ((toptagname != NULL) && (xmlStrlen(toptagname) > 0))
{
xmlBufferWriteChar(buf, "<"); xmlBufferWriteChar(buf, "<");
xmlBufferWriteCHAR(buf, toptagname); xmlBufferWriteCHAR(buf, toptagname);
xmlBufferWriteChar(buf, ">"); xmlBufferWriteChar(buf, ">");
} }
if (nodeset != NULL) { if (nodeset != NULL)
for (i=0; i < nodeset->nodeNr; i++) { {
if ((septagname != NULL) && (xmlStrlen(septagname)>0)) { for (i = 0; i < nodeset->nodeNr; i++)
{
if ((septagname != NULL) && (xmlStrlen(septagname) > 0))
{
xmlBufferWriteChar(buf, "<"); xmlBufferWriteChar(buf, "<");
xmlBufferWriteCHAR(buf, septagname); xmlBufferWriteCHAR(buf, septagname);
xmlBufferWriteChar(buf, ">"); xmlBufferWriteChar(buf, ">");
} }
xmlNodeDump(buf, doc, nodeset->nodeTab[i], 1, (format == 2)); xmlNodeDump(buf, doc, nodeset->nodeTab[i], 1, (format == 2));
if ((septagname != NULL) && (xmlStrlen(septagname)>0)) { if ((septagname != NULL) && (xmlStrlen(septagname) > 0))
{
xmlBufferWriteChar(buf, "</"); xmlBufferWriteChar(buf, "</");
xmlBufferWriteCHAR(buf, septagname); xmlBufferWriteCHAR(buf, septagname);
xmlBufferWriteChar(buf, ">"); xmlBufferWriteChar(buf, ">");
} }
if (format) { if (format)
xmlBufferWriteChar(buf, "\n"); xmlBufferWriteChar(buf, "\n");
} }
} }
}
if ((toptagname != NULL) && (xmlStrlen(toptagname)>0)) { if ((toptagname != NULL) && (xmlStrlen(toptagname) > 0))
{
xmlBufferWriteChar(buf, "</"); xmlBufferWriteChar(buf, "</");
xmlBufferWriteCHAR(buf, toptagname); xmlBufferWriteCHAR(buf, toptagname);
xmlBufferWriteChar(buf, ">"); xmlBufferWriteChar(buf, ">");
@ -141,7 +158,9 @@ static xmlChar
return result; return result;
} }
static xmlChar *pgxml_texttoxmlchar(text *textstring) { static xmlChar *
pgxml_texttoxmlchar(text *textstring)
{
xmlChar *res; xmlChar *res;
int32 txsize; int32 txsize;
@ -161,11 +180,16 @@ pgxml_xpath(PG_FUNCTION_ARGS)
xmlDocPtr doctree; xmlDocPtr doctree;
xmlXPathContextPtr ctxt; xmlXPathContextPtr ctxt;
xmlXPathObjectPtr res; xmlXPathObjectPtr res;
xmlChar *xpath, *xpresstr, *toptag, *septag; xmlChar *xpath,
*xpresstr,
*toptag,
*septag;
xmlXPathCompExprPtr comppath; xmlXPathCompExprPtr comppath;
int32 docsize,ressize; int32 docsize,
text *t, *xpres; ressize;
text *t,
*xpres;
t = PG_GETARG_TEXT_P(0); /* document buffer */ t = PG_GETARG_TEXT_P(0); /* document buffer */
xpath = pgxml_texttoxmlchar(PG_GETARG_TEXT_P(1)); /* XPath expression */ xpath = pgxml_texttoxmlchar(PG_GETARG_TEXT_P(1)); /* XPath expression */
@ -177,7 +201,8 @@ pgxml_xpath(PG_FUNCTION_ARGS)
pgxml_parser_init(); pgxml_parser_init();
doctree = xmlParseMemory((char *) VARDATA(t), docsize); doctree = xmlParseMemory((char *) VARDATA(t), docsize);
if (doctree == NULL) { /* not well-formed */ if (doctree == NULL)
{ /* not well-formed */
PG_RETURN_NULL(); PG_RETURN_NULL();
} }
@ -186,7 +211,8 @@ pgxml_xpath(PG_FUNCTION_ARGS)
/* compile the path */ /* compile the path */
comppath = xmlXPathCompile(xpath); comppath = xmlXPathCompile(xpath);
if (comppath == NULL) { if (comppath == NULL)
{
elog(NOTICE, "XPath syntax error"); elog(NOTICE, "XPath syntax error");
xmlFreeDoc(doctree); xmlFreeDoc(doctree);
pfree((void *) xpath); pfree((void *) xpath);
@ -197,14 +223,16 @@ pgxml_xpath(PG_FUNCTION_ARGS)
res = xmlXPathCompiledEval(comppath, ctxt); res = xmlXPathCompiledEval(comppath, ctxt);
xmlXPathFreeCompExpr(comppath); xmlXPathFreeCompExpr(comppath);
if (res==NULL) { if (res == NULL)
{
xmlFreeDoc(doctree); xmlFreeDoc(doctree);
pfree((void *) xpath); pfree((void *) xpath);
PG_RETURN_NULL(); /* seems appropriate */ PG_RETURN_NULL(); /* seems appropriate */
} }
/* now we dump this node, ?surrounding by tags? */ /* now we dump this node, ?surrounding by tags? */
/* To do this, we look first at the type */ /* To do this, we look first at the type */
switch(res->type) { switch (res->type)
{
case XPATH_NODESET: case XPATH_NODESET:
xpresstr = pgxmlNodeSetToText(res->nodesetval, xpresstr = pgxmlNodeSetToText(res->nodesetval,
doctree, doctree,
@ -232,7 +260,3 @@ pgxml_xpath(PG_FUNCTION_ARGS)
PG_RETURN_TEXT_P(xpres); PG_RETURN_TEXT_P(xpres);
} }

View File

@ -9,7 +9,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/access/common/heaptuple.c,v 1.73 2001/08/23 23:06:37 tgl Exp $ * $Header: /cvsroot/pgsql/src/backend/access/common/heaptuple.c,v 1.74 2001/10/25 05:49:20 momjian Exp $
* *
* NOTES * NOTES
* The old interface functions have been converted to macros * The old interface functions have been converted to macros
@ -241,7 +241,6 @@ nocachegetattr(HeapTuple tuple,
} }
else else
{ {
/* /*
* there's a null somewhere in the tuple * there's a null somewhere in the tuple
*/ */
@ -347,7 +346,6 @@ nocachegetattr(HeapTuple tuple,
(HeapTupleNoNulls(tuple) || !att_isnull(j, bp)) && (HeapTupleNoNulls(tuple) || !att_isnull(j, bp)) &&
(HeapTupleAllFixed(tuple) || att[j]->attlen > 0)); j++) (HeapTupleAllFixed(tuple) || att[j]->attlen > 0)); j++)
{ {
/* /*
* Fix me when going to a machine with more than a four-byte * Fix me when going to a machine with more than a four-byte
* word! * word!
@ -546,7 +544,6 @@ heap_deformtuple(HeapTuple tuple,
nulls[i] = ' '; nulls[i] = ' ';
} }
} }
#endif #endif
/* ---------------- /* ----------------

View File

@ -9,7 +9,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/access/common/indextuple.c,v 1.54 2001/03/22 06:16:06 momjian Exp $ * $Header: /cvsroot/pgsql/src/backend/access/common/indextuple.c,v 1.55 2001/10/25 05:49:20 momjian Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
@ -49,7 +49,6 @@ index_formtuple(TupleDesc tupleDescriptor,
#ifdef TOAST_INDEX_HACK #ifdef TOAST_INDEX_HACK
Datum untoasted_value[INDEX_MAX_KEYS]; Datum untoasted_value[INDEX_MAX_KEYS];
bool untoasted_free[INDEX_MAX_KEYS]; bool untoasted_free[INDEX_MAX_KEYS];
#endif #endif
if (numberOfAttributes > INDEX_MAX_KEYS) if (numberOfAttributes > INDEX_MAX_KEYS)
@ -338,7 +337,6 @@ nocache_index_getattr(IndexTuple tup,
for (; j <= attnum; j++) for (; j <= attnum; j++)
{ {
/* /*
* Fix me when going to a machine with more than a four-byte * Fix me when going to a machine with more than a four-byte
* word! * word!

View File

@ -9,7 +9,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/access/common/printtup.c,v 1.59 2001/03/22 06:16:06 momjian Exp $ * $Header: /cvsroot/pgsql/src/backend/access/common/printtup.c,v 1.60 2001/10/25 05:49:20 momjian Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
@ -197,7 +197,6 @@ printtup(HeapTuple tuple, TupleDesc typeinfo, DestReceiver *self)
continue; continue;
if (OidIsValid(thisState->typoutput)) if (OidIsValid(thisState->typoutput))
{ {
/* /*
* If we have a toasted datum, forcibly detoast it here to * If we have a toasted datum, forcibly detoast it here to
* avoid memory leakage inside the type's output routine. * avoid memory leakage inside the type's output routine.
@ -306,7 +305,6 @@ debugtup(HeapTuple tuple, TupleDesc typeinfo, DestReceiver *self)
if (getTypeOutputInfo(typeinfo->attrs[i]->atttypid, if (getTypeOutputInfo(typeinfo->attrs[i]->atttypid,
&typoutput, &typelem, &typisvarlena)) &typoutput, &typelem, &typisvarlena))
{ {
/* /*
* If we have a toasted datum, forcibly detoast it here to * If we have a toasted datum, forcibly detoast it here to
* avoid memory leakage inside the type's output routine. * avoid memory leakage inside the type's output routine.
@ -401,7 +399,6 @@ printtup_internal(HeapTuple tuple, TupleDesc typeinfo, DestReceiver *self)
/* send # of bytes, and opaque data */ /* send # of bytes, and opaque data */
if (thisState->typisvarlena) if (thisState->typisvarlena)
{ {
/* /*
* If we have a toasted datum, must detoast before sending. * If we have a toasted datum, must detoast before sending.
*/ */

View File

@ -8,7 +8,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/access/common/tupdesc.c,v 1.75 2001/06/25 21:11:43 tgl Exp $ * $Header: /cvsroot/pgsql/src/backend/access/common/tupdesc.c,v 1.76 2001/10/25 05:49:20 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,9 +238,9 @@ equalTupleDescs(TupleDesc tupdesc1, TupleDesc tupdesc2)
Form_pg_attribute attr2 = tupdesc2->attrs[i]; Form_pg_attribute attr2 = tupdesc2->attrs[i];
/* /*
* We do not need to check every single field here: we can disregard * We do not need to check every single field here: we can
* attrelid, attnum (it was used to place the row in the attrs array) * disregard attrelid, attnum (it was used to place the row in the
* and everything derived from the column datatype. * attrs array) and everything derived from the column datatype.
*/ */
if (strcmp(NameStr(attr1->attname), NameStr(attr2->attname)) != 0) if (strcmp(NameStr(attr1->attname), NameStr(attr2->attname)) != 0)
return false; return false;
@ -399,7 +399,6 @@ TupleDescInitEntry(TupleDesc desc,
0, 0, 0); 0, 0, 0);
if (!HeapTupleIsValid(tuple)) if (!HeapTupleIsValid(tuple))
{ {
/* /*
* here type info does not exist yet so we just fill the attribute * here type info does not exist yet so we just fill the attribute
* with dummy information and return false. * with dummy information and return false.
@ -585,7 +584,6 @@ BuildDescForRelation(List *schema, char *relname)
typenameTypeId(typename), typenameTypeId(typename),
atttypmod, attdim, attisset)) atttypmod, attdim, attisset))
{ {
/* /*
* if TupleDescInitEntry() fails, it means there is no type in * if TupleDescInitEntry() fails, it means there is no type in
* the system catalogs. So now we check if the type name * the system catalogs. So now we check if the type name

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/access/gist/gist.c,v 1.84 2001/10/06 23:21:43 tgl Exp $ * $Header: /cvsroot/pgsql/src/backend/access/gist/gist.c,v 1.85 2001/10/25 05:49:20 momjian Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
@ -124,6 +124,7 @@ static OffsetNumber gistchoose(Relation r, Page p,
IndexTuple it, IndexTuple it,
GISTSTATE *giststate); GISTSTATE *giststate);
static void gistdelete(Relation r, ItemPointer tid); static void gistdelete(Relation r, ItemPointer tid);
#ifdef GIST_PAGEADDITEM #ifdef GIST_PAGEADDITEM
static IndexTuple gist_tuple_replacekey(Relation r, static IndexTuple gist_tuple_replacekey(Relation r,
GISTENTRY entry, IndexTuple t); GISTENTRY entry, IndexTuple t);
@ -140,6 +141,7 @@ static void gistpenalty( GISTSTATE *giststate, int attno,
GISTENTRY *key1, bool isNull1, GISTENTRY *key1, bool isNull1,
GISTENTRY *key2, bool isNull2, GISTENTRY *key2, bool isNull2,
float *penalty); float *penalty);
#undef GISTDEBUG #undef GISTDEBUG
#ifdef GISTDEBUG #ifdef GISTDEBUG
@ -240,10 +242,13 @@ gistbuildCallback(Relation index,
/* immediately compress keys to normalize */ /* immediately compress keys to normalize */
for (i = 0; i < buildstate->numindexattrs; i++) for (i = 0; i < buildstate->numindexattrs; i++)
{ {
if ( nulls[i]=='n' ) { if (nulls[i] == 'n')
{
attdata[i] = (Datum) 0; attdata[i] = (Datum) 0;
compvec[i] = FALSE; compvec[i] = FALSE;
} else { }
else
{
gistcentryinit(&buildstate->giststate, i, &tmpcentry, attdata[i], gistcentryinit(&buildstate->giststate, i, &tmpcentry, attdata[i],
(Relation) NULL, (Page) NULL, (OffsetNumber) 0, (Relation) NULL, (Page) NULL, (OffsetNumber) 0,
-1 /* size is currently bogus */ , TRUE, FALSE); -1 /* size is currently bogus */ , TRUE, FALSE);
@ -262,10 +267,10 @@ gistbuildCallback(Relation index,
/* /*
* Since we already have the index relation locked, we call * Since we already have the index relation locked, we call
* gistdoinsert directly. Normal access method calls dispatch * gistdoinsert directly. Normal access method calls dispatch through
* through gistinsert, which locks the relation for write. This * gistinsert, which locks the relation for write. This is the right
* is the right thing to do if you're inserting single tups, but * thing to do if you're inserting single tups, but not when you're
* not when you're initializing the whole index at once. * initializing the whole index at once.
*/ */
gistdoinsert(index, itup, NULL, &buildstate->giststate); gistdoinsert(index, itup, NULL, &buildstate->giststate);
@ -291,6 +296,7 @@ gistinsert(PG_FUNCTION_ARGS)
Datum *datum = (Datum *) PG_GETARG_POINTER(1); Datum *datum = (Datum *) PG_GETARG_POINTER(1);
char *nulls = (char *) PG_GETARG_POINTER(2); char *nulls = (char *) PG_GETARG_POINTER(2);
ItemPointer ht_ctid = (ItemPointer) PG_GETARG_POINTER(3); ItemPointer ht_ctid = (ItemPointer) PG_GETARG_POINTER(3);
#ifdef NOT_USED #ifdef NOT_USED
Relation heapRel = (Relation) PG_GETARG_POINTER(4); Relation heapRel = (Relation) PG_GETARG_POINTER(4);
#endif #endif
@ -308,7 +314,8 @@ gistinsert(PG_FUNCTION_ARGS)
*/ */
/* GiST cannot index tuples with leading NULLs */ /* GiST cannot index tuples with leading NULLs */
if ( nulls[0] == 'n' ) { if (nulls[0] == 'n')
{
res = NULL; res = NULL;
PG_RETURN_POINTER(res); PG_RETURN_POINTER(res);
} }
@ -318,10 +325,13 @@ gistinsert(PG_FUNCTION_ARGS)
/* immediately compress keys to normalize */ /* immediately compress keys to normalize */
for (i = 0; i < r->rd_att->natts; i++) for (i = 0; i < r->rd_att->natts; i++)
{ {
if ( nulls[i]=='n' ) { if (nulls[i] == 'n')
{
datum[i] = (Datum) 0; datum[i] = (Datum) 0;
compvec[i] = FALSE; compvec[i] = FALSE;
} else { }
else
{
gistcentryinit(&giststate, i, &tmpentry, datum[i], gistcentryinit(&giststate, i, &tmpentry, datum[i],
(Relation) NULL, (Page) NULL, (OffsetNumber) 0, (Relation) NULL, (Page) NULL, (OffsetNumber) 0,
-1 /* size is currently bogus */ , TRUE, FALSE); -1 /* size is currently bogus */ , TRUE, FALSE);
@ -471,6 +481,7 @@ gistlayerinsert(Relation r, BlockNumber blkno,
if (!(ret & SPLITED)) if (!(ret & SPLITED))
{ {
IndexTuple newtup = gistgetadjusted(r, oldtup, (*itup)[0], giststate); IndexTuple newtup = gistgetadjusted(r, oldtup, (*itup)[0], giststate);
if (!newtup) if (!newtup)
{ {
/* not need to update key */ /* not need to update key */
@ -492,8 +503,10 @@ gistlayerinsert(Relation r, BlockNumber blkno,
if (gistnospace(page, (*itup), *len)) if (gistnospace(page, (*itup), *len))
{ {
/* no space for insertion */ /* no space for insertion */
IndexTuple *itvec, *newitup; IndexTuple *itvec,
int tlen,oldlen; *newitup;
int tlen,
oldlen;
ret |= SPLITED; ret |= SPLITED;
itvec = gistreadbuffer(r, buffer, &tlen); itvec = gistreadbuffer(r, buffer, &tlen);
@ -539,6 +552,7 @@ gistlayerinsert(Relation r, BlockNumber blkno,
* parent * parent
*/ */
IndexTuple newtup = gistunion(r, (*itup), *len, giststate); IndexTuple newtup = gistunion(r, (*itup), *len, giststate);
ItemPointerSet(&(newtup->t_tid), blkno, 1); ItemPointerSet(&(newtup->t_tid), blkno, 1);
for (i = 0; i < *len; i++) for (i = 0; i < *len; i++)
@ -560,6 +574,7 @@ gistwritebuffer(Relation r, Page page, IndexTuple *itup,
{ {
OffsetNumber l = InvalidOffsetNumber; OffsetNumber l = InvalidOffsetNumber;
int i; int i;
#ifdef GIST_PAGEADDITEM #ifdef GIST_PAGEADDITEM
GISTENTRY tmpdentry; GISTENTRY tmpdentry;
IndexTuple newtup; IndexTuple newtup;
@ -639,14 +654,16 @@ gistjoinvector(IndexTuple *itvec, int *len, IndexTuple *additvec, int addlen)
* return union of itup vector * return union of itup vector
*/ */
static IndexTuple static IndexTuple
gistunion(Relation r, IndexTuple *itvec, int len, GISTSTATE *giststate) { gistunion(Relation r, IndexTuple *itvec, int len, GISTSTATE *giststate)
{
Datum attr[INDEX_MAX_KEYS]; Datum attr[INDEX_MAX_KEYS];
bool whatfree[INDEX_MAX_KEYS]; bool whatfree[INDEX_MAX_KEYS];
char isnull[INDEX_MAX_KEYS]; char isnull[INDEX_MAX_KEYS];
bytea *evec; bytea *evec;
Datum datum; Datum datum;
int datumsize, int datumsize,
i,j; i,
j;
GISTENTRY centry[INDEX_MAX_KEYS]; GISTENTRY centry[INDEX_MAX_KEYS];
bool *needfree; bool *needfree;
IndexTuple newtup; IndexTuple newtup;
@ -656,11 +673,14 @@ gistunion(Relation r, IndexTuple *itvec, int len, GISTSTATE *giststate) {
needfree = (bool *) palloc(((len == 1) ? 2 : len) * sizeof(bool)); needfree = (bool *) palloc(((len == 1) ? 2 : len) * sizeof(bool));
evec = (bytea *) palloc(((len == 1) ? 2 : len) * sizeof(GISTENTRY) + VARHDRSZ); evec = (bytea *) palloc(((len == 1) ? 2 : len) * sizeof(GISTENTRY) + VARHDRSZ);
for (j = 0; j < r->rd_att->natts; j++) { for (j = 0; j < r->rd_att->natts; j++)
{
reallen = 0; reallen = 0;
for (i = 0; i < len; i++) { for (i = 0; i < len; i++)
{
datum = index_getattr(itvec[i], j + 1, giststate->tupdesc, &IsNull); datum = index_getattr(itvec[i], j + 1, giststate->tupdesc, &IsNull);
if ( IsNull ) continue; if (IsNull)
continue;
gistdentryinit(giststate, j, gistdentryinit(giststate, j,
&((GISTENTRY *) VARDATA(evec))[reallen], &((GISTENTRY *) VARDATA(evec))[reallen],
@ -675,20 +695,24 @@ gistunion(Relation r, IndexTuple *itvec, int len, GISTSTATE *giststate) {
reallen++; reallen++;
} }
if ( reallen == 0 ) { if (reallen == 0)
{
attr[j] = (Datum) 0; attr[j] = (Datum) 0;
isnull[j] = 'n'; isnull[j] = 'n';
whatfree[j] = FALSE; whatfree[j] = FALSE;
} else { }
if ( reallen == 1 ) { else
{
if (reallen == 1)
{
VARATT_SIZEP(evec) = 2 * sizeof(GISTENTRY) + VARHDRSZ; VARATT_SIZEP(evec) = 2 * sizeof(GISTENTRY) + VARHDRSZ;
gistentryinit(((GISTENTRY *) VARDATA(evec))[1], gistentryinit(((GISTENTRY *) VARDATA(evec))[1],
((GISTENTRY *) VARDATA(evec))[0].key, r, (Page) NULL, ((GISTENTRY *) VARDATA(evec))[0].key, r, (Page) NULL,
(OffsetNumber) 0, ((GISTENTRY *) VARDATA(evec))[0].bytes, FALSE); (OffsetNumber) 0, ((GISTENTRY *) VARDATA(evec))[0].bytes, FALSE);
} else {
VARATT_SIZEP(evec) = reallen * sizeof(GISTENTRY) + VARHDRSZ;
} }
else
VARATT_SIZEP(evec) = reallen * sizeof(GISTENTRY) + VARHDRSZ;
datum = FunctionCall2(&giststate->unionFn[j], datum = FunctionCall2(&giststate->unionFn[j],
PointerGetDatum(evec), PointerGetDatum(evec),
PointerGetDatum(&datumsize)); PointerGetDatum(&datumsize));
@ -702,11 +726,13 @@ gistunion(Relation r, IndexTuple *itvec, int len, GISTSTATE *giststate) {
datumsize, FALSE, FALSE); datumsize, FALSE, FALSE);
isnull[j] = ' '; isnull[j] = ' ';
attr[j] = centry[j].key; attr[j] = centry[j].key;
if ( !isAttByVal( giststate, j ) ) { if (!isAttByVal(giststate, j))
{
whatfree[j] = TRUE; whatfree[j] = TRUE;
if (centry[j].key != datum) if (centry[j].key != datum)
pfree(DatumGetPointer(datum)); pfree(DatumGetPointer(datum));
} else }
else
whatfree[j] = FALSE; whatfree[j] = FALSE;
} }
} }
@ -732,7 +758,8 @@ gistgetadjusted(Relation r, IndexTuple oldtup, IndexTuple addtup, GISTSTATE *gis
bytea *evec; bytea *evec;
Datum datum; Datum datum;
int datumsize; int datumsize;
bool result, neednew = false; bool result,
neednew = false;
char isnull[INDEX_MAX_KEYS], char isnull[INDEX_MAX_KEYS],
whatfree[INDEX_MAX_KEYS]; whatfree[INDEX_MAX_KEYS];
Datum attr[INDEX_MAX_KEYS]; Datum attr[INDEX_MAX_KEYS];
@ -761,12 +788,16 @@ gistgetadjusted(Relation r, IndexTuple oldtup, IndexTuple addtup, GISTSTATE *gis
(OffsetNumber) 0, addatt, adddec, addisnull); (OffsetNumber) 0, addatt, adddec, addisnull);
for( j=0; j<r->rd_att->natts; j++ ) { for (j = 0; j < r->rd_att->natts; j++)
if ( oldisnull[j] && addisnull[j] ) { {
if (oldisnull[j] && addisnull[j])
{
isnull[j] = 'n'; isnull[j] = 'n';
attr[j] = (Datum) 0; attr[j] = (Datum) 0;
whatfree[j] = FALSE; whatfree[j] = FALSE;
} else { }
else
{
FILLEV( FILLEV(
oldisnull[j], oldatt[j].key, oldatt[j].bytes, oldisnull[j], oldatt[j].key, oldatt[j].bytes,
addisnull[j], addatt[j].key, addatt[j].bytes addisnull[j], addatt[j].key, addatt[j].bytes
@ -776,10 +807,13 @@ gistgetadjusted(Relation r, IndexTuple oldtup, IndexTuple addtup, GISTSTATE *gis
PointerGetDatum(evec), PointerGetDatum(evec),
PointerGetDatum(&datumsize)); PointerGetDatum(&datumsize));
if ( oldisnull[j] || addisnull[j] ) { if (oldisnull[j] || addisnull[j])
{
if (oldisnull[j]) if (oldisnull[j])
neednew = true; neednew = true;
} else { }
else
{
FunctionCall3(&giststate->equalFn[j], FunctionCall3(&giststate->equalFn[j],
ev0p->key, ev0p->key,
datum, datum,
@ -789,8 +823,10 @@ gistgetadjusted(Relation r, IndexTuple oldtup, IndexTuple addtup, GISTSTATE *gis
neednew = true; neednew = true;
} }
if ( olddec[j] ) pfree( DatumGetPointer(oldatt[j].key) ); if (olddec[j])
if ( adddec[j] ) pfree( DatumGetPointer(addatt[j].key) ); pfree(DatumGetPointer(oldatt[j].key));
if (adddec[j])
pfree(DatumGetPointer(addatt[j].key));
gistcentryinit(giststate, j, &centry[j], datum, gistcentryinit(giststate, j, &centry[j], datum,
(Relation) NULL, (Page) NULL, (OffsetNumber) NULL, (Relation) NULL, (Page) NULL, (OffsetNumber) NULL,
@ -798,17 +834,20 @@ gistgetadjusted(Relation r, IndexTuple oldtup, IndexTuple addtup, GISTSTATE *gis
isnull[j] = ' '; isnull[j] = ' ';
attr[j] = centry[j].key; attr[j] = centry[j].key;
if ( (!isAttByVal( giststate, j ) ) ) { if ((!isAttByVal(giststate, j)))
{
whatfree[j] = TRUE; whatfree[j] = TRUE;
if (centry[j].key != datum) if (centry[j].key != datum)
pfree(DatumGetPointer(datum)); pfree(DatumGetPointer(datum));
} else }
else
whatfree[j] = FALSE; whatfree[j] = FALSE;
} }
} }
pfree(evec); pfree(evec);
if (neednew) { if (neednew)
{
/* need to update key */ /* need to update key */
newtup = (IndexTuple) index_formtuple(giststate->tupdesc, attr, isnull); newtup = (IndexTuple) index_formtuple(giststate->tupdesc, attr, isnull);
newtup->t_tid = oldtup->t_tid; newtup->t_tid = oldtup->t_tid;
@ -822,11 +861,16 @@ gistgetadjusted(Relation r, IndexTuple oldtup, IndexTuple addtup, GISTSTATE *gis
} }
static void static void
gistunionsubkey( Relation r, GISTSTATE *giststate, IndexTuple *itvec, GIST_SPLITVEC * spl ) { gistunionsubkey(Relation r, GISTSTATE *giststate, IndexTuple *itvec, GIST_SPLITVEC *spl)
int i,j,lr; {
int i,
j,
lr;
Datum *attr; Datum *attr;
bool *needfree, IsNull; bool *needfree,
int len, *attrsize; IsNull;
int len,
*attrsize;
OffsetNumber *entries; OffsetNumber *entries;
bytea *evec; bytea *evec;
Datum datum; Datum datum;
@ -834,14 +878,18 @@ gistunionsubkey( Relation r, GISTSTATE *giststate, IndexTuple *itvec, GIST_SPLIT
int reallen; int reallen;
bool *isnull; bool *isnull;
for(lr=0;lr<=1;lr++) { for (lr = 0; lr <= 1; lr++)
if ( lr ) { {
if (lr)
{
attrsize = spl->spl_lattrsize; attrsize = spl->spl_lattrsize;
attr = spl->spl_lattr; attr = spl->spl_lattr;
len = spl->spl_nleft; len = spl->spl_nleft;
entries = spl->spl_left; entries = spl->spl_left;
isnull = spl->spl_lisnull; isnull = spl->spl_lisnull;
} else { }
else
{
attrsize = spl->spl_rattrsize; attrsize = spl->spl_rattrsize;
attr = spl->spl_rattr; attr = spl->spl_rattr;
len = spl->spl_nright; len = spl->spl_nright;
@ -851,9 +899,11 @@ gistunionsubkey( Relation r, GISTSTATE *giststate, IndexTuple *itvec, GIST_SPLIT
needfree = (bool *) palloc(((len == 1) ? 2 : len) * sizeof(bool)); needfree = (bool *) palloc(((len == 1) ? 2 : len) * sizeof(bool));
evec = (bytea *) palloc(((len == 1) ? 2 : len) * sizeof(GISTENTRY) + VARHDRSZ); evec = (bytea *) palloc(((len == 1) ? 2 : len) * sizeof(GISTENTRY) + VARHDRSZ);
for (j = 1; j < r->rd_att->natts; j++) { for (j = 1; j < r->rd_att->natts; j++)
{
reallen = 0; reallen = 0;
for (i = 0; i < len; i++) { for (i = 0; i < len; i++)
{
if (spl->spl_idgrp[entries[i]]) if (spl->spl_idgrp[entries[i]])
continue; continue;
datum = index_getattr(itvec[entries[i] - 1], j + 1, datum = index_getattr(itvec[entries[i] - 1], j + 1,
@ -879,17 +929,21 @@ gistunionsubkey( Relation r, GISTSTATE *giststate, IndexTuple *itvec, GIST_SPLIT
datum = (Datum) 0; datum = (Datum) 0;
datumsize = 0; datumsize = 0;
isnull[j] = true; isnull[j] = true;
} else { }
else
{
/* /*
* ((GISTENTRY *) VARDATA(evec))[0].bytes may be not defined, * ((GISTENTRY *) VARDATA(evec))[0].bytes may be not
* so form union with itself * defined, so form union with itself
*/ */
if ( reallen == 1 ) { if (reallen == 1)
{
VARATT_SIZEP(evec) = 2 * sizeof(GISTENTRY) + VARHDRSZ; VARATT_SIZEP(evec) = 2 * sizeof(GISTENTRY) + VARHDRSZ;
memcpy((void *) &((GISTENTRY *) VARDATA(evec))[1], memcpy((void *) &((GISTENTRY *) VARDATA(evec))[1],
(void *) &((GISTENTRY *) VARDATA(evec))[0], (void *) &((GISTENTRY *) VARDATA(evec))[0],
sizeof(GISTENTRY)); sizeof(GISTENTRY));
} else }
else
VARATT_SIZEP(evec) = reallen * sizeof(GISTENTRY) + VARHDRSZ; VARATT_SIZEP(evec) = reallen * sizeof(GISTENTRY) + VARHDRSZ;
datum = FunctionCall2(&giststate->unionFn[j], datum = FunctionCall2(&giststate->unionFn[j],
PointerGetDatum(evec), PointerGetDatum(evec),
@ -913,43 +967,55 @@ gistunionsubkey( Relation r, GISTSTATE *giststate, IndexTuple *itvec, GIST_SPLIT
* find group in vector with equial value * find group in vector with equial value
*/ */
static int static int
gistfindgroup( GISTSTATE *giststate, GISTENTRY *valvec, GIST_SPLITVEC * spl ) { gistfindgroup(GISTSTATE *giststate, GISTENTRY *valvec, GIST_SPLITVEC *spl)
int i,j,len; {
int i,
j,
len;
int curid = 1; int curid = 1;
bool result; bool result;
/* /*
* first key is always not null (see gistinsert), * first key is always not null (see gistinsert), so we may not check
* so we may not check for nulls * for nulls
*/ */
for(i=0; i<spl->spl_nleft; i++) { for (i = 0; i < spl->spl_nleft; i++)
if ( spl->spl_idgrp[ spl->spl_left[i] ]) continue; {
if (spl->spl_idgrp[spl->spl_left[i]])
continue;
len = 0; len = 0;
/* find all equal value in right part */ /* find all equal value in right part */
for(j=0; j < spl->spl_nright; j++) { for (j = 0; j < spl->spl_nright; j++)
if ( spl->spl_idgrp[ spl->spl_right[j] ]) continue; {
if (spl->spl_idgrp[spl->spl_right[j]])
continue;
FunctionCall3(&giststate->equalFn[0], FunctionCall3(&giststate->equalFn[0],
valvec[spl->spl_left[i]].key, valvec[spl->spl_left[i]].key,
valvec[spl->spl_right[j]].key, valvec[spl->spl_right[j]].key,
PointerGetDatum(&result)); PointerGetDatum(&result));
if ( result ) { if (result)
{
spl->spl_idgrp[spl->spl_right[j]] = curid; spl->spl_idgrp[spl->spl_right[j]] = curid;
len++; len++;
} }
} }
/* find all other equal value in left part */ /* find all other equal value in left part */
if ( len ) { if (len)
{
/* add current val to list of equial values */ /* add current val to list of equial values */
spl->spl_idgrp[spl->spl_left[i]] = curid; spl->spl_idgrp[spl->spl_left[i]] = curid;
/* searching .. */ /* searching .. */
for(j=i+1; j < spl->spl_nleft; j++) { for (j = i + 1; j < spl->spl_nleft; j++)
if ( spl->spl_idgrp[ spl->spl_left[j] ]) continue; {
if (spl->spl_idgrp[spl->spl_left[j]])
continue;
FunctionCall3(&giststate->equalFn[0], FunctionCall3(&giststate->equalFn[0],
valvec[spl->spl_left[i]].key, valvec[spl->spl_left[i]].key,
valvec[spl->spl_left[j]].key, valvec[spl->spl_left[j]].key,
PointerGetDatum(&result)); PointerGetDatum(&result));
if ( result ) { if (result)
{
spl->spl_idgrp[spl->spl_left[j]] = curid; spl->spl_idgrp[spl->spl_left[j]] = curid;
len++; len++;
} }
@ -972,36 +1038,46 @@ gistadjsubkey(Relation r,
int *len, int *len,
GIST_SPLITVEC *v, GIST_SPLITVEC *v,
GISTSTATE *giststate GISTSTATE *giststate
) { )
{
int curlen; int curlen;
OffsetNumber *curwpos; OffsetNumber *curwpos;
bool decfree[INDEX_MAX_KEYS]; bool decfree[INDEX_MAX_KEYS];
GISTENTRY entry,identry[INDEX_MAX_KEYS], *ev0p, *ev1p; GISTENTRY entry,
float lpenalty, rpenalty; identry[INDEX_MAX_KEYS],
*ev0p,
*ev1p;
float lpenalty,
rpenalty;
bytea *evec; bytea *evec;
int datumsize; int datumsize;
bool isnull[INDEX_MAX_KEYS]; bool isnull[INDEX_MAX_KEYS];
int i,j; int i,
j;
Datum datum; Datum datum;
/* clear vectors */ /* clear vectors */
curlen = v->spl_nleft; curlen = v->spl_nleft;
curwpos = v->spl_left; curwpos = v->spl_left;
for (i = 0; i < v->spl_nleft; i++) for (i = 0; i < v->spl_nleft; i++)
if ( v->spl_idgrp[ v->spl_left[i] ] == 0 ) { if (v->spl_idgrp[v->spl_left[i]] == 0)
{
*curwpos = v->spl_left[i]; *curwpos = v->spl_left[i];
curwpos++; curwpos++;
} else }
else
curlen--; curlen--;
v->spl_nleft = curlen; v->spl_nleft = curlen;
curlen = v->spl_nright; curlen = v->spl_nright;
curwpos = v->spl_right; curwpos = v->spl_right;
for (i = 0; i < v->spl_nright; i++) for (i = 0; i < v->spl_nright; i++)
if ( v->spl_idgrp[ v->spl_right[i] ] == 0 ) { if (v->spl_idgrp[v->spl_right[i]] == 0)
{
*curwpos = v->spl_right[i]; *curwpos = v->spl_right[i];
curwpos++; curwpos++;
} else }
else
curlen--; curlen--;
v->spl_nright = curlen; v->spl_nright = curlen;
@ -1011,7 +1087,8 @@ gistadjsubkey(Relation r,
ev1p = &((GISTENTRY *) VARDATA(evec))[1]; ev1p = &((GISTENTRY *) VARDATA(evec))[1];
/* add equivalent tuple */ /* add equivalent tuple */
for(i = 0; i< *len; i++) { for (i = 0; i < *len; i++)
{
if (v->spl_idgrp[i + 1] == 0) /* already inserted */ if (v->spl_idgrp[i + 1] == 0) /* already inserted */
continue; continue;
gistDeCompressAtt(giststate, r, itup[i], (Page) NULL, (OffsetNumber) 0, gistDeCompressAtt(giststate, r, itup[i], (Page) NULL, (OffsetNumber) 0,
@ -1019,14 +1096,18 @@ gistadjsubkey(Relation r,
v->spl_ngrp[v->spl_idgrp[i + 1]]--; v->spl_ngrp[v->spl_idgrp[i + 1]]--;
if (v->spl_ngrp[v->spl_idgrp[i + 1]] == 0 && if (v->spl_ngrp[v->spl_idgrp[i + 1]] == 0 &&
(v->spl_grpflag[ v->spl_idgrp[ i+1 ] ] & BOTH_ADDED) != BOTH_ADDED ) { (v->spl_grpflag[v->spl_idgrp[i + 1]] & BOTH_ADDED) != BOTH_ADDED)
{
/* force last in group */ /* force last in group */
rpenalty = 1.0; rpenalty = 1.0;
lpenalty = (v->spl_grpflag[v->spl_idgrp[i + 1]] & LEFT_ADDED) ? 2.0 : 0.0; lpenalty = (v->spl_grpflag[v->spl_idgrp[i + 1]] & LEFT_ADDED) ? 2.0 : 0.0;
} else { }
else
{
/* where? */ /* where? */
for( j=1; j<r->rd_att->natts; j++ ) { for (j = 1; j < r->rd_att->natts; j++)
{
gistentryinit(entry, v->spl_lattr[j], r, (Page) NULL, gistentryinit(entry, v->spl_lattr[j], r, (Page) NULL,
(OffsetNumber) 0, v->spl_lattrsize[j], FALSE); (OffsetNumber) 0, v->spl_lattrsize[j], FALSE);
gistpenalty(giststate, j, &entry, v->spl_lisnull[j], gistpenalty(giststate, j, &entry, v->spl_lisnull[j],
@ -1042,15 +1123,20 @@ gistadjsubkey(Relation r,
} }
} }
/* add */ /* add */
if ( lpenalty < rpenalty ) { if (lpenalty < rpenalty)
{
v->spl_grpflag[v->spl_idgrp[i + 1]] |= LEFT_ADDED; v->spl_grpflag[v->spl_idgrp[i + 1]] |= LEFT_ADDED;
v->spl_left[v->spl_nleft] = i + 1; v->spl_left[v->spl_nleft] = i + 1;
v->spl_nleft++; v->spl_nleft++;
for( j=1; j<r->rd_att->natts; j++ ) { for (j = 1; j < r->rd_att->natts; j++)
if ( isnull[j] && v->spl_lisnull[j] ) { {
if (isnull[j] && v->spl_lisnull[j])
{
v->spl_lattr[j] = (Datum) 0; v->spl_lattr[j] = (Datum) 0;
v->spl_lattrsize[j] = 0; v->spl_lattrsize[j] = 0;
} else { }
else
{
FILLEV( FILLEV(
v->spl_lisnull[j], v->spl_lattr[j], v->spl_lattrsize[j], v->spl_lisnull[j], v->spl_lattr[j], v->spl_lattrsize[j],
isnull[j], identry[j].key, identry[j].bytes isnull[j], identry[j].key, identry[j].bytes
@ -1067,15 +1153,21 @@ gistadjsubkey(Relation r,
v->spl_lisnull[j] = false; v->spl_lisnull[j] = false;
} }
} }
} else { }
else
{
v->spl_grpflag[v->spl_idgrp[i + 1]] |= RIGHT_ADDED; v->spl_grpflag[v->spl_idgrp[i + 1]] |= RIGHT_ADDED;
v->spl_right[v->spl_nright] = i + 1; v->spl_right[v->spl_nright] = i + 1;
v->spl_nright++; v->spl_nright++;
for( j=1; j<r->rd_att->natts; j++ ) { for (j = 1; j < r->rd_att->natts; j++)
if ( isnull[j] && v->spl_risnull[j] ) { {
if (isnull[j] && v->spl_risnull[j])
{
v->spl_rattr[j] = (Datum) 0; v->spl_rattr[j] = (Datum) 0;
v->spl_rattrsize[j] = 0; v->spl_rattrsize[j] = 0;
} else { }
else
{
FILLEV( FILLEV(
v->spl_risnull[j], v->spl_rattr[j], v->spl_rattrsize[j], v->spl_risnull[j], v->spl_rattr[j], v->spl_rattrsize[j],
isnull[j], identry[j].key, identry[j].bytes isnull[j], identry[j].key, identry[j].bytes
@ -1125,7 +1217,8 @@ gistSplit(Relation r,
GIST_SPLITVEC v; GIST_SPLITVEC v;
bytea *entryvec; bytea *entryvec;
bool *decompvec; bool *decompvec;
int i,j, int i,
j,
nlen; nlen;
int MaxGrpId = 1; int MaxGrpId = 1;
Datum datum; Datum datum;
@ -1177,8 +1270,10 @@ gistSplit(Relation r,
decompvec[i] = FALSE; decompvec[i] = FALSE;
} }
/* now let the user-defined picksplit function set up the split vector; /*
in entryvec have no null value!! */ * now let the user-defined picksplit function set up the split
* vector; in entryvec have no null value!!
*/
FunctionCall2(&giststate->picksplitFn[0], FunctionCall2(&giststate->picksplitFn[0],
PointerGetDatum(entryvec), PointerGetDatum(entryvec),
PointerGetDatum(&v)); PointerGetDatum(&v));
@ -1194,10 +1289,12 @@ gistSplit(Relation r,
v.spl_lisnull[0] = false; v.spl_lisnull[0] = false;
v.spl_risnull[0] = false; v.spl_risnull[0] = false;
/* if index is multikey, then we must to try get smaller /*
* bounding box for subkey(s) * if index is multikey, then we must to try get smaller bounding box
* for subkey(s)
*/ */
if ( r->rd_att->natts > 1 ) { if (r->rd_att->natts > 1)
{
v.spl_idgrp = (int *) palloc(sizeof(int) * (*len + 1)); v.spl_idgrp = (int *) palloc(sizeof(int) * (*len + 1));
MemSet((void *) v.spl_idgrp, 0, sizeof(int) * (*len + 1)); MemSet((void *) v.spl_idgrp, 0, sizeof(int) * (*len + 1));
v.spl_grpflag = (char *) palloc(sizeof(char) * (*len + 1)); v.spl_grpflag = (char *) palloc(sizeof(char) * (*len + 1));
@ -1209,8 +1306,9 @@ gistSplit(Relation r,
/* form union of sub keys for each page (l,p) */ /* form union of sub keys for each page (l,p) */
gistunionsubkey(r, giststate, itup, &v); gistunionsubkey(r, giststate, itup, &v);
/* if possible, we insert equivalent tuples /*
* with control by penalty for a subkey(s) * if possible, we insert equivalent tuples with control by
* penalty for a subkey(s)
*/ */
if (MaxGrpId > 1) if (MaxGrpId > 1)
gistadjsubkey(r, itup, len, &v, giststate); gistadjsubkey(r, itup, len, &v, giststate);
@ -1359,10 +1457,13 @@ gistchoose(Relation r, Page p, IndexTuple it, /* it has compressed entry */
Datum datum; Datum datum;
float usize; float usize;
OffsetNumber which; OffsetNumber which;
float sum_grow, which_grow[INDEX_MAX_KEYS]; float sum_grow,
which_grow[INDEX_MAX_KEYS];
GISTENTRY entry, GISTENTRY entry,
identry[INDEX_MAX_KEYS]; identry[INDEX_MAX_KEYS];
bool IsNull, decompvec[INDEX_MAX_KEYS], isnull[INDEX_MAX_KEYS]; bool IsNull,
decompvec[INDEX_MAX_KEYS],
isnull[INDEX_MAX_KEYS];
int j; int j;
maxoff = PageGetMaxOffsetNumber(p); maxoff = PageGetMaxOffsetNumber(p);
@ -1376,8 +1477,10 @@ gistchoose(Relation r, Page p, IndexTuple it, /* it has compressed entry */
for (i = FirstOffsetNumber; i <= maxoff && sum_grow; i = OffsetNumberNext(i)) for (i = FirstOffsetNumber; i <= maxoff && sum_grow; i = OffsetNumberNext(i))
{ {
IndexTuple itup = (IndexTuple) PageGetItem(p, PageGetItemId(p, i)); IndexTuple itup = (IndexTuple) PageGetItem(p, PageGetItemId(p, i));
sum_grow = 0; sum_grow = 0;
for (j=0; j<r->rd_att->natts; j++) { for (j = 0; j < r->rd_att->natts; j++)
{
datum = index_getattr(itup, j + 1, giststate->tupdesc, &IsNull); datum = index_getattr(itup, j + 1, giststate->tupdesc, &IsNull);
gistdentryinit(giststate, j, &entry, datum, r, p, i, ATTSIZE(datum, giststate->tupdesc, j + 1, IsNull), FALSE, IsNull); gistdentryinit(giststate, j, &entry, datum, r, p, i, ATTSIZE(datum, giststate->tupdesc, j + 1, IsNull), FALSE, IsNull);
gistpenalty(giststate, j, &entry, IsNull, &identry[j], isnull[j], &usize); gistpenalty(giststate, j, &entry, IsNull, &identry[j], isnull[j], &usize);
@ -1385,14 +1488,18 @@ gistchoose(Relation r, Page p, IndexTuple it, /* it has compressed entry */
if ((!isAttByVal(giststate, j)) && entry.key != datum) if ((!isAttByVal(giststate, j)) && entry.key != datum)
pfree(DatumGetPointer(entry.key)); pfree(DatumGetPointer(entry.key));
if ( which_grow[j]<0 || usize < which_grow[j] ) { if (which_grow[j] < 0 || usize < which_grow[j])
{
which = i; which = i;
which_grow[j] = usize; which_grow[j] = usize;
if ( j<r->rd_att->natts-1 && i==FirstOffsetNumber ) which_grow[j+1]=-1; if (j < r->rd_att->natts - 1 && i == FirstOffsetNumber)
which_grow[j + 1] = -1;
sum_grow += which_grow[j]; sum_grow += which_grow[j];
} else if ( which_grow[j] == usize ) { }
else if (which_grow[j] == usize)
sum_grow += usize; sum_grow += usize;
} else { else
{
sum_grow = 1; sum_grow = 1;
break; break;
} }
@ -1577,7 +1684,8 @@ initGISTstate(GISTSTATE *giststate, Relation index)
} }
void void
freeGISTstate(GISTSTATE *giststate) { freeGISTstate(GISTSTATE *giststate)
{
/* no work */ /* no work */
} }
@ -1597,8 +1705,9 @@ gist_tuple_replacekey(Relation r, GISTENTRY entry, IndexTuple t)
/* /*
* If new entry fits in index tuple, copy it in. To avoid worrying * If new entry fits in index tuple, copy it in. To avoid worrying
* about null-value bitmask, pass it off to the general index_formtuple * about null-value bitmask, pass it off to the general
* routine if either the previous or new value is NULL. * index_formtuple routine if either the previous or new value is
* NULL.
*/ */
if (!IsNull && DatumGetPointer(entry.key) != NULL && if (!IsNull && DatumGetPointer(entry.key) != NULL &&
(Size) entry.bytes <= ATTSIZE(datum, r, 1, IsNull)) (Size) entry.bytes <= ATTSIZE(datum, r, 1, IsNull))
@ -1655,10 +1764,8 @@ gistdentryinit(GISTSTATE *giststate, int nkey, GISTENTRY *e,
} }
} }
else else
{
gistentryinit(*e, (Datum) 0, r, pg, o, 0, l); gistentryinit(*e, (Datum) 0, r, pg, o, 0, l);
} }
}
/* /*
@ -1686,10 +1793,8 @@ gistcentryinit(GISTSTATE *giststate, int nkey,
} }
} }
else else
{
gistentryinit(*e, (Datum) 0, r, pg, o, 0, l); gistentryinit(*e, (Datum) 0, r, pg, o, 0, l);
} }
}
static IndexTuple static IndexTuple
gistFormTuple(GISTSTATE *giststate, Relation r, gistFormTuple(GISTSTATE *giststate, Relation r,
@ -1702,47 +1807,57 @@ gistFormTuple( GISTSTATE *giststate, Relation r,
Datum compatt[INDEX_MAX_KEYS]; Datum compatt[INDEX_MAX_KEYS];
int j; int j;
for (j = 0; j < r->rd_att->natts; j++) { for (j = 0; j < r->rd_att->natts; j++)
if ( isnull[j] ) { {
if (isnull[j])
{
isnullchar[j] = 'n'; isnullchar[j] = 'n';
compatt[j] = (Datum) 0; compatt[j] = (Datum) 0;
whatfree[j] = FALSE; whatfree[j] = FALSE;
} else { }
else
{
gistcentryinit(giststate, j, &centry[j], attdata[j], gistcentryinit(giststate, j, &centry[j], attdata[j],
(Relation) NULL, (Page) NULL, (OffsetNumber) NULL, (Relation) NULL, (Page) NULL, (OffsetNumber) NULL,
datumsize[j], FALSE, FALSE); datumsize[j], FALSE, FALSE);
isnullchar[j] = ' '; isnullchar[j] = ' ';
compatt[j] = centry[j].key; compatt[j] = centry[j].key;
if ( !isAttByVal(giststate,j) ) { if (!isAttByVal(giststate, j))
{
whatfree[j] = TRUE; whatfree[j] = TRUE;
if (centry[j].key != attdata[j]) if (centry[j].key != attdata[j])
pfree(DatumGetPointer(attdata[j])); pfree(DatumGetPointer(attdata[j]));
} else }
else
whatfree[j] = FALSE; whatfree[j] = FALSE;
} }
} }
tup = (IndexTuple) index_formtuple(giststate->tupdesc, compatt, isnullchar); tup = (IndexTuple) index_formtuple(giststate->tupdesc, compatt, isnullchar);
for (j = 0; j < r->rd_att->natts; j++) for (j = 0; j < r->rd_att->natts; j++)
if ( whatfree[j] ) pfree(DatumGetPointer(compatt[j])); if (whatfree[j])
pfree(DatumGetPointer(compatt[j]));
return tup; return tup;
} }
static void static void
gistDeCompressAtt(GISTSTATE *giststate, Relation r, IndexTuple tuple, Page p, gistDeCompressAtt(GISTSTATE *giststate, Relation r, IndexTuple tuple, Page p,
OffsetNumber o, GISTENTRY attdata[], bool decompvec[], bool isnull[] ) { OffsetNumber o, GISTENTRY attdata[], bool decompvec[], bool isnull[])
{
int i; int i;
Datum datum; Datum datum;
for(i=0; i < r->rd_att->natts; i++ ) { for (i = 0; i < r->rd_att->natts; i++)
{
datum = index_getattr(tuple, i + 1, giststate->tupdesc, &isnull[i]); datum = index_getattr(tuple, i + 1, giststate->tupdesc, &isnull[i]);
gistdentryinit(giststate, i, &attdata[i], gistdentryinit(giststate, i, &attdata[i],
datum, r, p, o, datum, r, p, o,
ATTSIZE(datum, giststate->tupdesc, i + 1, isnull[i]), FALSE, isnull[i]); ATTSIZE(datum, giststate->tupdesc, i + 1, isnull[i]), FALSE, isnull[i]);
if (isAttByVal(giststate, i)) if (isAttByVal(giststate, i))
decompvec[i] = FALSE; decompvec[i] = FALSE;
else { else
{
if (attdata[i].key == datum || isnull[i]) if (attdata[i].key == datum || isnull[i])
decompvec[i] = FALSE; decompvec[i] = FALSE;
else else
@ -1752,8 +1867,10 @@ gistDeCompressAtt( GISTSTATE *giststate, Relation r, IndexTuple tuple, Page p,
} }
static void static void
gistFreeAtt( Relation r, GISTENTRY attdata[], bool decompvec[] ) { gistFreeAtt(Relation r, GISTENTRY attdata[], bool decompvec[])
{
int i; int i;
for (i = 0; i < r->rd_att->natts; i++) for (i = 0; i < r->rd_att->natts; i++)
if (decompvec[i]) if (decompvec[i])
pfree(DatumGetPointer(attdata[i].key)); pfree(DatumGetPointer(attdata[i].key));
@ -1762,7 +1879,8 @@ gistFreeAtt( Relation r, GISTENTRY attdata[], bool decompvec[] ) {
static void static void
gistpenalty(GISTSTATE *giststate, int attno, gistpenalty(GISTSTATE *giststate, int attno,
GISTENTRY *key1, bool isNull1, GISTENTRY *key1, bool isNull1,
GISTENTRY *key2, bool isNull2, float *penalty ){ GISTENTRY *key2, bool isNull2, float *penalty)
{
if (giststate->penaltyFn[attno].fn_strict && (isNull1 || isNull2)) if (giststate->penaltyFn[attno].fn_strict && (isNull1 || isNull2))
*penalty = 0.0; *penalty = 0.0;
else else
@ -1816,7 +1934,6 @@ gist_dumptree(Relation r, int level, BlockNumber blk, OffsetNumber coff)
ReleaseBuffer(buffer); ReleaseBuffer(buffer);
pfree(pred); pfree(pred);
} }
#endif /* defined GISTDEBUG */ #endif /* defined GISTDEBUG */
void void

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/access/gist/gistget.c,v 1.30 2001/08/22 18:24:26 tgl Exp $ * $Header: /cvsroot/pgsql/src/backend/access/gist/gistget.c,v 1.31 2001/10/25 05:49:20 momjian Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */

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/access/gist/gistscan.c,v 1.39 2001/08/22 18:24:26 tgl Exp $ * $Header: /cvsroot/pgsql/src/backend/access/gist/gistscan.c,v 1.40 2001/10/25 05:49:20 momjian Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
@ -383,7 +383,6 @@ adjustiptr(IndexScanDesc s,
} }
else else
{ {
/* /*
* remember that we're before the current * remember that we're before the current
* tuple * tuple

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/access/gist/Attic/giststrat.c,v 1.17 2001/05/30 19:53:40 tgl Exp $ * $Header: /cvsroot/pgsql/src/backend/access/gist/Attic/giststrat.c,v 1.18 2001/10/25 05:49:20 momjian Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
@ -121,5 +121,4 @@ RelationInvokeGISTStrategy(Relation r,
return (RelationInvokeStrategy(r, &GISTEvaluationData, attnum, s, return (RelationInvokeStrategy(r, &GISTEvaluationData, attnum, s,
left, right)); left, right));
} }
#endif #endif

View File

@ -8,7 +8,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/access/hash/hash.c,v 1.52 2001/07/15 22:48:15 tgl Exp $ * $Header: /cvsroot/pgsql/src/backend/access/hash/hash.c,v 1.53 2001/10/25 05:49:20 momjian Exp $
* *
* NOTES * NOTES
* This file contains only the public interface routines. * This file contains only the public interface routines.
@ -164,6 +164,7 @@ hashinsert(PG_FUNCTION_ARGS)
Datum *datum = (Datum *) PG_GETARG_POINTER(1); Datum *datum = (Datum *) PG_GETARG_POINTER(1);
char *nulls = (char *) PG_GETARG_POINTER(2); char *nulls = (char *) PG_GETARG_POINTER(2);
ItemPointer ht_ctid = (ItemPointer) PG_GETARG_POINTER(3); ItemPointer ht_ctid = (ItemPointer) PG_GETARG_POINTER(3);
#ifdef NOT_USED #ifdef NOT_USED
Relation heapRel = (Relation) PG_GETARG_POINTER(4); Relation heapRel = (Relation) PG_GETARG_POINTER(4);
#endif #endif
@ -176,14 +177,13 @@ hashinsert(PG_FUNCTION_ARGS)
itup->t_tid = *ht_ctid; itup->t_tid = *ht_ctid;
/* /*
* If the single index key is null, we don't insert it into the * If the single index key is null, we don't insert it into the index.
* index. Hash tables support scans on '='. Relational algebra * Hash tables support scans on '='. Relational algebra says that A =
* says that A = B returns null if either A or B is null. This * B returns null if either A or B is null. This means that no
* means that no qualification used in an index scan could ever * qualification used in an index scan could ever return true on a
* return true on a null attribute. It also means that indices * null attribute. It also means that indices can't be used by ISNULL
* can't be used by ISNULL or NOTNULL scans, but that's an * or NOTNULL scans, but that's an artifact of the strategy map
* artifact of the strategy map architecture chosen in 1986, not * architecture chosen in 1986, not of the way nulls are handled here.
* of the way nulls are handled here.
*/ */
if (IndexTupleHasNulls(itup)) if (IndexTupleHasNulls(itup))
{ {
@ -262,7 +262,6 @@ hashrescan(PG_FUNCTION_ARGS)
#ifdef NOT_USED /* XXX surely it's wrong to ignore this? */ #ifdef NOT_USED /* XXX surely it's wrong to ignore this? */
bool fromEnd = PG_GETARG_BOOL(1); bool fromEnd = PG_GETARG_BOOL(1);
#endif #endif
ScanKey scankey = (ScanKey) PG_GETARG_POINTER(2); ScanKey scankey = (ScanKey) PG_GETARG_POINTER(2);
ItemPointer iptr; ItemPointer iptr;

View File

@ -8,7 +8,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/access/hash/hashinsert.c,v 1.22 2001/03/07 21:20:26 tgl Exp $ * $Header: /cvsroot/pgsql/src/backend/access/hash/hashinsert.c,v 1.23 2001/10/25 05:49:21 momjian Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
@ -133,13 +133,11 @@ _hash_insertonpg(Relation rel,
while (PageGetFreeSpace(page) < itemsz) while (PageGetFreeSpace(page) < itemsz)
{ {
/* /*
* no space on this page; check for an overflow page * no space on this page; check for an overflow page
*/ */
if (BlockNumberIsValid(pageopaque->hasho_nextblkno)) if (BlockNumberIsValid(pageopaque->hasho_nextblkno))
{ {
/* /*
* ovfl page exists; go get it. if it doesn't have room, * ovfl page exists; go get it. if it doesn't have room,
* we'll find out next pass through the loop test above. * we'll find out next pass through the loop test above.
@ -152,7 +150,6 @@ _hash_insertonpg(Relation rel,
} }
else else
{ {
/* /*
* we're at the end of the bucket chain and we haven't found a * we're at the end of the bucket chain and we haven't found a
* page with enough room. allocate a new overflow page. * page with enough room. allocate a new overflow page.
@ -184,7 +181,6 @@ _hash_insertonpg(Relation rel,
if (res != NULL) if (res != NULL)
{ {
/* /*
* Increment the number of keys in the table. We switch lock * Increment the number of keys in the table. We switch lock
* access type just for a moment to allow greater accessibility to * access type just for a moment to allow greater accessibility to

View File

@ -8,7 +8,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/access/hash/hashovfl.c,v 1.30 2001/07/15 22:48:15 tgl Exp $ * $Header: /cvsroot/pgsql/src/backend/access/hash/hashovfl.c,v 1.31 2001/10/25 05:49:21 momjian Exp $
* *
* NOTES * NOTES
* Overflow pages look like ordinary relation pages. * Overflow pages look like ordinary relation pages.
@ -208,7 +208,6 @@ _hash_getovfladdr(Relation rel, Buffer *metabufp)
} }
else else
{ {
/* /*
* Free_bit addresses the last used bit. Bump it to address the * Free_bit addresses the last used bit. Bump it to address the
* first available bit. * first available bit.

View File

@ -8,7 +8,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/access/hash/hashpage.c,v 1.32 2001/07/15 22:48:15 tgl Exp $ * $Header: /cvsroot/pgsql/src/backend/access/hash/hashpage.c,v 1.33 2001/10/25 05:49:21 momjian Exp $
* *
* NOTES * NOTES
* Postgres hash pages look like ordinary relation pages. The opaque * Postgres hash pages look like ordinary relation pages. The opaque
@ -532,7 +532,6 @@ _hash_splitpage(Relation rel,
_hash_relbuf(rel, obuf, HASH_WRITE); _hash_relbuf(rel, obuf, HASH_WRITE);
if (!BlockNumberIsValid(oblkno)) if (!BlockNumberIsValid(oblkno))
{ {
/* /*
* the old bucket is completely empty; of course, the new * the old bucket is completely empty; of course, the new
* bucket will be as well, but since it's a base bucket page * bucket will be as well, but since it's a base bucket page
@ -559,7 +558,6 @@ _hash_splitpage(Relation rel,
omaxoffnum = PageGetMaxOffsetNumber(opage); omaxoffnum = PageGetMaxOffsetNumber(opage);
for (;;) for (;;)
{ {
/* /*
* at each iteration through this loop, each of these variables * at each iteration through this loop, each of these variables
* should be up-to-date: obuf opage oopaque ooffnum omaxoffnum * should be up-to-date: obuf opage oopaque ooffnum omaxoffnum
@ -572,7 +570,6 @@ _hash_splitpage(Relation rel,
oblkno = oopaque->hasho_nextblkno; oblkno = oopaque->hasho_nextblkno;
if (BlockNumberIsValid(oblkno)) if (BlockNumberIsValid(oblkno))
{ {
/* /*
* we ran out of tuples on this particular page, but we * we ran out of tuples on this particular page, but we
* have more overflow pages; re-init values. * have more overflow pages; re-init values.
@ -594,7 +591,6 @@ _hash_splitpage(Relation rel,
} }
else else
{ {
/* /*
* we're at the end of the bucket chain, so now we're * we're at the end of the bucket chain, so now we're
* really done with everything. before quitting, call * really done with everything. before quitting, call
@ -618,7 +614,6 @@ _hash_splitpage(Relation rel,
if (bucket == nbucket) if (bucket == nbucket)
{ {
/* /*
* insert the tuple into the new bucket. if it doesn't fit on * insert the tuple into the new bucket. if it doesn't fit on
* the current page in the new bucket, we must allocate a new * the current page in the new bucket, we must allocate a new
@ -695,7 +690,6 @@ _hash_splitpage(Relation rel,
} }
else else
{ {
/* /*
* the tuple stays on this page. we didn't move anything, so * the tuple stays on this page. we didn't move anything, so
* we didn't delete anything and therefore we don't have to * we didn't delete anything and therefore we don't have to

View File

@ -8,7 +8,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/access/hash/hashsearch.c,v 1.26 2001/03/23 04:49:51 momjian Exp $ * $Header: /cvsroot/pgsql/src/backend/access/hash/hashsearch.c,v 1.27 2001/10/25 05:49:21 momjian Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
@ -36,7 +36,6 @@ _hash_search(Relation rel,
if (scankey == (ScanKey) NULL || if (scankey == (ScanKey) NULL ||
(keyDatum = scankey[0].sk_argument) == (Datum) NULL) (keyDatum = scankey[0].sk_argument) == (Datum) NULL)
{ {
/* /*
* If the scankey argument is NULL, all tuples will satisfy the * If the scankey argument is NULL, all tuples will satisfy the
* scan so we start the scan at the first bucket (bucket 0). * scan so we start the scan at the first bucket (bucket 0).

View File

@ -8,7 +8,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/access/hash/Attic/hashstrat.c,v 1.18 2001/05/30 19:53:40 tgl Exp $ * $Header: /cvsroot/pgsql/src/backend/access/hash/Attic/hashstrat.c,v 1.19 2001/10/25 05:49:21 momjian Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
@ -46,7 +46,6 @@ static StrategyEvaluationData HTEvaluationData = {
(StrategyTransformMap) HTNegateCommute, (StrategyTransformMap) HTNegateCommute,
HTEvaluationExpressions HTEvaluationExpressions
}; };
#endif #endif
/* ---------------------------------------------------------------- /* ----------------------------------------------------------------
@ -68,7 +67,6 @@ _hash_getstrat(Relation rel,
return strat; return strat;
} }
#endif #endif
#ifdef NOT_USED #ifdef NOT_USED
@ -82,5 +80,4 @@ _hash_invokestrat(Relation rel,
return (RelationInvokeStrategy(rel, &HTEvaluationData, attno, strat, return (RelationInvokeStrategy(rel, &HTEvaluationData, attno, strat,
left, right)); left, right));
} }
#endif #endif

View File

@ -8,7 +8,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/access/heap/heapam.c,v 1.125 2001/08/23 23:06:37 tgl Exp $ * $Header: /cvsroot/pgsql/src/backend/access/heap/heapam.c,v 1.126 2001/10/25 05:49:21 momjian Exp $
* *
* *
* INTERFACE ROUTINES * INTERFACE ROUTINES
@ -431,7 +431,6 @@ fastgetattr(HeapTuple tup, int attnum, TupleDesc tupleDesc,
) )
); );
} }
#endif /* defined(DISABLE_COMPLEX_MACRO) */ #endif /* defined(DISABLE_COMPLEX_MACRO) */
@ -1045,12 +1044,13 @@ heap_insert(Relation relation, HeapTuple tup)
if (relation->rd_rel->relhasoids) if (relation->rd_rel->relhasoids)
{ {
/* /*
* If the object id of this tuple has already been assigned, trust the * If the object id of this tuple has already been assigned, trust
* caller. There are a couple of ways this can happen. At initial db * the caller. There are a couple of ways this can happen. At
* creation, the backend program sets oids for tuples. When we define * initial db creation, the backend program sets oids for tuples.
* an index, we set the oid. Finally, in the future, we may allow * When we define an index, we set the oid. Finally, in the
* users to set their own object ids in order to support a persistent * future, we may allow users to set their own object ids in order
* object store (objects need to contain pointers to one another). * to support a persistent object store (objects need to contain
* pointers to one another).
*/ */
if (!OidIsValid(tup->t_data->t_oid)) if (!OidIsValid(tup->t_data->t_oid))
tup->t_data->t_oid = newoid(); tup->t_data->t_oid = newoid();
@ -1478,21 +1478,22 @@ l2:
} }
/* /*
* Now, do we need a new page for the tuple, or not? This is a bit * Now, do we need a new page for the tuple, or not? This is a
* tricky since someone else could have added tuples to the page * bit tricky since someone else could have added tuples to the
* while we weren't looking. We have to recheck the available space * page while we weren't looking. We have to recheck the
* after reacquiring the buffer lock. But don't bother to do that * available space after reacquiring the buffer lock. But don't
* if the former amount of free space is still not enough; it's * bother to do that if the former amount of free space is still
* unlikely there's more free now than before. * not enough; it's unlikely there's more free now than before.
* *
* What's more, if we need to get a new page, we will need to acquire * What's more, if we need to get a new page, we will need to acquire
* buffer locks on both old and new pages. To avoid deadlock against * buffer locks on both old and new pages. To avoid deadlock
* some other backend trying to get the same two locks in the other * against some other backend trying to get the same two locks in
* order, we must be consistent about the order we get the locks in. * the other order, we must be consistent about the order we get
* We use the rule "lock the lower-numbered page of the relation * the locks in. We use the rule "lock the lower-numbered page of
* first". To implement this, we must do RelationGetBufferForTuple * the relation first". To implement this, we must do
* while not holding the lock on the old page, and we must rely on it * RelationGetBufferForTuple while not holding the lock on the old
* to get the locks on both pages in the correct order. * page, and we must rely on it to get the locks on both pages in
* the correct order.
*/ */
if (newtupsize > pagefree) if (newtupsize > pagefree)
{ {
@ -1510,8 +1511,8 @@ l2:
{ {
/* /*
* Rats, it doesn't fit anymore. We must now unlock and * Rats, it doesn't fit anymore. We must now unlock and
* relock to avoid deadlock. Fortunately, this path should * relock to avoid deadlock. Fortunately, this path
* seldom be taken. * should seldom be taken.
*/ */
LockBuffer(buffer, BUFFER_LOCK_UNLOCK); LockBuffer(buffer, BUFFER_LOCK_UNLOCK);
newbuf = RelationGetBufferForTuple(relation, newtup->t_len, newbuf = RelationGetBufferForTuple(relation, newtup->t_len,
@ -1534,9 +1535,9 @@ l2:
pgstat_count_heap_update(&relation->pgstat_info); pgstat_count_heap_update(&relation->pgstat_info);
/* /*
* At this point newbuf and buffer are both pinned and locked, * At this point newbuf and buffer are both pinned and locked, and
* and newbuf has enough space for the new tuple. If they are * newbuf has enough space for the new tuple. If they are the same
* the same buffer, only one pin is held. * buffer, only one pin is held.
*/ */
/* NO ELOG(ERROR) from here till changes are logged */ /* NO ELOG(ERROR) from here till changes are logged */
@ -1865,9 +1866,11 @@ log_heap_update(Relation reln, Buffer oldbuf, ItemPointerData from,
* Note: xlhdr is declared to have adequate size and correct alignment * Note: xlhdr is declared to have adequate size and correct alignment
* for an xl_heap_header. However the two tids, if present at all, * for an xl_heap_header. However the two tids, if present at all,
* will be packed in with no wasted space after the xl_heap_header; * will be packed in with no wasted space after the xl_heap_header;
* they aren't necessarily aligned as implied by this struct declaration. * they aren't necessarily aligned as implied by this struct
* declaration.
*/ */
struct { struct
{
xl_heap_header hdr; xl_heap_header hdr;
TransactionId tid1; TransactionId tid1;
TransactionId tid2; TransactionId tid2;
@ -2084,7 +2087,8 @@ heap_xlog_insert(bool redo, XLogRecPtr lsn, XLogRecord *record)
if (redo) if (redo)
{ {
struct { struct
{
HeapTupleHeaderData hdr; HeapTupleHeaderData hdr;
char data[MaxTupleSize]; char data[MaxTupleSize];
} tbuf; } tbuf;
@ -2251,7 +2255,8 @@ newsame:;
if (redo) if (redo)
{ {
struct { struct
{
HeapTupleHeaderData hdr; HeapTupleHeaderData hdr;
char data[MaxTupleSize]; char data[MaxTupleSize];
} tbuf; } tbuf;

View File

@ -8,7 +8,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $Id: hio.c,v 1.42 2001/07/13 22:52:58 tgl Exp $ * $Id: hio.c,v 1.43 2001/10/25 05:49:21 momjian Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
@ -115,7 +115,8 @@ RelationGetBufferForTuple(Relation relation, Size len,
if (otherBuffer != InvalidBuffer) if (otherBuffer != InvalidBuffer)
otherBlock = BufferGetBlockNumber(otherBuffer); otherBlock = BufferGetBlockNumber(otherBuffer);
else else
otherBlock = InvalidBlockNumber; /* just to keep compiler quiet */ otherBlock = InvalidBlockNumber; /* just to keep compiler
* quiet */
/* /*
* We first try to put the tuple on the same page we last inserted a * We first try to put the tuple on the same page we last inserted a
@ -123,9 +124,10 @@ RelationGetBufferForTuple(Relation relation, Size len,
* we ask the shared Free Space Map to locate a suitable page. Since * we ask the shared Free Space Map to locate a suitable page. Since
* the FSM's info might be out of date, we have to be prepared to loop * the FSM's info might be out of date, we have to be prepared to loop
* around and retry multiple times. (To insure this isn't an infinite * around and retry multiple times. (To insure this isn't an infinite
* loop, we must update the FSM with the correct amount of free space on * loop, we must update the FSM with the correct amount of free space
* each page that proves not to be suitable.) If the FSM has no record of * on each page that proves not to be suitable.) If the FSM has no
* a page with enough free space, we give up and extend the relation. * record of a page with enough free space, we give up and extend the
* relation.
*/ */
targetBlock = relation->rd_targblock; targetBlock = relation->rd_targblock;
@ -137,6 +139,7 @@ RelationGetBufferForTuple(Relation relation, Size len,
* target. * target.
*/ */
targetBlock = GetPageWithFreeSpace(&relation->rd_node, len); targetBlock = GetPageWithFreeSpace(&relation->rd_node, len);
/* /*
* If the FSM knows nothing of the rel, try the last page before * If the FSM knows nothing of the rel, try the last page before
* we give up and extend. This avoids one-tuple-per-page syndrome * we give up and extend. This avoids one-tuple-per-page syndrome
@ -154,9 +157,9 @@ RelationGetBufferForTuple(Relation relation, Size len,
while (targetBlock != InvalidBlockNumber) while (targetBlock != InvalidBlockNumber)
{ {
/* /*
* Read and exclusive-lock the target block, as well as the * Read and exclusive-lock the target block, as well as the other
* other block if one was given, taking suitable care with * block if one was given, taking suitable care with lock ordering
* lock ordering and the possibility they are the same block. * and the possibility they are the same block.
*/ */
if (otherBuffer == InvalidBuffer) if (otherBuffer == InvalidBuffer)
{ {
@ -184,9 +187,10 @@ RelationGetBufferForTuple(Relation relation, Size len,
LockBuffer(buffer, BUFFER_LOCK_EXCLUSIVE); LockBuffer(buffer, BUFFER_LOCK_EXCLUSIVE);
LockBuffer(otherBuffer, BUFFER_LOCK_EXCLUSIVE); LockBuffer(otherBuffer, BUFFER_LOCK_EXCLUSIVE);
} }
/* /*
* Now we can check to see if there's enough free space here. * Now we can check to see if there's enough free space here. If
* If so, we're done. * so, we're done.
*/ */
pageHeader = (Page) BufferGetPage(buffer); pageHeader = (Page) BufferGetPage(buffer);
pageFreeSpace = PageGetFreeSpace(pageHeader); pageFreeSpace = PageGetFreeSpace(pageHeader);
@ -196,22 +200,22 @@ RelationGetBufferForTuple(Relation relation, Size len,
relation->rd_targblock = targetBlock; relation->rd_targblock = targetBlock;
return buffer; return buffer;
} }
/* /*
* Not enough space, so we must give up our page locks and * Not enough space, so we must give up our page locks and pin (if
* pin (if any) and prepare to look elsewhere. We don't care * any) and prepare to look elsewhere. We don't care which order
* which order we unlock the two buffers in, so this can be * we unlock the two buffers in, so this can be slightly simpler
* slightly simpler than the code above. * than the code above.
*/ */
LockBuffer(buffer, BUFFER_LOCK_UNLOCK); LockBuffer(buffer, BUFFER_LOCK_UNLOCK);
if (otherBuffer == InvalidBuffer) if (otherBuffer == InvalidBuffer)
{
ReleaseBuffer(buffer); ReleaseBuffer(buffer);
}
else if (otherBlock != targetBlock) else if (otherBlock != targetBlock)
{ {
LockBuffer(otherBuffer, BUFFER_LOCK_UNLOCK); LockBuffer(otherBuffer, BUFFER_LOCK_UNLOCK);
ReleaseBuffer(buffer); ReleaseBuffer(buffer);
} }
/* /*
* Update FSM as to condition of this page, and ask for another * Update FSM as to condition of this page, and ask for another
* page to try. * page to try.
@ -225,9 +229,9 @@ RelationGetBufferForTuple(Relation relation, Size len,
/* /*
* Have to extend the relation. * Have to extend the relation.
* *
* We have to use a lock to ensure no one else is extending the * We have to use a lock to ensure no one else is extending the rel at
* rel at the same time, else we will both try to initialize the * the same time, else we will both try to initialize the same new
* same new page. * page.
*/ */
if (!relation->rd_myxactonly) if (!relation->rd_myxactonly)
LockPage(relation, 0, ExclusiveLock); LockPage(relation, 0, ExclusiveLock);
@ -236,20 +240,21 @@ RelationGetBufferForTuple(Relation relation, Size len,
* XXX This does an lseek - rather expensive - but at the moment it is * XXX This does an lseek - rather expensive - but at the moment it is
* the only way to accurately determine how many blocks are in a * the only way to accurately determine how many blocks are in a
* relation. Is it worth keeping an accurate file length in shared * relation. Is it worth keeping an accurate file length in shared
* memory someplace, rather than relying on the kernel to do it for us? * memory someplace, rather than relying on the kernel to do it for
* us?
*/ */
buffer = ReadBuffer(relation, P_NEW); buffer = ReadBuffer(relation, P_NEW);
/* /*
* Release the file-extension lock; it's now OK for someone else * Release the file-extension lock; it's now OK for someone else to
* to extend the relation some more. * extend the relation some more.
*/ */
if (!relation->rd_myxactonly) if (!relation->rd_myxactonly)
UnlockPage(relation, 0, ExclusiveLock); UnlockPage(relation, 0, ExclusiveLock);
/* /*
* We can be certain that locking the otherBuffer first is OK, * We can be certain that locking the otherBuffer first is OK, since
* since it must have a lower page number. * it must have a lower page number.
*/ */
if (otherBuffer != InvalidBuffer) if (otherBuffer != InvalidBuffer)
LockBuffer(otherBuffer, BUFFER_LOCK_EXCLUSIVE); LockBuffer(otherBuffer, BUFFER_LOCK_EXCLUSIVE);

View File

@ -8,7 +8,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/access/heap/Attic/stats.c,v 1.24 2001/03/22 06:16:07 momjian Exp $ * $Header: /cvsroot/pgsql/src/backend/access/heap/Attic/stats.c,v 1.25 2001/10/25 05:49:21 momjian Exp $
* *
* NOTES * NOTES
* initam should be moved someplace else. * initam should be moved someplace else.
@ -164,7 +164,6 @@ ResetHeapAccessStatistics()
time(&stats->local_reset_timestamp); time(&stats->local_reset_timestamp);
time(&stats->last_request_timestamp); time(&stats->last_request_timestamp);
} }
#endif #endif
#ifdef NOT_USED #ifdef NOT_USED
@ -200,7 +199,6 @@ GetHeapAccessStatistics()
return stats; return stats;
} }
#endif #endif
#ifdef NOT_USED #ifdef NOT_USED
@ -211,7 +209,6 @@ GetHeapAccessStatistics()
void void
PrintHeapAccessStatistics(HeapAccessStatistics stats) PrintHeapAccessStatistics(HeapAccessStatistics stats)
{ {
/* /*
* return nothing if stats aren't valid * return nothing if stats aren't valid
*/ */
@ -302,7 +299,6 @@ PrintHeapAccessStatistics(HeapAccessStatistics stats)
printf("\n"); printf("\n");
} }
#endif #endif
#ifdef NOT_USED #ifdef NOT_USED
@ -317,7 +313,6 @@ PrintAndFreeHeapAccessStatistics(HeapAccessStatistics stats)
if (stats != NULL) if (stats != NULL)
pfree(stats); pfree(stats);
} }
#endif #endif
/* ---------------------------------------------------------------- /* ----------------------------------------------------------------
@ -331,7 +326,6 @@ PrintAndFreeHeapAccessStatistics(HeapAccessStatistics stats)
void void
initam(void) initam(void)
{ {
/* /*
* initialize heap statistics. * initialize heap statistics.
*/ */

View File

@ -8,7 +8,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/access/heap/tuptoaster.c,v 1.24 2001/08/10 18:57:33 tgl Exp $ * $Header: /cvsroot/pgsql/src/backend/access/heap/tuptoaster.c,v 1.25 2001/10/25 05:49:21 momjian Exp $
* *
* *
* INTERFACE ROUTINES * INTERFACE ROUTINES
@ -81,7 +81,6 @@ heap_tuple_fetch_attr(varattrib *attr)
if (VARATT_IS_EXTERNAL(attr)) if (VARATT_IS_EXTERNAL(attr))
{ {
/* /*
* This is an external stored plain value * This is an external stored plain value
*/ */
@ -89,7 +88,6 @@ heap_tuple_fetch_attr(varattrib *attr)
} }
else else
{ {
/* /*
* This is a plain value inside of the main tuple - why am I * This is a plain value inside of the main tuple - why am I
* called? * called?
@ -135,7 +133,6 @@ heap_tuple_untoast_attr(varattrib *attr)
} }
else else
{ {
/* /*
* This is an external stored plain value * This is an external stored plain value
*/ */
@ -144,7 +141,6 @@ heap_tuple_untoast_attr(varattrib *attr)
} }
else if (VARATT_IS_COMPRESSED(attr)) else if (VARATT_IS_COMPRESSED(attr))
{ {
/* /*
* This is a compressed value inside of the main tuple * This is a compressed value inside of the main tuple
*/ */
@ -181,8 +177,8 @@ toast_raw_datum_size(Datum value)
if (VARATT_IS_COMPRESSED(attr)) if (VARATT_IS_COMPRESSED(attr))
{ {
/* /*
* va_rawsize shows the original data size, whether the datum * va_rawsize shows the original data size, whether the datum is
* is external or not. * external or not.
*/ */
result = attr->va_content.va_compressed.va_rawsize + VARHDRSZ; result = attr->va_content.va_compressed.va_rawsize + VARHDRSZ;
} }
@ -301,7 +297,6 @@ toast_insert_or_update(Relation rel, HeapTuple newtup, HeapTuple oldtup)
if (oldtup != NULL) if (oldtup != NULL)
{ {
/* /*
* For UPDATE get the old and new values of this attribute * For UPDATE get the old and new values of this attribute
*/ */
@ -324,7 +319,6 @@ toast_insert_or_update(Relation rel, HeapTuple newtup, HeapTuple oldtup)
old_value->va_content.va_external.va_toastrelid != old_value->va_content.va_external.va_toastrelid !=
new_value->va_content.va_external.va_toastrelid) new_value->va_content.va_external.va_toastrelid)
{ {
/* /*
* The old external store value isn't needed any more * The old external store value isn't needed any more
* after the update * after the update
@ -334,7 +328,6 @@ toast_insert_or_update(Relation rel, HeapTuple newtup, HeapTuple oldtup)
} }
else else
{ {
/* /*
* This attribute isn't changed by this update so we * This attribute isn't changed by this update so we
* reuse the original reference to the old value in * reuse the original reference to the old value in
@ -348,7 +341,6 @@ toast_insert_or_update(Relation rel, HeapTuple newtup, HeapTuple oldtup)
} }
else else
{ {
/* /*
* For INSERT simply get the new value * For INSERT simply get the new value
*/ */
@ -372,7 +364,6 @@ toast_insert_or_update(Relation rel, HeapTuple newtup, HeapTuple oldtup)
*/ */
if (att[i]->attlen == -1) if (att[i]->attlen == -1)
{ {
/* /*
* If the table's attribute says PLAIN always, force it so. * If the table's attribute says PLAIN always, force it so.
*/ */
@ -400,7 +391,6 @@ toast_insert_or_update(Relation rel, HeapTuple newtup, HeapTuple oldtup)
} }
else else
{ {
/* /*
* Not a variable size attribute, plain storage always * Not a variable size attribute, plain storage always
*/ */
@ -475,7 +465,6 @@ toast_insert_or_update(Relation rel, HeapTuple newtup, HeapTuple oldtup)
} }
else else
{ {
/* /*
* incompressible data, ignore on subsequent compression * incompressible data, ignore on subsequent compression
* passes * passes
@ -588,7 +577,6 @@ toast_insert_or_update(Relation rel, HeapTuple newtup, HeapTuple oldtup)
} }
else else
{ {
/* /*
* incompressible data, ignore on subsequent compression * incompressible data, ignore on subsequent compression
* passes * passes
@ -776,7 +764,8 @@ toast_save_datum(Relation rel, Datum value)
Datum t_values[3]; Datum t_values[3];
char t_nulls[3]; char t_nulls[3];
varattrib *result; varattrib *result;
struct { struct
{
struct varlena hdr; struct varlena hdr;
char data[TOAST_MAX_CHUNK_SIZE]; char data[TOAST_MAX_CHUNK_SIZE];
} chunk_data; } chunk_data;
@ -855,8 +844,8 @@ toast_save_datum(Relation rel, Datum value)
* FormIndexDatum: this relies on the knowledge that the index * FormIndexDatum: this relies on the knowledge that the index
* columns are the same as the initial columns of the table. * columns are the same as the initial columns of the table.
* *
* Note also that there had better not be any user-created index * Note also that there had better not be any user-created index on
* on the TOAST table, since we don't bother to update anything else. * the TOAST table, since we don't bother to update anything else.
*/ */
idxres = index_insert(toastidx, t_values, t_nulls, idxres = index_insert(toastidx, t_values, t_nulls,
&(toasttup->t_self), &(toasttup->t_self),
@ -916,8 +905,8 @@ toast_delete_datum(Relation rel, Datum value)
toastidx = index_open(toastrel->rd_rel->reltoastidxid); toastidx = index_open(toastrel->rd_rel->reltoastidxid);
/* /*
* Setup a scan key to fetch from the index by va_valueid * Setup a scan key to fetch from the index by va_valueid (we don't
* (we don't particularly care whether we see them in sequence or not) * particularly care whether we see them in sequence or not)
*/ */
ScanKeyEntryInitialize(&toastkey, ScanKeyEntryInitialize(&toastkey,
(bits16) 0, (bits16) 0,
@ -1096,5 +1085,4 @@ toast_fetch_datum(varattrib *attr)
return result; return result;
} }
#endif /* TUPLE_TOASTER_ACTIVE */ #endif /* TUPLE_TOASTER_ACTIVE */

View File

@ -8,7 +8,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/access/index/genam.c,v 1.28 2001/06/22 19:16:21 wieck Exp $ * $Header: /cvsroot/pgsql/src/backend/access/index/genam.c,v 1.29 2001/10/25 05:49:21 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
@ -240,5 +240,4 @@ IndexScanRestorePosition(IndexScanDesc scan)
scan->flags = 0x0; /* XXX should have a symbolic name */ scan->flags = 0x0; /* XXX should have a symbolic name */
} }
#endif #endif

View File

@ -8,7 +8,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/access/index/indexam.c,v 1.53 2001/10/06 23:21:43 tgl Exp $ * $Header: /cvsroot/pgsql/src/backend/access/index/indexam.c,v 1.54 2001/10/25 05:49:21 momjian Exp $
* *
* INTERFACE ROUTINES * INTERFACE ROUTINES
* index_open - open an index relation by relationId * index_open - open an index relation by relationId
@ -241,9 +241,9 @@ index_beginscan(Relation relation,
pgstat_initstats(&scan->xs_pgstat_info, relation); pgstat_initstats(&scan->xs_pgstat_info, relation);
/* /*
* We want to look up the amgettuple procedure just once per scan, * We want to look up the amgettuple procedure just once per scan, not
* not once per index_getnext call. So do it here and save * once per index_getnext call. So do it here and save the fmgr info
* the fmgr info result in the scan descriptor. * result in the scan descriptor.
*/ */
GET_SCAN_PROCEDURE(beginscan, amgettuple); GET_SCAN_PROCEDURE(beginscan, amgettuple);
fmgr_info(procedure, &scan->fn_getnext); fmgr_info(procedure, &scan->fn_getnext);
@ -342,8 +342,8 @@ index_getnext(IndexScanDesc scan,
pgstat_count_index_scan(&scan->xs_pgstat_info); pgstat_count_index_scan(&scan->xs_pgstat_info);
/* /*
* have the am's gettuple proc do all the work. * have the am's gettuple proc do all the work. index_beginscan
* index_beginscan already set up fn_getnext. * already set up fn_getnext.
*/ */
result = (RetrieveIndexResult) result = (RetrieveIndexResult)
DatumGetPointer(FunctionCall2(&scan->fn_getnext, DatumGetPointer(FunctionCall2(&scan->fn_getnext,

View File

@ -9,7 +9,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/access/index/Attic/istrat.c,v 1.53 2001/10/06 23:21:43 tgl Exp $ * $Header: /cvsroot/pgsql/src/backend/access/index/Attic/istrat.c,v 1.54 2001/10/25 05:49:21 momjian Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
@ -196,7 +196,6 @@ StrategyEvaluationIsValid(StrategyEvaluation evaluation)
} }
return true; return true;
} }
#endif #endif
#ifdef NOT_USED #ifdef NOT_USED
@ -255,7 +254,6 @@ StrategyTermEvaluate(StrategyTerm term,
return result; return result;
} }
#endif #endif
/* ---------------- /* ----------------
@ -453,7 +451,6 @@ RelationInvokeStrategy(Relation relation,
/* not reached, just to make compiler happy */ /* not reached, just to make compiler happy */
return FALSE; return FALSE;
} }
#endif #endif
/* ---------------- /* ----------------
@ -643,5 +640,4 @@ IndexStrategyDisplay(IndexStrategy indexStrategy,
} }
} }
} }
#endif /* defined(ISTRATDEBUG) */ #endif /* defined(ISTRATDEBUG) */

View File

@ -8,7 +8,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/access/nbtree/nbtcompare.c,v 1.42 2001/05/03 19:00:36 tgl Exp $ * $Header: /cvsroot/pgsql/src/backend/access/nbtree/nbtcompare.c,v 1.43 2001/10/25 05:49:21 momjian Exp $
* *
* NOTES * NOTES
* *

View File

@ -8,7 +8,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/access/nbtree/nbtinsert.c,v 1.86 2001/09/29 23:49:51 tgl Exp $ * $Header: /cvsroot/pgsql/src/backend/access/nbtree/nbtinsert.c,v 1.87 2001/10/25 05:49:21 momjian Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
@ -1115,7 +1115,8 @@ _bt_checksplitloc(FindSplitData *state, OffsetNumber firstright,
{ {
/* /*
* On a rightmost page, try to equalize right free space with * On a rightmost page, try to equalize right free space with
* twice the left free space. See comments for _bt_findsplitloc. * twice the left free space. See comments for
* _bt_findsplitloc.
*/ */
delta = (2 * leftfree) - rightfree; delta = (2 * leftfree) - rightfree;
} }
@ -1618,7 +1619,6 @@ _bt_fixlevel(Relation rel, Buffer buf, BlockNumber limit)
for (;;) for (;;)
{ {
/* /*
* Read up to 2 more child pages and look for pointers to them in * Read up to 2 more child pages and look for pointers to them in
* *saved* parent page * *saved* parent page

View File

@ -9,7 +9,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/access/nbtree/nbtpage.c,v 1.53 2001/07/15 22:48:16 tgl Exp $ * $Header: /cvsroot/pgsql/src/backend/access/nbtree/nbtpage.c,v 1.54 2001/10/25 05:49:21 momjian Exp $
* *
* NOTES * NOTES
* Postgres btree pages look like ordinary relation pages. The opaque * Postgres btree pages look like ordinary relation pages. The opaque
@ -153,7 +153,6 @@ _bt_getroot(Relation rel, int access)
*/ */
if (metad->btm_root == P_NONE) if (metad->btm_root == P_NONE)
{ {
/* /*
* Get, initialize, write, and leave a lock of the appropriate * Get, initialize, write, and leave a lock of the appropriate
* type on the new root page. Since this is the first page in * type on the new root page. Since this is the first page in
@ -209,7 +208,6 @@ _bt_getroot(Relation rel, int access)
} }
else else
{ {
/* /*
* Metadata initialized by someone else. In order to * Metadata initialized by someone else. In order to
* guarantee no deadlocks, we have to release the metadata * guarantee no deadlocks, we have to release the metadata
@ -237,7 +235,6 @@ _bt_getroot(Relation rel, int access)
if (!P_ISROOT(rootopaque)) if (!P_ISROOT(rootopaque))
{ {
/* /*
* It happened, but if root page splitter failed to create new * It happened, but if root page splitter failed to create new
* root page then we'll go in loop trying to call _bt_getroot * root page then we'll go in loop trying to call _bt_getroot
@ -402,7 +399,6 @@ _bt_wrtnorelbuf(Relation rel, Buffer buf)
void void
_bt_pageinit(Page page, Size size) _bt_pageinit(Page page, Size size)
{ {
/* /*
* Cargo_cult programming -- don't really need this to be zero, but * Cargo_cult programming -- don't really need this to be zero, but
* creating new pages is an infrequent occurrence and it makes me feel * creating new pages is an infrequent occurrence and it makes me feel

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.82 2001/07/15 22:48:16 tgl Exp $ * $Header: /cvsroot/pgsql/src/backend/access/nbtree/nbtree.c,v 1.83 2001/10/25 05:49:21 momjian Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
@ -37,6 +37,7 @@ typedef struct
bool haveDead; bool haveDead;
Relation heapRel; Relation heapRel;
BTSpool *spool; BTSpool *spool;
/* /*
* spool2 is needed only when the index is an unique index. Dead * spool2 is needed only when the index is an unique index. Dead
* tuples are put into spool2 instead of spool in order to avoid * tuples are put into spool2 instead of spool in order to avoid
@ -134,6 +135,7 @@ btbuild(PG_FUNCTION_ARGS)
if (buildstate.usefast) if (buildstate.usefast)
{ {
buildstate.spool = _bt_spoolinit(index, indexInfo->ii_Unique); buildstate.spool = _bt_spoolinit(index, indexInfo->ii_Unique);
/* /*
* Different from spool, the uniqueness isn't checked for spool2. * Different from spool, the uniqueness isn't checked for spool2.
*/ */
@ -226,9 +228,9 @@ btbuildCallback(Relation index,
btitem = _bt_formitem(itup); btitem = _bt_formitem(itup);
/* /*
* if we are doing bottom-up btree build, we insert the index into * if we are doing bottom-up btree build, we insert the index into a
* a spool file for subsequent processing. otherwise, we insert * spool file for subsequent processing. otherwise, we insert into
* into the btree. * the btree.
*/ */
if (buildstate->usefast) if (buildstate->usefast)
{ {
@ -305,7 +307,6 @@ btgettuple(PG_FUNCTION_ARGS)
if (ItemPointerIsValid(&(scan->currentItemData))) if (ItemPointerIsValid(&(scan->currentItemData)))
{ {
/* /*
* Restore scan position using heap TID returned by previous call * Restore scan position using heap TID returned by previous call
* to btgettuple(). _bt_restscan() re-grabs the read lock on the * to btgettuple(). _bt_restscan() re-grabs the read lock on the
@ -362,7 +363,6 @@ btrescan(PG_FUNCTION_ARGS)
#ifdef NOT_USED /* XXX surely it's wrong to ignore this? */ #ifdef NOT_USED /* XXX surely it's wrong to ignore this? */
bool fromEnd = PG_GETARG_BOOL(1); bool fromEnd = PG_GETARG_BOOL(1);
#endif #endif
ScanKey scankey = (ScanKey) PG_GETARG_POINTER(2); ScanKey scankey = (ScanKey) PG_GETARG_POINTER(2);
ItemPointer iptr; ItemPointer iptr;
@ -559,15 +559,16 @@ btbulkdelete(PG_FUNCTION_ARGS)
num_index_tuples = 0; num_index_tuples = 0;
/* /*
* We use a standard IndexScanDesc scan object, but to speed up the loop, * We use a standard IndexScanDesc scan object, but to speed up the
* we skip most of the wrapper layers of index_getnext and instead call * loop, we skip most of the wrapper layers of index_getnext and
* _bt_step directly. This implies holding buffer lock on a target page * instead call _bt_step directly. This implies holding buffer lock
* throughout the loop over the page's tuples. Initially, we have a read * on a target page throughout the loop over the page's tuples.
* lock acquired by _bt_step when we stepped onto the page. If we find * Initially, we have a read lock acquired by _bt_step when we stepped
* a tuple we need to delete, we trade in the read lock for an exclusive * onto the page. If we find a tuple we need to delete, we trade in
* write lock; after that, we hold the write lock until we step off the * the read lock for an exclusive write lock; after that, we hold the
* page (fortunately, _bt_relbuf doesn't care which kind of lock it's * write lock until we step off the page (fortunately, _bt_relbuf
* releasing). This should minimize the amount of work needed per page. * doesn't care which kind of lock it's releasing). This should
* minimize the amount of work needed per page.
*/ */
scan = index_beginscan(rel, false, 0, (ScanKey) NULL); scan = index_beginscan(rel, false, 0, (ScanKey) NULL);
so = (BTScanOpaque) scan->opaque; so = (BTScanOpaque) scan->opaque;
@ -607,9 +608,10 @@ btbulkdelete(PG_FUNCTION_ARGS)
{ {
/* /*
* If this is first deletion on this page, trade in read * If this is first deletion on this page, trade in read
* lock for a really-exclusive write lock. Then, step back * lock for a really-exclusive write lock. Then, step
* one and re-examine the item, because someone else might * back one and re-examine the item, because someone else
* have inserted an item while we weren't holding the lock! * might have inserted an item while we weren't holding
* the lock!
*/ */
if (blkno != lockedBlock) if (blkno != lockedBlock)
{ {
@ -632,8 +634,8 @@ btbulkdelete(PG_FUNCTION_ARGS)
* We need to back up the scan one item so that the next * We need to back up the scan one item so that the next
* cycle will re-examine the same offnum on this page. * cycle will re-examine the same offnum on this page.
* *
* For now, just hack the current-item index. Will need * For now, just hack the current-item index. Will need to
* to be smarter when deletion includes removal of empty * be smarter when deletion includes removal of empty
* index pages. * index pages.
*/ */
current->ip_posid--; current->ip_posid--;

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/access/nbtree/nbtsearch.c,v 1.68 2001/10/06 23:21:43 tgl Exp $ * $Header: /cvsroot/pgsql/src/backend/access/nbtree/nbtsearch.c,v 1.69 2001/10/25 05:49:21 momjian Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
@ -590,8 +590,8 @@ _bt_first(IndexScanDesc scan, ScanDirection dir)
/* /*
* At this point we are positioned at the first item >= scan key, or * At this point we are positioned at the first item >= scan key, or
* possibly at the end of a page on which all the existing items are * possibly at the end of a page on which all the existing items are
* greater than the scan key and we know that everything on later pages * greater than the scan key and we know that everything on later
* is less than or equal to scan key. * pages is less than or equal to scan key.
* *
* We could step forward in the latter case, but that'd be a waste of * We could step forward in the latter case, but that'd be a waste of
* time if we want to scan backwards. So, it's now time to examine * time if we want to scan backwards. So, it's now time to examine

View File

@ -35,7 +35,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.60 2001/03/22 03:59:15 momjian Exp $ * $Header: /cvsroot/pgsql/src/backend/access/nbtree/nbtsort.c,v 1.61 2001/10/25 05:49:21 momjian Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
@ -354,7 +354,6 @@ _bt_buildadd(Relation index, BTPageState *state, BTItem bti)
if (pgspc < btisz || pgspc < state->btps_full) if (pgspc < btisz || pgspc < state->btps_full)
{ {
/* /*
* Item won't fit on this page, or we feel the page is full enough * Item won't fit on this page, or we feel the page is full enough
* already. Finish off the page and write it out. * already. Finish off the page and write it out.
@ -544,7 +543,6 @@ _bt_load(Relation index, BTSpool *btspool, BTSpool *btspool2)
if (merge) if (merge)
{ {
/* /*
* Another BTSpool for dead tuples exists. Now we have to merge * Another BTSpool for dead tuples exists. Now we have to merge
* btspool and btspool2. * btspool and btspool2.

View File

@ -8,7 +8,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/access/nbtree/Attic/nbtstrat.c,v 1.14 2001/05/30 19:53:40 tgl Exp $ * $Header: /cvsroot/pgsql/src/backend/access/nbtree/Attic/nbtstrat.c,v 1.15 2001/10/25 05:49:21 momjian Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
@ -134,5 +134,4 @@ _bt_invokestrat(Relation rel,
return (RelationInvokeStrategy(rel, &BTEvaluationData, attno, strat, return (RelationInvokeStrategy(rel, &BTEvaluationData, attno, strat,
left, right)); left, right));
} }
#endif #endif

View File

@ -8,7 +8,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/access/nbtree/nbtutils.c,v 1.46 2001/10/06 23:21:43 tgl Exp $ * $Header: /cvsroot/pgsql/src/backend/access/nbtree/nbtutils.c,v 1.47 2001/10/25 05:49:21 momjian Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
@ -221,7 +221,6 @@ _bt_orderkeys(Relation relation, BTScanOpaque so)
/* We can short-circuit most of the work if there's just one key */ /* We can short-circuit most of the work if there's just one key */
if (numberOfKeys == 1) if (numberOfKeys == 1)
{ {
/* /*
* We don't use indices for 'A is null' and 'A is not null' * We don't use indices for 'A is null' and 'A is not null'
* currently and 'A < = > <> NULL' will always fail - so qual is * currently and 'A < = > <> NULL' will always fail - so qual is
@ -317,7 +316,6 @@ _bt_orderkeys(Relation relation, BTScanOpaque so)
} }
else else
{ {
/* /*
* No "=" for this key, so we're done with required keys * No "=" for this key, so we're done with required keys
*/ */

View File

@ -8,7 +8,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/access/rtree/Attic/rtree.c,v 1.65 2001/10/06 23:21:43 tgl Exp $ * $Header: /cvsroot/pgsql/src/backend/access/rtree/Attic/rtree.c,v 1.66 2001/10/25 05:49:21 momjian Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
@ -194,11 +194,11 @@ rtbuildCallback(Relation index,
} }
/* /*
* Since we already have the index relation locked, we call * Since we already have the index relation locked, we call rtdoinsert
* rtdoinsert directly. Normal access method calls dispatch * directly. Normal access method calls dispatch through rtinsert,
* through rtinsert, which locks the relation for write. This is * which locks the relation for write. This is the right thing to do
* the right thing to do if you're inserting single tups, but not * if you're inserting single tups, but not when you're initializing
* when you're initializing the whole index at once. * the whole index at once.
*/ */
res = rtdoinsert(index, itup, &buildstate->rtState); res = rtdoinsert(index, itup, &buildstate->rtState);
@ -223,6 +223,7 @@ rtinsert(PG_FUNCTION_ARGS)
Datum *datum = (Datum *) PG_GETARG_POINTER(1); Datum *datum = (Datum *) PG_GETARG_POINTER(1);
char *nulls = (char *) PG_GETARG_POINTER(2); char *nulls = (char *) PG_GETARG_POINTER(2);
ItemPointer ht_ctid = (ItemPointer) PG_GETARG_POINTER(3); ItemPointer ht_ctid = (ItemPointer) PG_GETARG_POINTER(3);
#ifdef NOT_USED #ifdef NOT_USED
Relation heapRel = (Relation) PG_GETARG_POINTER(4); Relation heapRel = (Relation) PG_GETARG_POINTER(4);
#endif #endif
@ -376,9 +377,8 @@ rttighten(Relation r,
PointerGetDatum(&newd_size)); PointerGetDatum(&newd_size));
/* /*
* If newd_size == 0 we have degenerate rectangles, so we * If newd_size == 0 we have degenerate rectangles, so we don't know
* don't know if there was any change, so we have to * if there was any change, so we have to assume there was.
* assume there was.
*/ */
if ((newd_size == 0) || (newd_size != old_size)) if ((newd_size == 0) || (newd_size != old_size))
{ {
@ -386,7 +386,6 @@ rttighten(Relation r,
if (td->attrs[0]->attlen < 0) if (td->attrs[0]->attlen < 0)
{ {
/* /*
* This is an internal page, so 'oldud' had better be a union * This is an internal page, so 'oldud' had better be a union
* (constant-length) key, too. (See comment below.) * (constant-length) key, too. (See comment below.)
@ -500,10 +499,10 @@ rtdosplit(Relation r,
res = (InsertIndexResult) palloc(sizeof(InsertIndexResultData)); res = (InsertIndexResult) palloc(sizeof(InsertIndexResultData));
/* /*
* spl_left contains a list of the offset numbers of the * spl_left contains a list of the offset numbers of the tuples that
* tuples that will go to the left page. For each offset * will go to the left page. For each offset number, get the tuple
* number, get the tuple item, then add the item to the * item, then add the item to the left page. Similarly for the right
* left page. Similarly for the right side. * side.
*/ */
/* fill left node */ /* fill left node */
@ -765,7 +764,8 @@ rtpicksplit(Relation r,
int total_num_tuples, int total_num_tuples,
num_tuples_without_seeds, num_tuples_without_seeds,
max_after_split; /* in Guttman's lingo, (M - m) */ max_after_split; /* in Guttman's lingo, (M - m) */
float diff; /* diff between cost of putting tuple left or right */ float diff; /* diff between cost of putting tuple left
* or right */
SPLITCOST *cost_vector; SPLITCOST *cost_vector;
int n; int n;
@ -852,7 +852,6 @@ rtpicksplit(Relation r,
if (firsttime) if (firsttime)
{ {
/* /*
* There is no possible split except to put the new item on its * There is no possible split except to put the new item on its
* own page. Since we still have to compute the union rectangles, * own page. Since we still have to compute the union rectangles,
@ -885,25 +884,25 @@ rtpicksplit(Relation r,
/* /*
* Now split up the regions between the two seeds. * Now split up the regions between the two seeds.
* *
* The cost_vector array will contain hints for determining where * The cost_vector array will contain hints for determining where each
* each tuple should go. Each record in the array will contain * tuple should go. Each record in the array will contain a boolean,
* a boolean, choose_left, that indicates which node the tuple * choose_left, that indicates which node the tuple prefers to be on,
* prefers to be on, and the absolute difference in cost between * and the absolute difference in cost between putting the tuple in
* putting the tuple in its favored node and in the other node. * its favored node and in the other node.
* *
* Later, we will sort the cost_vector in descending order by cost * Later, we will sort the cost_vector in descending order by cost
* difference, and consider the tuples in that order for * difference, and consider the tuples in that order for placement.
* placement. That way, the tuples that *really* want to be in * That way, the tuples that *really* want to be in one node or the
* one node or the other get to choose first, and the tuples that * other get to choose first, and the tuples that don't really care
* don't really care choose last. * choose last.
* *
* First, build the cost_vector array. The new index tuple will * First, build the cost_vector array. The new index tuple will also be
* also be handled in this loop, and represented in the array, * handled in this loop, and represented in the array, with
* with i==newitemoff. * i==newitemoff.
* *
* In the case of variable size tuples it is possible that we only * In the case of variable size tuples it is possible that we only have
* have the two seeds and no other tuples, in which case we don't * the two seeds and no other tuples, in which case we don't do any of
* do any of this cost_vector stuff. * this cost_vector stuff.
*/ */
/* to keep compiler quiet */ /* to keep compiler quiet */
@ -943,21 +942,21 @@ rtpicksplit(Relation r,
} }
/* /*
* Sort the array. The function qsort_comp_splitcost is * Sort the array. The function qsort_comp_splitcost is set up
* set up "backwards", to provided descending order. * "backwards", to provided descending order.
*/ */
qsort(cost_vector, num_tuples_without_seeds, sizeof(SPLITCOST), qsort(cost_vector, num_tuples_without_seeds, sizeof(SPLITCOST),
&qsort_comp_splitcost); &qsort_comp_splitcost);
} }
/* /*
* Now make the final decisions about where each tuple will go, * Now make the final decisions about where each tuple will go, and
* and build the vectors to return in the SPLITVEC record. * build the vectors to return in the SPLITVEC record.
* *
* The cost_vector array contains (descriptions of) all the * The cost_vector array contains (descriptions of) all the tuples, in
* tuples, in the order that we want to consider them, so we * the order that we want to consider them, so we we just iterate
* we just iterate through it and place each tuple in left * through it and place each tuple in left or right nodes, according
* or right nodes, according to the criteria described below. * to the criteria described below.
*/ */
left = v->spl_left; left = v->spl_left;
@ -965,9 +964,9 @@ rtpicksplit(Relation r,
right = v->spl_right; right = v->spl_right;
v->spl_nright = 0; v->spl_nright = 0;
/* Place the seeds first. /*
* left avail space, left union, right avail space, and right * Place the seeds first. left avail space, left union, right avail
* union have already been adjusted for the seeds. * space, and right union have already been adjusted for the seeds.
*/ */
*left++ = seed_1; *left++ = seed_1;
@ -983,8 +982,8 @@ rtpicksplit(Relation r,
choose_left; choose_left;
/* /*
* We need to figure out which page needs the least * We need to figure out which page needs the least enlargement in
* enlargement in order to store the item. * order to store the item.
*/ */
i = cost_vector[n].offset_number; i = cost_vector[n].offset_number;
@ -1021,20 +1020,20 @@ rtpicksplit(Relation r,
* Guttman's algorithm actually has two factors to consider (in * Guttman's algorithm actually has two factors to consider (in
* order): 1. if one node has so many tuples already assigned to * order): 1. if one node has so many tuples already assigned to
* it that the other needs all the rest in order to satisfy the * it that the other needs all the rest in order to satisfy the
* condition that neither node has fewer than m tuples, then * condition that neither node has fewer than m tuples, then that
* that is decisive; 2. otherwise, choose the page that shows * is decisive; 2. otherwise, choose the page that shows the
* the smaller enlargement of its union area. * smaller enlargement of its union area.
* *
* I have chosen m = M/2, where M is the maximum number of * I have chosen m = M/2, where M is the maximum number of tuples on
* tuples on a page. (Actually, this is only strictly * a page. (Actually, this is only strictly true for fixed size
* true for fixed size tuples. For variable size tuples, * tuples. For variable size tuples, there still might have to be
* there still might have to be only one tuple on a page, * only one tuple on a page, if it is really big. But even with
* if it is really big. But even with variable size * variable size tuples we still try to get m as close as possible
* tuples we still try to get m as close as possible to M/2.) * to M/2.)
* *
* The question of which page shows the smaller enlargement of * The question of which page shows the smaller enlargement of its
* its union area has already been answered, and the answer * union area has already been answered, and the answer stored in
* stored in the choose_left field of the SPLITCOST record. * the choose_left field of the SPLITCOST record.
*/ */
left_feasible = (left_avail_space >= item_1_sz && left_feasible = (left_avail_space >= item_1_sz &&
((left_avail_space - item_1_sz) >= newitemsz || ((left_avail_space - item_1_sz) >= newitemsz ||
@ -1045,10 +1044,10 @@ rtpicksplit(Relation r,
if (left_feasible && right_feasible) if (left_feasible && right_feasible)
{ {
/* /*
* Both feasible, use Guttman's algorithm. * Both feasible, use Guttman's algorithm. First check the m
* First check the m condition described above, and if * condition described above, and if that doesn't apply,
* that doesn't apply, choose the page with the smaller * choose the page with the smaller enlargement of its union
* enlargement of its union area. * area.
*/ */
if (v->spl_nleft > max_after_split) if (v->spl_nleft > max_after_split)
choose_left = false; choose_left = false;
@ -1090,9 +1089,7 @@ rtpicksplit(Relation r,
} }
if (num_tuples_without_seeds > 0) if (num_tuples_without_seeds > 0)
{
pfree(cost_vector); pfree(cost_vector);
}
*left = *right = InvalidOffsetNumber; /* add ending sentinels */ *left = *right = InvalidOffsetNumber; /* add ending sentinels */
@ -1282,6 +1279,7 @@ qsort_comp_splitcost(const void *a, const void *b)
float diff = float diff =
((SPLITCOST *) a)->cost_differential - ((SPLITCOST *) a)->cost_differential -
((SPLITCOST *) b)->cost_differential; ((SPLITCOST *) b)->cost_differential;
if (diff < 0) if (diff < 0)
return 1; return 1;
else if (diff > 0) else if (diff > 0)
@ -1342,7 +1340,6 @@ _rtdump(Relation r)
ReleaseBuffer(buf); ReleaseBuffer(buf);
} }
} }
#endif /* defined RTDEBUG */ #endif /* defined RTDEBUG */
void void

View File

@ -8,7 +8,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/access/rtree/Attic/rtscan.c,v 1.38 2001/07/15 22:48:16 tgl Exp $ * $Header: /cvsroot/pgsql/src/backend/access/rtree/Attic/rtscan.c,v 1.39 2001/10/25 05:49:21 momjian Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
@ -380,7 +380,6 @@ adjustiptr(IndexScanDesc s,
} }
else else
{ {
/* /*
* remember that we're before the current * remember that we're before the current
* tuple * tuple

View File

@ -8,7 +8,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/access/rtree/Attic/rtstrat.c,v 1.17 2001/05/30 19:53:40 tgl Exp $ * $Header: /cvsroot/pgsql/src/backend/access/rtree/Attic/rtstrat.c,v 1.18 2001/10/25 05:49:22 momjian Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
@ -221,7 +221,6 @@ RelationInvokeRTStrategy(Relation r,
return (RelationInvokeStrategy(r, &RTEvaluationData, attnum, s, return (RelationInvokeStrategy(r, &RTEvaluationData, attnum, s,
left, right)); left, right));
} }
#endif #endif
RegProcedure RegProcedure

View File

@ -13,7 +13,7 @@
* Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group * Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group
* 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/clog.c,v 1.4 2001/09/29 04:02:21 tgl Exp $ * $Header: /cvsroot/pgsql/src/backend/access/transam/clog.c,v 1.5 2001/10/25 05:49:22 momjian Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
@ -121,10 +121,12 @@
typedef enum typedef enum
{ {
CLOG_PAGE_EMPTY,/* CLOG buffer is not in use */ CLOG_PAGE_EMPTY,/* CLOG buffer is not in use */
CLOG_PAGE_READ_IN_PROGRESS, /* CLOG page is being read in */ CLOG_PAGE_READ_IN_PROGRESS, /* CLOG page is being read
* in */
CLOG_PAGE_CLEAN,/* CLOG page is valid and not dirty */ CLOG_PAGE_CLEAN,/* CLOG page is valid and not dirty */
CLOG_PAGE_DIRTY,/* CLOG page is valid but needs write */ CLOG_PAGE_DIRTY,/* CLOG page is valid but needs write */
CLOG_PAGE_WRITE_IN_PROGRESS /* CLOG page is being written out in */ CLOG_PAGE_WRITE_IN_PROGRESS /* CLOG page is being
* written out in */
} ClogPageStatus; } ClogPageStatus;
/* /*
@ -134,14 +136,15 @@ typedef struct ClogCtlData
{ {
/* /*
* Info for each buffer slot. Page number is undefined when status is * Info for each buffer slot. Page number is undefined when status is
* EMPTY. lru_count is essentially the number of operations since last * EMPTY. lru_count is essentially the number of operations since
* use of this page; the page with highest lru_count is the best candidate * last use of this page; the page with highest lru_count is the best
* to replace. * candidate to replace.
*/ */
char *page_buffer[NUM_CLOG_BUFFERS]; char *page_buffer[NUM_CLOG_BUFFERS];
ClogPageStatus page_status[NUM_CLOG_BUFFERS]; ClogPageStatus page_status[NUM_CLOG_BUFFERS];
int page_number[NUM_CLOG_BUFFERS]; int page_number[NUM_CLOG_BUFFERS];
unsigned int page_lru_count[NUM_CLOG_BUFFERS]; unsigned int page_lru_count[NUM_CLOG_BUFFERS];
/* /*
* latest_page_number is the page number of the current end of the * latest_page_number is the page number of the current end of the
* CLOG; this is not critical data, since we use it only to avoid * CLOG; this is not critical data, since we use it only to avoid
@ -489,11 +492,12 @@ WriteCLOGPage(int slotno)
* update on this page will mark it dirty again. NB: we are assuming * update on this page will mark it dirty again. NB: we are assuming
* that read/write of the page status field is atomic, since we change * that read/write of the page status field is atomic, since we change
* the state while not holding control lock. However, we cannot set * the state while not holding control lock. However, we cannot set
* this state any sooner, or we'd possibly fool a previous writer * this state any sooner, or we'd possibly fool a previous writer into
* into thinking he's successfully dumped the page when he hasn't. * thinking he's successfully dumped the page when he hasn't.
* (Scenario: other writer starts, page is redirtied, we come along and * (Scenario: other writer starts, page is redirtied, we come along
* set WRITE_IN_PROGRESS again, other writer completes and sets CLEAN * and set WRITE_IN_PROGRESS again, other writer completes and sets
* because redirty info has been lost, then we think it's clean too.) * CLEAN because redirty info has been lost, then we think it's clean
* too.)
*/ */
ClogCtl->page_status[slotno] = CLOG_PAGE_WRITE_IN_PROGRESS; ClogCtl->page_status[slotno] = CLOG_PAGE_WRITE_IN_PROGRESS;
@ -533,8 +537,8 @@ CLOGPhysicalReadPage(int pageno, int slotno)
/* /*
* In a crash-and-restart situation, it's possible for us to receive * In a crash-and-restart situation, it's possible for us to receive
* commands to set the commit status of transactions whose bits are * commands to set the commit status of transactions whose bits are in
* in already-truncated segments of the commit log (see notes in * already-truncated segments of the commit log (see notes in
* CLOGPhysicalWritePage). Hence, if we are InRecovery, allow the * CLOGPhysicalWritePage). Hence, if we are InRecovery, allow the
* case where the file doesn't exist, and return zeroes instead. * case where the file doesn't exist, and return zeroes instead.
*/ */
@ -578,16 +582,17 @@ CLOGPhysicalWritePage(int pageno, int slotno)
ClogFileName(path, segno); ClogFileName(path, segno);
/* /*
* If the file doesn't already exist, we should create it. It is possible * If the file doesn't already exist, we should create it. It is
* for this to need to happen when writing a page that's not first in * possible for this to need to happen when writing a page that's not
* its segment; we assume the OS can cope with that. (Note: it might seem * first in its segment; we assume the OS can cope with that. (Note:
* that it'd be okay to create files only when ZeroCLOGPage is called for * it might seem that it'd be okay to create files only when
* the first page of a segment. However, if after a crash and restart * ZeroCLOGPage is called for the first page of a segment. However,
* the REDO logic elects to replay the log from a checkpoint before the * if after a crash and restart the REDO logic elects to replay the
* latest one, then it's possible that we will get commands to set * log from a checkpoint before the latest one, then it's possible
* transaction status of transactions that have already been truncated * that we will get commands to set transaction status of transactions
* from the commit log. Easiest way to deal with that is to accept * that have already been truncated from the commit log. Easiest way
* references to nonexistent files here and in CLOGPhysicalReadPage.) * to deal with that is to accept references to nonexistent files here
* and in CLOGPhysicalReadPage.)
*/ */
fd = BasicOpenFile(path, O_RDWR | PG_BINARY, S_IRUSR | S_IWUSR); fd = BasicOpenFile(path, O_RDWR | PG_BINARY, S_IRUSR | S_IWUSR);
if (fd < 0) if (fd < 0)
@ -649,9 +654,8 @@ SelectLRUCLOGPage(int pageno)
} }
/* /*
* If we find any EMPTY slot, just select that one. * If we find any EMPTY slot, just select that one. Else locate
* Else locate the least-recently-used slot that isn't the * the least-recently-used slot that isn't the latest CLOG page.
* latest CLOG page.
*/ */
for (slotno = 0; slotno < NUM_CLOG_BUFFERS; slotno++) for (slotno = 0; slotno < NUM_CLOG_BUFFERS; slotno++)
{ {
@ -672,10 +676,10 @@ SelectLRUCLOGPage(int pageno)
return bestslot; return bestslot;
/* /*
* We need to do I/O. Normal case is that we have to write it out, * We need to do I/O. Normal case is that we have to write it
* but it's possible in the worst case to have selected a read-busy * out, but it's possible in the worst case to have selected a
* page. In that case we use ReadCLOGPage to wait for the read to * read-busy page. In that case we use ReadCLOGPage to wait for
* complete. * the read to complete.
*/ */
if (ClogCtl->page_status[bestslot] == CLOG_PAGE_READ_IN_PROGRESS) if (ClogCtl->page_status[bestslot] == CLOG_PAGE_READ_IN_PROGRESS)
(void) ReadCLOGPage(ClogCtl->page_number[bestslot]); (void) ReadCLOGPage(ClogCtl->page_number[bestslot]);
@ -683,9 +687,9 @@ SelectLRUCLOGPage(int pageno)
WriteCLOGPage(bestslot); WriteCLOGPage(bestslot);
/* /*
* Now loop back and try again. This is the easiest way of dealing * Now loop back and try again. This is the easiest way of
* with corner cases such as the victim page being re-dirtied while * dealing with corner cases such as the victim page being
* we wrote it. * re-dirtied while we wrote it.
*/ */
} }
} }
@ -736,6 +740,7 @@ CheckPointCLOG(void)
for (slotno = 0; slotno < NUM_CLOG_BUFFERS; slotno++) for (slotno = 0; slotno < NUM_CLOG_BUFFERS; slotno++)
{ {
WriteCLOGPage(slotno); WriteCLOGPage(slotno);
/* /*
* We cannot assert that the slot is clean now, since another * We cannot assert that the slot is clean now, since another
* process might have re-dirtied it already. That's okay. * process might have re-dirtied it already. That's okay.
@ -813,15 +818,16 @@ TruncateCLOG(TransactionId oldestXact)
/* /*
* Scan CLOG shared memory and remove any pages preceding the cutoff * Scan CLOG shared memory and remove any pages preceding the cutoff
* page, to ensure we won't rewrite them later. (Any dirty pages * page, to ensure we won't rewrite them later. (Any dirty pages
* should have been flushed already during the checkpoint, we're * should have been flushed already during the checkpoint, we're just
* just being extra careful here.) * being extra careful here.)
*/ */
LWLockAcquire(CLogControlLock, LW_EXCLUSIVE); LWLockAcquire(CLogControlLock, LW_EXCLUSIVE);
restart:; restart:;
/* /*
* While we are holding the lock, make an important safety check: * While we are holding the lock, make an important safety check: the
* the planned cutoff point must be <= the current CLOG endpoint page. * planned cutoff point must be <= the current CLOG endpoint page.
* Otherwise we have already wrapped around, and proceeding with the * Otherwise we have already wrapped around, and proceeding with the
* truncation would risk removing the current CLOG segment. * truncation would risk removing the current CLOG segment.
*/ */
@ -838,6 +844,7 @@ restart:;
continue; continue;
if (!CLOGPagePrecedes(ClogCtl->page_number[slotno], cutoffPage)) if (!CLOGPagePrecedes(ClogCtl->page_number[slotno], cutoffPage))
continue; continue;
/* /*
* If page is CLEAN, just change state to EMPTY (expected case). * If page is CLEAN, just change state to EMPTY (expected case).
*/ */
@ -846,6 +853,7 @@ restart:;
ClogCtl->page_status[slotno] = CLOG_PAGE_EMPTY; ClogCtl->page_status[slotno] = CLOG_PAGE_EMPTY;
continue; continue;
} }
/* /*
* Hmm, we have (or may have) I/O operations acting on the page, * Hmm, we have (or may have) I/O operations acting on the page,
* so we've got to wait for them to finish and then start again. * so we've got to wait for them to finish and then start again.
@ -929,8 +937,10 @@ CLOGPagePrecedes(int page1, int page2)
TransactionId xid2; TransactionId xid2;
xid1 = (TransactionId) page1 *CLOG_XACTS_PER_PAGE; xid1 = (TransactionId) page1 *CLOG_XACTS_PER_PAGE;
xid1 += FirstNormalTransactionId; xid1 += FirstNormalTransactionId;
xid2 = (TransactionId) page2 *CLOG_XACTS_PER_PAGE; xid2 = (TransactionId) page2 *CLOG_XACTS_PER_PAGE;
xid2 += FirstNormalTransactionId; xid2 += FirstNormalTransactionId;
return TransactionIdPrecedes(xid1, xid2); return TransactionIdPrecedes(xid1, xid2);

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