mirror of
https://github.com/postgres/postgres.git
synced 2025-07-30 11:03:19 +03:00
pgindent run for 8.2.
This commit is contained in:
@ -4,11 +4,11 @@
|
||||
*
|
||||
*
|
||||
* Copyright (c) 2002 - 2006, PostgreSQL Global Development Group
|
||||
*
|
||||
*
|
||||
* Author: Andreas Pflug <pgadmin@pse-consulting.de>
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $PostgreSQL: pgsql/contrib/adminpack/adminpack.c,v 1.3 2006/07/11 16:35:30 momjian Exp $
|
||||
* $PostgreSQL: pgsql/contrib/adminpack/adminpack.c,v 1.4 2006/10/04 00:29:44 momjian Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
@ -35,7 +35,6 @@
|
||||
#ifdef unlink
|
||||
#undef unlink
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
extern DLLIMPORT char *DataDir;
|
||||
@ -44,20 +43,20 @@ extern DLLIMPORT char *Log_filename;
|
||||
|
||||
PG_MODULE_MAGIC;
|
||||
|
||||
Datum pg_file_write(PG_FUNCTION_ARGS);
|
||||
Datum pg_file_rename(PG_FUNCTION_ARGS);
|
||||
Datum pg_file_unlink(PG_FUNCTION_ARGS);
|
||||
Datum pg_logdir_ls(PG_FUNCTION_ARGS);
|
||||
Datum pg_file_write(PG_FUNCTION_ARGS);
|
||||
Datum pg_file_rename(PG_FUNCTION_ARGS);
|
||||
Datum pg_file_unlink(PG_FUNCTION_ARGS);
|
||||
Datum pg_logdir_ls(PG_FUNCTION_ARGS);
|
||||
|
||||
PG_FUNCTION_INFO_V1(pg_file_write);
|
||||
PG_FUNCTION_INFO_V1(pg_file_rename);
|
||||
PG_FUNCTION_INFO_V1(pg_file_unlink);
|
||||
PG_FUNCTION_INFO_V1(pg_logdir_ls);
|
||||
|
||||
typedef struct
|
||||
typedef struct
|
||||
{
|
||||
char *location;
|
||||
DIR *dirdesc;
|
||||
char *location;
|
||||
DIR *dirdesc;
|
||||
} directory_fctx;
|
||||
|
||||
/*-----------------------
|
||||
@ -65,30 +64,31 @@ typedef struct
|
||||
*/
|
||||
|
||||
/*
|
||||
* Return an absolute path. Argument may be absolute or
|
||||
* Return an absolute path. Argument may be absolute or
|
||||
* relative to the DataDir.
|
||||
*/
|
||||
static char *absClusterPath(text *arg, bool logAllowed)
|
||||
static char *
|
||||
absClusterPath(text *arg, bool logAllowed)
|
||||
{
|
||||
char *filename;
|
||||
int len=VARSIZE(arg) - VARHDRSZ;
|
||||
int dlen = strlen(DataDir);
|
||||
char *filename;
|
||||
int len = VARSIZE(arg) - VARHDRSZ;
|
||||
int dlen = strlen(DataDir);
|
||||
|
||||
filename = palloc(len+1);
|
||||
filename = palloc(len + 1);
|
||||
memcpy(filename, VARDATA(arg), len);
|
||||
filename[len] = 0;
|
||||
|
||||
if (strstr(filename, "..") != NULL)
|
||||
ereport(ERROR,
|
||||
(errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
|
||||
(errmsg("No .. allowed in filenames"))));
|
||||
|
||||
ereport(ERROR,
|
||||
(errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
|
||||
(errmsg("No .. allowed in filenames"))));
|
||||
|
||||
if (is_absolute_path(filename))
|
||||
{
|
||||
if (logAllowed && !strncmp(filename, Log_directory, strlen(Log_directory)))
|
||||
return filename;
|
||||
if (logAllowed && !strncmp(filename, Log_directory, strlen(Log_directory)))
|
||||
return filename;
|
||||
if (strncmp(filename, DataDir, dlen))
|
||||
ereport(ERROR,
|
||||
ereport(ERROR,
|
||||
(errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
|
||||
(errmsg("Absolute path not allowed"))));
|
||||
|
||||
@ -96,7 +96,8 @@ static char *absClusterPath(text *arg, bool logAllowed)
|
||||
}
|
||||
else
|
||||
{
|
||||
char *absname = palloc(dlen+len+2);
|
||||
char *absname = palloc(dlen + len + 2);
|
||||
|
||||
sprintf(absname, "%s/%s", DataDir, filename);
|
||||
pfree(filename);
|
||||
return absname;
|
||||
@ -111,9 +112,9 @@ static void
|
||||
requireSuperuser(void)
|
||||
{
|
||||
if (!superuser())
|
||||
ereport(ERROR,
|
||||
ereport(ERROR,
|
||||
(errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
|
||||
(errmsg("only superuser may access generic file functions"))));
|
||||
(errmsg("only superuser may access generic file functions"))));
|
||||
}
|
||||
|
||||
|
||||
@ -122,12 +123,13 @@ requireSuperuser(void)
|
||||
* generic file handling functions
|
||||
*/
|
||||
|
||||
Datum pg_file_write(PG_FUNCTION_ARGS)
|
||||
Datum
|
||||
pg_file_write(PG_FUNCTION_ARGS)
|
||||
{
|
||||
FILE *f;
|
||||
char *filename;
|
||||
text *data;
|
||||
int64 count = 0;
|
||||
FILE *f;
|
||||
char *filename;
|
||||
text *data;
|
||||
int64 count = 0;
|
||||
|
||||
requireSuperuser();
|
||||
|
||||
@ -136,16 +138,17 @@ Datum pg_file_write(PG_FUNCTION_ARGS)
|
||||
|
||||
if (PG_ARGISNULL(2) || !PG_GETARG_BOOL(2))
|
||||
{
|
||||
struct stat fst;
|
||||
struct stat fst;
|
||||
|
||||
if (stat(filename, &fst) >= 0)
|
||||
ereport(ERROR,
|
||||
ereport(ERROR,
|
||||
(ERRCODE_DUPLICATE_FILE,
|
||||
errmsg("file %s exists", filename)));
|
||||
|
||||
f = fopen(filename, "wb");
|
||||
f = fopen(filename, "wb");
|
||||
}
|
||||
else
|
||||
f = fopen(filename, "ab");
|
||||
f = fopen(filename, "ab");
|
||||
|
||||
if (!f)
|
||||
{
|
||||
@ -159,7 +162,7 @@ Datum pg_file_write(PG_FUNCTION_ARGS)
|
||||
count = fwrite(VARDATA(data), 1, VARSIZE(data) - VARHDRSZ, f);
|
||||
|
||||
if (count != VARSIZE(data) - VARHDRSZ)
|
||||
ereport(ERROR,
|
||||
ereport(ERROR,
|
||||
(errcode_for_file_access(),
|
||||
errmsg("error writing file %s: %m", filename)));
|
||||
}
|
||||
@ -169,22 +172,25 @@ Datum pg_file_write(PG_FUNCTION_ARGS)
|
||||
}
|
||||
|
||||
|
||||
Datum pg_file_rename(PG_FUNCTION_ARGS)
|
||||
Datum
|
||||
pg_file_rename(PG_FUNCTION_ARGS)
|
||||
{
|
||||
char *fn1, *fn2, *fn3;
|
||||
int rc;
|
||||
char *fn1,
|
||||
*fn2,
|
||||
*fn3;
|
||||
int rc;
|
||||
|
||||
requireSuperuser();
|
||||
|
||||
if (PG_ARGISNULL(0) || PG_ARGISNULL(1))
|
||||
PG_RETURN_NULL();
|
||||
|
||||
fn1=absClusterPath(PG_GETARG_TEXT_P(0), false);
|
||||
fn2=absClusterPath(PG_GETARG_TEXT_P(1), false);
|
||||
fn1 = absClusterPath(PG_GETARG_TEXT_P(0), false);
|
||||
fn2 = absClusterPath(PG_GETARG_TEXT_P(1), false);
|
||||
if (PG_ARGISNULL(2))
|
||||
fn3=0;
|
||||
fn3 = 0;
|
||||
else
|
||||
fn3=absClusterPath(PG_GETARG_TEXT_P(2), false);
|
||||
fn3 = absClusterPath(PG_GETARG_TEXT_P(2), false);
|
||||
|
||||
if (access(fn1, W_OK) < 0)
|
||||
{
|
||||
@ -192,7 +198,7 @@ Datum pg_file_rename(PG_FUNCTION_ARGS)
|
||||
(errcode_for_file_access(),
|
||||
errmsg("file %s not accessible: %m", fn1)));
|
||||
|
||||
PG_RETURN_BOOL(false);
|
||||
PG_RETURN_BOOL(false);
|
||||
}
|
||||
|
||||
if (fn3 && access(fn2, W_OK) < 0)
|
||||
@ -201,7 +207,7 @@ Datum pg_file_rename(PG_FUNCTION_ARGS)
|
||||
(errcode_for_file_access(),
|
||||
errmsg("file %s not accessible: %m", fn2)));
|
||||
|
||||
PG_RETURN_BOOL(false);
|
||||
PG_RETURN_BOOL(false);
|
||||
}
|
||||
|
||||
|
||||
@ -212,10 +218,10 @@ Datum pg_file_rename(PG_FUNCTION_ARGS)
|
||||
(ERRCODE_DUPLICATE_FILE,
|
||||
errmsg("cannot rename to target file %s", fn3 ? fn3 : fn2)));
|
||||
}
|
||||
|
||||
|
||||
if (fn3)
|
||||
{
|
||||
if (rename(fn2, fn3) != 0)
|
||||
if (rename(fn2, fn3) != 0)
|
||||
{
|
||||
ereport(ERROR,
|
||||
(errcode_for_file_access(),
|
||||
@ -231,7 +237,7 @@ Datum pg_file_rename(PG_FUNCTION_ARGS)
|
||||
{
|
||||
ereport(ERROR,
|
||||
(errcode_for_file_access(),
|
||||
errmsg("could not rename %s back to %s: %m", fn3, fn2)));
|
||||
errmsg("could not rename %s back to %s: %m", fn3, fn2)));
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -244,9 +250,9 @@ Datum pg_file_rename(PG_FUNCTION_ARGS)
|
||||
}
|
||||
else if (rename(fn1, fn2) != 0)
|
||||
{
|
||||
ereport(WARNING,
|
||||
(errcode_for_file_access(),
|
||||
errmsg("renaming %s to %s %m", fn1, fn2)));
|
||||
ereport(WARNING,
|
||||
(errcode_for_file_access(),
|
||||
errmsg("renaming %s to %s %m", fn1, fn2)));
|
||||
ereport(ERROR,
|
||||
(errcode_for_file_access(),
|
||||
errmsg("could not rename %s to %s: %m", fn1, fn2)));
|
||||
@ -256,20 +262,21 @@ Datum pg_file_rename(PG_FUNCTION_ARGS)
|
||||
}
|
||||
|
||||
|
||||
Datum pg_file_unlink(PG_FUNCTION_ARGS)
|
||||
Datum
|
||||
pg_file_unlink(PG_FUNCTION_ARGS)
|
||||
{
|
||||
char *filename;
|
||||
char *filename;
|
||||
|
||||
requireSuperuser();
|
||||
|
||||
filename = absClusterPath(PG_GETARG_TEXT_P(0), false);
|
||||
filename = absClusterPath(PG_GETARG_TEXT_P(0), false);
|
||||
|
||||
if (access(filename, W_OK) < 0)
|
||||
{
|
||||
if (errno == ENOENT)
|
||||
PG_RETURN_BOOL(false);
|
||||
if (errno == ENOENT)
|
||||
PG_RETURN_BOOL(false);
|
||||
else
|
||||
ereport(ERROR,
|
||||
ereport(ERROR,
|
||||
(errcode_for_file_access(),
|
||||
errmsg("file %s not accessible: %m", filename)));
|
||||
|
||||
@ -287,17 +294,18 @@ Datum pg_file_unlink(PG_FUNCTION_ARGS)
|
||||
}
|
||||
|
||||
|
||||
Datum pg_logdir_ls(PG_FUNCTION_ARGS)
|
||||
Datum
|
||||
pg_logdir_ls(PG_FUNCTION_ARGS)
|
||||
{
|
||||
FuncCallContext *funcctx;
|
||||
struct dirent *de;
|
||||
directory_fctx *fctx;
|
||||
|
||||
if (!superuser())
|
||||
if (!superuser())
|
||||
ereport(ERROR,
|
||||
(errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
|
||||
(errmsg("only superuser can list the log directory"))));
|
||||
|
||||
|
||||
if (memcmp(Log_filename, "postgresql-%Y-%m-%d_%H%M%S.log", 30) != 0)
|
||||
ereport(ERROR,
|
||||
(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
|
||||
@ -306,17 +314,17 @@ Datum pg_logdir_ls(PG_FUNCTION_ARGS)
|
||||
if (SRF_IS_FIRSTCALL())
|
||||
{
|
||||
MemoryContext oldcontext;
|
||||
TupleDesc tupdesc;
|
||||
TupleDesc tupdesc;
|
||||
|
||||
funcctx=SRF_FIRSTCALL_INIT();
|
||||
funcctx = SRF_FIRSTCALL_INIT();
|
||||
oldcontext = MemoryContextSwitchTo(funcctx->multi_call_memory_ctx);
|
||||
|
||||
fctx = palloc(sizeof(directory_fctx));
|
||||
if (is_absolute_path(Log_directory))
|
||||
fctx->location = Log_directory;
|
||||
fctx->location = Log_directory;
|
||||
else
|
||||
{
|
||||
fctx->location = palloc(strlen(DataDir) + strlen(Log_directory) +2);
|
||||
fctx->location = palloc(strlen(DataDir) + strlen(Log_directory) + 2);
|
||||
sprintf(fctx->location, "%s/%s", DataDir, Log_directory);
|
||||
}
|
||||
tupdesc = CreateTemplateTupleDesc(2, false);
|
||||
@ -326,11 +334,11 @@ Datum pg_logdir_ls(PG_FUNCTION_ARGS)
|
||||
TEXTOID, -1, 0);
|
||||
|
||||
funcctx->attinmeta = TupleDescGetAttInMetadata(tupdesc);
|
||||
|
||||
|
||||
fctx->dirdesc = AllocateDir(fctx->location);
|
||||
|
||||
if (!fctx->dirdesc)
|
||||
ereport(ERROR,
|
||||
ereport(ERROR,
|
||||
(errcode_for_file_access(),
|
||||
errmsg("%s is not browsable: %m", fctx->location)));
|
||||
|
||||
@ -338,47 +346,47 @@ Datum pg_logdir_ls(PG_FUNCTION_ARGS)
|
||||
MemoryContextSwitchTo(oldcontext);
|
||||
}
|
||||
|
||||
funcctx=SRF_PERCALL_SETUP();
|
||||
fctx = (directory_fctx*) funcctx->user_fctx;
|
||||
funcctx = SRF_PERCALL_SETUP();
|
||||
fctx = (directory_fctx *) funcctx->user_fctx;
|
||||
|
||||
if (!fctx->dirdesc) /* not a readable directory */
|
||||
if (!fctx->dirdesc) /* not a readable directory */
|
||||
SRF_RETURN_DONE(funcctx);
|
||||
|
||||
while ((de = readdir(fctx->dirdesc)) != NULL)
|
||||
{
|
||||
char *values[2];
|
||||
HeapTuple tuple;
|
||||
|
||||
char *field[MAXDATEFIELDS];
|
||||
char *values[2];
|
||||
HeapTuple tuple;
|
||||
|
||||
char *field[MAXDATEFIELDS];
|
||||
char lowstr[MAXDATELEN + 1];
|
||||
int dtype;
|
||||
int nf, ftype[MAXDATEFIELDS];
|
||||
int dtype;
|
||||
int nf,
|
||||
ftype[MAXDATEFIELDS];
|
||||
fsec_t fsec;
|
||||
int tz = 0;
|
||||
struct pg_tm date;
|
||||
int tz = 0;
|
||||
struct pg_tm date;
|
||||
|
||||
/*
|
||||
* Default format:
|
||||
* postgresql-YYYY-MM-DD_HHMMSS.log
|
||||
* Default format: postgresql-YYYY-MM-DD_HHMMSS.log
|
||||
*/
|
||||
if (strlen(de->d_name) != 32
|
||||
|| memcmp(de->d_name, "postgresql-", 11)
|
||||
|| memcmp(de->d_name, "postgresql-", 11)
|
||||
|| de->d_name[21] != '_'
|
||||
|| strcmp(de->d_name + 28, ".log"))
|
||||
continue;
|
||||
continue;
|
||||
|
||||
values[1] = palloc(strlen(fctx->location) + strlen(de->d_name) + 2);
|
||||
sprintf(values[1], "%s/%s", fctx->location, de->d_name);
|
||||
|
||||
values[0] = de->d_name + 11; /* timestamp */
|
||||
values[0] = de->d_name + 11; /* timestamp */
|
||||
values[0][17] = 0;
|
||||
|
||||
/* parse and decode expected timestamp */
|
||||
/* parse and decode expected timestamp */
|
||||
if (ParseDateTime(values[0], lowstr, MAXDATELEN, field, ftype, MAXDATEFIELDS, &nf))
|
||||
continue;
|
||||
continue;
|
||||
|
||||
if (DecodeDateTime(field, ftype, nf, &dtype, &date, &fsec, &tz))
|
||||
continue;
|
||||
continue;
|
||||
|
||||
/* Seems the format fits the expected format; feed it into the tuple */
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
/******************************************************************************
|
||||
$PostgreSQL: pgsql/contrib/cube/cube.c,v 1.29 2006/09/10 17:36:50 tgl Exp $
|
||||
$PostgreSQL: pgsql/contrib/cube/cube.c,v 1.30 2006/10/04 00:29:44 momjian Exp $
|
||||
|
||||
This file contains routines that can be bound to a Postgres backend and
|
||||
called by the backend in the process of processing queries. The calling
|
||||
@ -159,7 +159,7 @@ Datum
|
||||
cube_in(PG_FUNCTION_ARGS)
|
||||
{
|
||||
void *result;
|
||||
char *str;
|
||||
char *str;
|
||||
|
||||
str = PG_GETARG_CSTRING(0);
|
||||
|
||||
@ -170,7 +170,7 @@ cube_in(PG_FUNCTION_ARGS)
|
||||
|
||||
cube_scanner_finish();
|
||||
|
||||
PG_RETURN_POINTER (result);
|
||||
PG_RETURN_POINTER(result);
|
||||
}
|
||||
|
||||
/* Allow conversion from text to cube to allow input of computed strings */
|
||||
@ -178,11 +178,11 @@ cube_in(PG_FUNCTION_ARGS)
|
||||
Datum
|
||||
cube(PG_FUNCTION_ARGS)
|
||||
{
|
||||
char *cstring;
|
||||
char *cstring;
|
||||
|
||||
cstring = DatumGetCString(DirectFunctionCall1(textout, PointerGetDatum(PG_GETARG_TEXT_P(0))));
|
||||
|
||||
PG_RETURN_DATUM (DirectFunctionCall1 (cube_in, PointerGetDatum(cstring)));
|
||||
PG_RETURN_DATUM(DirectFunctionCall1(cube_in, PointerGetDatum(cstring)));
|
||||
}
|
||||
|
||||
|
||||
@ -192,12 +192,14 @@ cube(PG_FUNCTION_ARGS)
|
||||
Datum
|
||||
cube_a_f8_f8(PG_FUNCTION_ARGS)
|
||||
{
|
||||
int i;
|
||||
int dim;
|
||||
int size;
|
||||
NDBOX *result;
|
||||
ArrayType *ur, *ll;
|
||||
double *dur, *dll;
|
||||
int i;
|
||||
int dim;
|
||||
int size;
|
||||
NDBOX *result;
|
||||
ArrayType *ur,
|
||||
*ll;
|
||||
double *dur,
|
||||
*dll;
|
||||
|
||||
ur = (ArrayType *) PG_GETARG_VARLENA_P(0);
|
||||
ll = (ArrayType *) PG_GETARG_VARLENA_P(1);
|
||||
@ -205,31 +207,31 @@ cube_a_f8_f8(PG_FUNCTION_ARGS)
|
||||
if (ARR_HASNULL(ur) || ARR_HASNULL(ll))
|
||||
{
|
||||
ereport(ERROR,
|
||||
(errcode(ERRCODE_ARRAY_ELEMENT_ERROR),
|
||||
errmsg("Cannot work with NULL arrays")));
|
||||
(errcode(ERRCODE_ARRAY_ELEMENT_ERROR),
|
||||
errmsg("Cannot work with NULL arrays")));
|
||||
}
|
||||
|
||||
dim = ARRNELEMS(ur);
|
||||
if (ARRNELEMS(ll) != dim)
|
||||
{
|
||||
ereport(ERROR,
|
||||
(errcode(ERRCODE_ARRAY_ELEMENT_ERROR),
|
||||
errmsg("UR and LL arrays must be of same length")));
|
||||
(errcode(ERRCODE_ARRAY_ELEMENT_ERROR),
|
||||
errmsg("UR and LL arrays must be of same length")));
|
||||
}
|
||||
|
||||
dur = ARRPTR(ur);
|
||||
dll = ARRPTR(ll);
|
||||
|
||||
size = offsetof(NDBOX, x[0]) + sizeof(double) * 2 * dim;
|
||||
result = (NDBOX *) palloc (size);
|
||||
memset (result, 0, size);
|
||||
result = (NDBOX *) palloc(size);
|
||||
memset(result, 0, size);
|
||||
result->size = size;
|
||||
result->dim = dim;
|
||||
|
||||
for (i=0; i<dim; i++)
|
||||
for (i = 0; i < dim; i++)
|
||||
{
|
||||
result->x[i] = dur[i];
|
||||
result->x[i+dim] = dll[i];
|
||||
result->x[i + dim] = dll[i];
|
||||
}
|
||||
|
||||
PG_RETURN_POINTER(result);
|
||||
@ -241,20 +243,20 @@ cube_a_f8_f8(PG_FUNCTION_ARGS)
|
||||
Datum
|
||||
cube_a_f8(PG_FUNCTION_ARGS)
|
||||
{
|
||||
int i;
|
||||
int dim;
|
||||
int size;
|
||||
NDBOX *result;
|
||||
ArrayType *ur;
|
||||
double *dur;
|
||||
int i;
|
||||
int dim;
|
||||
int size;
|
||||
NDBOX *result;
|
||||
ArrayType *ur;
|
||||
double *dur;
|
||||
|
||||
ur = (ArrayType *) PG_GETARG_VARLENA_P(0);
|
||||
|
||||
if (ARR_HASNULL(ur))
|
||||
{
|
||||
ereport(ERROR,
|
||||
(errcode(ERRCODE_ARRAY_ELEMENT_ERROR),
|
||||
errmsg("Cannot work with NULL arrays")));
|
||||
(errcode(ERRCODE_ARRAY_ELEMENT_ERROR),
|
||||
errmsg("Cannot work with NULL arrays")));
|
||||
}
|
||||
|
||||
dim = ARRNELEMS(ur);
|
||||
@ -262,15 +264,15 @@ cube_a_f8(PG_FUNCTION_ARGS)
|
||||
dur = ARRPTR(ur);
|
||||
|
||||
size = offsetof(NDBOX, x[0]) + sizeof(double) * 2 * dim;
|
||||
result = (NDBOX *) palloc (size);
|
||||
memset (result, 0, size);
|
||||
result = (NDBOX *) palloc(size);
|
||||
memset(result, 0, size);
|
||||
result->size = size;
|
||||
result->dim = dim;
|
||||
|
||||
for (i=0; i<dim; i++)
|
||||
for (i = 0; i < dim; i++)
|
||||
{
|
||||
result->x[i] = dur[i];
|
||||
result->x[i+dim] = dur[i];
|
||||
result->x[i + dim] = dur[i];
|
||||
}
|
||||
|
||||
PG_RETURN_POINTER(result);
|
||||
@ -279,10 +281,13 @@ cube_a_f8(PG_FUNCTION_ARGS)
|
||||
Datum
|
||||
cube_subset(PG_FUNCTION_ARGS)
|
||||
{
|
||||
NDBOX *c, *result;
|
||||
ArrayType *idx;
|
||||
int size, dim, i;
|
||||
int *dx;
|
||||
NDBOX *c,
|
||||
*result;
|
||||
ArrayType *idx;
|
||||
int size,
|
||||
dim,
|
||||
i;
|
||||
int *dx;
|
||||
|
||||
c = (NDBOX *) PG_GETARG_POINTER(0);
|
||||
idx = (ArrayType *) PG_GETARG_VARLENA_P(1);
|
||||
@ -290,30 +295,30 @@ cube_subset(PG_FUNCTION_ARGS)
|
||||
if (ARR_HASNULL(idx))
|
||||
{
|
||||
ereport(ERROR,
|
||||
(errcode(ERRCODE_ARRAY_ELEMENT_ERROR),
|
||||
errmsg("Cannot work with NULL arrays")));
|
||||
(errcode(ERRCODE_ARRAY_ELEMENT_ERROR),
|
||||
errmsg("Cannot work with NULL arrays")));
|
||||
}
|
||||
|
||||
dx = (int4 *) ARR_DATA_PTR (idx);
|
||||
dx = (int4 *) ARR_DATA_PTR(idx);
|
||||
|
||||
dim = ARRNELEMS(idx);
|
||||
size = offsetof(NDBOX, x[0]) + sizeof(double) * 2 * dim;
|
||||
result = (NDBOX *) palloc (size);
|
||||
memset (result, 0, size);
|
||||
result = (NDBOX *) palloc(size);
|
||||
memset(result, 0, size);
|
||||
result->size = size;
|
||||
result->dim = dim;
|
||||
|
||||
for (i=0; i<dim; i++)
|
||||
for (i = 0; i < dim; i++)
|
||||
{
|
||||
if ((dx[i] <= 0) || (dx[i] > c->dim))
|
||||
{
|
||||
pfree (result);
|
||||
pfree(result);
|
||||
ereport(ERROR,
|
||||
(errcode(ERRCODE_ARRAY_ELEMENT_ERROR),
|
||||
errmsg("Index out of bounds")));
|
||||
(errcode(ERRCODE_ARRAY_ELEMENT_ERROR),
|
||||
errmsg("Index out of bounds")));
|
||||
}
|
||||
result->x[i] = c->x[dx[i]-1];
|
||||
result->x[i+dim] = c->x[dx[i]+c->dim-1];
|
||||
result->x[i] = c->x[dx[i] - 1];
|
||||
result->x[i + dim] = c->x[dx[i] + c->dim - 1];
|
||||
}
|
||||
|
||||
PG_RETURN_POINTER(result);
|
||||
@ -327,11 +332,11 @@ cube_out(PG_FUNCTION_ARGS)
|
||||
int dim;
|
||||
int i;
|
||||
int ndig;
|
||||
NDBOX *cube;
|
||||
NDBOX *cube;
|
||||
|
||||
initStringInfo(&buf);
|
||||
|
||||
cube = (NDBOX *) PG_GETARG_POINTER (0);
|
||||
cube = (NDBOX *) PG_GETARG_POINTER(0);
|
||||
|
||||
dim = cube->dim;
|
||||
|
||||
@ -369,7 +374,7 @@ cube_out(PG_FUNCTION_ARGS)
|
||||
appendStringInfoChar(&buf, ')');
|
||||
}
|
||||
|
||||
PG_RETURN_CSTRING (buf.data);
|
||||
PG_RETURN_CSTRING(buf.data);
|
||||
}
|
||||
|
||||
|
||||
@ -383,11 +388,11 @@ cube_out(PG_FUNCTION_ARGS)
|
||||
** the predicate x op query == FALSE, where op is the oper
|
||||
** corresponding to strategy in the pg_amop table.
|
||||
*/
|
||||
Datum
|
||||
Datum
|
||||
g_cube_consistent(PG_FUNCTION_ARGS)
|
||||
{
|
||||
GISTENTRY *entry = (GISTENTRY *) PG_GETARG_POINTER(0);
|
||||
NDBOX *query = (NDBOX *) DatumGetPointer(PG_DETOAST_DATUM(PG_GETARG_DATUM(1)));
|
||||
GISTENTRY *entry = (GISTENTRY *) PG_GETARG_POINTER(0);
|
||||
NDBOX *query = (NDBOX *) DatumGetPointer(PG_DETOAST_DATUM(PG_GETARG_DATUM(1)));
|
||||
StrategyNumber strategy = (StrategyNumber) PG_GETARG_UINT16(2);
|
||||
|
||||
/*
|
||||
@ -414,7 +419,7 @@ g_cube_union(PG_FUNCTION_ARGS)
|
||||
NDBOX *out = (NDBOX *) NULL;
|
||||
NDBOX *tmp;
|
||||
int *sizep;
|
||||
GistEntryVector *entryvec;
|
||||
GistEntryVector *entryvec;
|
||||
|
||||
entryvec = (GistEntryVector *) PG_GETARG_POINTER(0);
|
||||
sizep = (int *) PG_GETARG_POINTER(1);
|
||||
@ -446,15 +451,15 @@ g_cube_union(PG_FUNCTION_ARGS)
|
||||
*/
|
||||
|
||||
Datum
|
||||
g_cube_compress (PG_FUNCTION_ARGS)
|
||||
g_cube_compress(PG_FUNCTION_ARGS)
|
||||
{
|
||||
PG_RETURN_DATUM(PG_GETARG_DATUM(0));
|
||||
PG_RETURN_DATUM(PG_GETARG_DATUM(0));
|
||||
}
|
||||
|
||||
Datum
|
||||
g_cube_decompress (PG_FUNCTION_ARGS)
|
||||
g_cube_decompress(PG_FUNCTION_ARGS)
|
||||
{
|
||||
PG_RETURN_DATUM(PG_GETARG_DATUM(0));
|
||||
PG_RETURN_DATUM(PG_GETARG_DATUM(0));
|
||||
}
|
||||
|
||||
|
||||
@ -463,17 +468,17 @@ g_cube_decompress (PG_FUNCTION_ARGS)
|
||||
** As in the R-tree paper, we use change in area as our penalty metric
|
||||
*/
|
||||
Datum
|
||||
g_cube_penalty (PG_FUNCTION_ARGS)
|
||||
g_cube_penalty(PG_FUNCTION_ARGS)
|
||||
{
|
||||
GISTENTRY *origentry = (GISTENTRY *) PG_GETARG_POINTER(0);
|
||||
GISTENTRY *newentry = (GISTENTRY *) PG_GETARG_POINTER(1);
|
||||
float *result = (float *) PG_GETARG_POINTER(2);
|
||||
GISTENTRY *origentry = (GISTENTRY *) PG_GETARG_POINTER(0);
|
||||
GISTENTRY *newentry = (GISTENTRY *) PG_GETARG_POINTER(1);
|
||||
float *result = (float *) PG_GETARG_POINTER(2);
|
||||
NDBOX *ud;
|
||||
double tmp1,
|
||||
tmp2;
|
||||
|
||||
ud = cube_union_v0((NDBOX *) DatumGetPointer(origentry->key),
|
||||
(NDBOX *) DatumGetPointer(newentry->key));
|
||||
(NDBOX *) DatumGetPointer(newentry->key));
|
||||
rt_cube_size(ud, &tmp1);
|
||||
rt_cube_size((NDBOX *) DatumGetPointer(origentry->key), &tmp2);
|
||||
*result = (float) (tmp1 - tmp2);
|
||||
@ -481,7 +486,7 @@ g_cube_penalty (PG_FUNCTION_ARGS)
|
||||
/*
|
||||
* fprintf(stderr, "penalty\n"); fprintf(stderr, "\t%g\n", *result);
|
||||
*/
|
||||
PG_RETURN_FLOAT8 (*result);
|
||||
PG_RETURN_FLOAT8(*result);
|
||||
}
|
||||
|
||||
|
||||
@ -493,8 +498,8 @@ g_cube_penalty (PG_FUNCTION_ARGS)
|
||||
Datum
|
||||
g_cube_picksplit(PG_FUNCTION_ARGS)
|
||||
{
|
||||
GistEntryVector *entryvec;
|
||||
GIST_SPLITVEC *v;
|
||||
GistEntryVector *entryvec;
|
||||
GIST_SPLITVEC *v;
|
||||
OffsetNumber i,
|
||||
j;
|
||||
NDBOX *datum_alpha,
|
||||
@ -546,9 +551,9 @@ g_cube_picksplit(PG_FUNCTION_ARGS)
|
||||
/* size_waste = size_union - size_inter; */
|
||||
union_d = cube_union_v0(datum_alpha, datum_beta);
|
||||
rt_cube_size(union_d, &size_union);
|
||||
inter_d = (NDBOX *) DatumGetPointer (DirectFunctionCall2
|
||||
(cube_inter,
|
||||
entryvec->vector[i].key, entryvec->vector[j].key));
|
||||
inter_d = (NDBOX *) DatumGetPointer(DirectFunctionCall2
|
||||
(cube_inter,
|
||||
entryvec->vector[i].key, entryvec->vector[j].key));
|
||||
rt_cube_size(inter_d, &size_inter);
|
||||
size_waste = size_union - size_inter;
|
||||
|
||||
@ -649,12 +654,13 @@ g_cube_picksplit(PG_FUNCTION_ARGS)
|
||||
Datum
|
||||
g_cube_same(PG_FUNCTION_ARGS)
|
||||
{
|
||||
NDBOX *b1, *b2;
|
||||
bool *result;
|
||||
|
||||
b1 = (NDBOX *) PG_GETARG_POINTER (0);
|
||||
b2 = (NDBOX *) PG_GETARG_POINTER (1);
|
||||
result = (bool *) PG_GETARG_POINTER (2);
|
||||
NDBOX *b1,
|
||||
*b2;
|
||||
bool *result;
|
||||
|
||||
b1 = (NDBOX *) PG_GETARG_POINTER(0);
|
||||
b2 = (NDBOX *) PG_GETARG_POINTER(1);
|
||||
result = (bool *) PG_GETARG_POINTER(2);
|
||||
|
||||
if (cube_cmp_v0(b1, b2) == 0)
|
||||
*result = TRUE;
|
||||
@ -664,7 +670,7 @@ g_cube_same(PG_FUNCTION_ARGS)
|
||||
/*
|
||||
* fprintf(stderr, "same: %s\n", (*result ? "TRUE" : "FALSE" ));
|
||||
*/
|
||||
PG_RETURN_POINTER (result);
|
||||
PG_RETURN_POINTER(result);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -803,14 +809,15 @@ cube_union_v0(NDBOX * a, NDBOX * b)
|
||||
}
|
||||
|
||||
Datum
|
||||
cube_union (PG_FUNCTION_ARGS)
|
||||
cube_union(PG_FUNCTION_ARGS)
|
||||
{
|
||||
NDBOX *a, *b;
|
||||
NDBOX *a,
|
||||
*b;
|
||||
|
||||
a = (NDBOX *) PG_GETARG_POINTER(0);
|
||||
b = (NDBOX *) PG_GETARG_POINTER(1);
|
||||
|
||||
PG_RETURN_POINTER(cube_union_v0(a,b));
|
||||
PG_RETURN_POINTER(cube_union_v0(a, b));
|
||||
}
|
||||
|
||||
/* cube_inter */
|
||||
@ -818,7 +825,9 @@ Datum
|
||||
cube_inter(PG_FUNCTION_ARGS)
|
||||
{
|
||||
int i;
|
||||
NDBOX *result, *a, *b;
|
||||
NDBOX *result,
|
||||
*a,
|
||||
*b;
|
||||
|
||||
a = (NDBOX *) PG_GETARG_POINTER(0);
|
||||
b = (NDBOX *) PG_GETARG_POINTER(1);
|
||||
@ -874,17 +883,17 @@ cube_inter(PG_FUNCTION_ARGS)
|
||||
/*
|
||||
* Is it OK to return a non-null intersection for non-overlapping boxes?
|
||||
*/
|
||||
PG_RETURN_POINTER (result);
|
||||
PG_RETURN_POINTER(result);
|
||||
}
|
||||
|
||||
/* cube_size */
|
||||
Datum
|
||||
cube_size(PG_FUNCTION_ARGS)
|
||||
{
|
||||
NDBOX *a;
|
||||
NDBOX *a;
|
||||
int i,
|
||||
j;
|
||||
double result;
|
||||
double result;
|
||||
|
||||
a = (NDBOX *) PG_GETARG_POINTER(0);
|
||||
|
||||
@ -892,7 +901,7 @@ cube_size(PG_FUNCTION_ARGS)
|
||||
for (i = 0, j = a->dim; i < a->dim; i++, j++)
|
||||
result = result * Abs((a->x[j] - a->x[i]));
|
||||
|
||||
PG_RETURN_FLOAT8 (result);
|
||||
PG_RETURN_FLOAT8(result);
|
||||
}
|
||||
|
||||
void
|
||||
@ -994,10 +1003,11 @@ cube_cmp_v0(NDBOX * a, NDBOX * b)
|
||||
return 0;
|
||||
}
|
||||
|
||||
Datum
|
||||
Datum
|
||||
cube_cmp(PG_FUNCTION_ARGS)
|
||||
{
|
||||
NDBOX *a, *b;
|
||||
NDBOX *a,
|
||||
*b;
|
||||
|
||||
a = (NDBOX *) PG_GETARG_POINTER(0);
|
||||
b = (NDBOX *) PG_GETARG_POINTER(1);
|
||||
@ -1009,7 +1019,8 @@ cube_cmp(PG_FUNCTION_ARGS)
|
||||
Datum
|
||||
cube_eq(PG_FUNCTION_ARGS)
|
||||
{
|
||||
NDBOX *a, *b;
|
||||
NDBOX *a,
|
||||
*b;
|
||||
|
||||
a = (NDBOX *) PG_GETARG_POINTER(0);
|
||||
b = (NDBOX *) PG_GETARG_POINTER(1);
|
||||
@ -1021,7 +1032,8 @@ cube_eq(PG_FUNCTION_ARGS)
|
||||
Datum
|
||||
cube_ne(PG_FUNCTION_ARGS)
|
||||
{
|
||||
NDBOX *a, *b;
|
||||
NDBOX *a,
|
||||
*b;
|
||||
|
||||
a = (NDBOX *) PG_GETARG_POINTER(0);
|
||||
b = (NDBOX *) PG_GETARG_POINTER(1);
|
||||
@ -1033,7 +1045,8 @@ cube_ne(PG_FUNCTION_ARGS)
|
||||
Datum
|
||||
cube_lt(PG_FUNCTION_ARGS)
|
||||
{
|
||||
NDBOX *a, *b;
|
||||
NDBOX *a,
|
||||
*b;
|
||||
|
||||
a = (NDBOX *) PG_GETARG_POINTER(0);
|
||||
b = (NDBOX *) PG_GETARG_POINTER(1);
|
||||
@ -1045,7 +1058,8 @@ cube_lt(PG_FUNCTION_ARGS)
|
||||
Datum
|
||||
cube_gt(PG_FUNCTION_ARGS)
|
||||
{
|
||||
NDBOX *a, *b;
|
||||
NDBOX *a,
|
||||
*b;
|
||||
|
||||
a = (NDBOX *) PG_GETARG_POINTER(0);
|
||||
b = (NDBOX *) PG_GETARG_POINTER(1);
|
||||
@ -1057,7 +1071,8 @@ cube_gt(PG_FUNCTION_ARGS)
|
||||
Datum
|
||||
cube_le(PG_FUNCTION_ARGS)
|
||||
{
|
||||
NDBOX *a, *b;
|
||||
NDBOX *a,
|
||||
*b;
|
||||
|
||||
a = (NDBOX *) PG_GETARG_POINTER(0);
|
||||
b = (NDBOX *) PG_GETARG_POINTER(1);
|
||||
@ -1069,7 +1084,8 @@ cube_le(PG_FUNCTION_ARGS)
|
||||
Datum
|
||||
cube_ge(PG_FUNCTION_ARGS)
|
||||
{
|
||||
NDBOX *a, *b;
|
||||
NDBOX *a,
|
||||
*b;
|
||||
|
||||
a = (NDBOX *) PG_GETARG_POINTER(0);
|
||||
b = (NDBOX *) PG_GETARG_POINTER(1);
|
||||
@ -1122,7 +1138,8 @@ cube_contains_v0(NDBOX * a, NDBOX * b)
|
||||
Datum
|
||||
cube_contains(PG_FUNCTION_ARGS)
|
||||
{
|
||||
NDBOX *a, *b;
|
||||
NDBOX *a,
|
||||
*b;
|
||||
|
||||
a = (NDBOX *) PG_GETARG_POINTER(0);
|
||||
b = (NDBOX *) PG_GETARG_POINTER(1);
|
||||
@ -1135,12 +1152,13 @@ cube_contains(PG_FUNCTION_ARGS)
|
||||
Datum
|
||||
cube_contained(PG_FUNCTION_ARGS)
|
||||
{
|
||||
NDBOX *a, *b;
|
||||
NDBOX *a,
|
||||
*b;
|
||||
|
||||
a = (NDBOX *) PG_GETARG_POINTER(0);
|
||||
b = (NDBOX *) PG_GETARG_POINTER(1);
|
||||
|
||||
PG_RETURN_BOOL (cube_contains_v0(b, a));
|
||||
PG_RETURN_BOOL(cube_contains_v0(b, a));
|
||||
}
|
||||
|
||||
/* Overlap */
|
||||
@ -1193,12 +1211,13 @@ cube_overlap_v0(NDBOX * a, NDBOX * b)
|
||||
Datum
|
||||
cube_overlap(PG_FUNCTION_ARGS)
|
||||
{
|
||||
NDBOX *a, *b;
|
||||
NDBOX *a,
|
||||
*b;
|
||||
|
||||
a = (NDBOX *) PG_GETARG_POINTER(0);
|
||||
b = (NDBOX *) PG_GETARG_POINTER(1);
|
||||
|
||||
PG_RETURN_BOOL (cube_overlap_v0(a, b));
|
||||
PG_RETURN_BOOL(cube_overlap_v0(a, b));
|
||||
}
|
||||
|
||||
|
||||
@ -1213,7 +1232,8 @@ cube_distance(PG_FUNCTION_ARGS)
|
||||
int i;
|
||||
double d,
|
||||
distance;
|
||||
NDBOX *a, *b;
|
||||
NDBOX *a,
|
||||
*b;
|
||||
|
||||
a = (NDBOX *) PG_GETARG_POINTER(0);
|
||||
b = (NDBOX *) PG_GETARG_POINTER(1);
|
||||
@ -1266,7 +1286,7 @@ cube_is_point(PG_FUNCTION_ARGS)
|
||||
{
|
||||
int i,
|
||||
j;
|
||||
NDBOX *a;
|
||||
NDBOX *a;
|
||||
|
||||
a = (NDBOX *) PG_GETARG_POINTER(0);
|
||||
|
||||
@ -1283,7 +1303,7 @@ cube_is_point(PG_FUNCTION_ARGS)
|
||||
Datum
|
||||
cube_dim(PG_FUNCTION_ARGS)
|
||||
{
|
||||
NDBOX *c;
|
||||
NDBOX *c;
|
||||
|
||||
c = (NDBOX *) PG_GETARG_POINTER(0);
|
||||
|
||||
@ -1397,8 +1417,8 @@ cube_f8(PG_FUNCTION_ARGS)
|
||||
result->dim = 1;
|
||||
result->x[0] = PG_GETARG_FLOAT8(0);
|
||||
result->x[1] = result->x[0];
|
||||
|
||||
PG_RETURN_POINTER (result);
|
||||
|
||||
PG_RETURN_POINTER(result);
|
||||
}
|
||||
|
||||
/* Create a one dimensional box */
|
||||
@ -1416,7 +1436,7 @@ cube_f8_f8(PG_FUNCTION_ARGS)
|
||||
result->x[0] = PG_GETARG_FLOAT8(0);
|
||||
result->x[1] = PG_GETARG_FLOAT8(1);
|
||||
|
||||
PG_RETURN_POINTER (result);
|
||||
PG_RETURN_POINTER(result);
|
||||
}
|
||||
|
||||
/* Add a dimension to an existing cube with the same values for the new
|
||||
@ -1431,7 +1451,7 @@ cube_c_f8(PG_FUNCTION_ARGS)
|
||||
int i;
|
||||
|
||||
c = (NDBOX *) PG_GETARG_POINTER(0);
|
||||
x = PG_GETARG_FLOAT8 (1);
|
||||
x = PG_GETARG_FLOAT8(1);
|
||||
|
||||
size = offsetof(NDBOX, x[0]) + sizeof(double) * (c->dim + 1) *2;
|
||||
result = (NDBOX *) palloc(size);
|
||||
@ -1446,7 +1466,7 @@ cube_c_f8(PG_FUNCTION_ARGS)
|
||||
result->x[result->dim - 1] = x;
|
||||
result->x[2 * result->dim - 1] = x;
|
||||
|
||||
PG_RETURN_POINTER(result);
|
||||
PG_RETURN_POINTER(result);
|
||||
}
|
||||
|
||||
/* Add a dimension to an existing cube */
|
||||
@ -1455,13 +1475,14 @@ cube_c_f8_f8(PG_FUNCTION_ARGS)
|
||||
{
|
||||
NDBOX *c;
|
||||
NDBOX *result;
|
||||
double x1, x2;
|
||||
double x1,
|
||||
x2;
|
||||
int size;
|
||||
int i;
|
||||
|
||||
c = (NDBOX *) PG_GETARG_POINTER(0);
|
||||
x1 = PG_GETARG_FLOAT8 (1);
|
||||
x2 = PG_GETARG_FLOAT8 (2);
|
||||
x1 = PG_GETARG_FLOAT8(1);
|
||||
x2 = PG_GETARG_FLOAT8(2);
|
||||
|
||||
size = offsetof(NDBOX, x[0]) + sizeof(double) * (c->dim + 1) *2;
|
||||
result = (NDBOX *) palloc(size);
|
||||
@ -1476,7 +1497,5 @@ cube_c_f8_f8(PG_FUNCTION_ARGS)
|
||||
result->x[result->dim - 1] = x1;
|
||||
result->x[2 * result->dim - 1] = x2;
|
||||
|
||||
PG_RETURN_POINTER(result);
|
||||
PG_RETURN_POINTER(result);
|
||||
}
|
||||
|
||||
|
||||
|
@ -8,7 +8,7 @@
|
||||
* Darko Prenosil <Darko.Prenosil@finteh.hr>
|
||||
* Shridhar Daithankar <shridhar_daithankar@persistent.co.in>
|
||||
*
|
||||
* $PostgreSQL: pgsql/contrib/dblink/dblink.c,v 1.58 2006/09/02 21:11:15 joe Exp $
|
||||
* $PostgreSQL: pgsql/contrib/dblink/dblink.c,v 1.59 2006/10/04 00:29:44 momjian Exp $
|
||||
* Copyright (c) 2001-2006, PostgreSQL Global Development Group
|
||||
* ALL RIGHTS RESERVED;
|
||||
*
|
||||
@ -362,11 +362,11 @@ dblink_open(PG_FUNCTION_ARGS)
|
||||
DBLINK_RES_INTERNALERROR("begin error");
|
||||
PQclear(res);
|
||||
rconn->newXactForCursor = TRUE;
|
||||
|
||||
/*
|
||||
* Since transaction state was IDLE, we force cursor count to
|
||||
* initially be 0. This is needed as a previous ABORT might
|
||||
* have wiped out our transaction without maintaining the
|
||||
* cursor count for us.
|
||||
* initially be 0. This is needed as a previous ABORT might have wiped
|
||||
* out our transaction without maintaining the cursor count for us.
|
||||
*/
|
||||
rconn->openCursorCount = 0;
|
||||
}
|
||||
@ -621,8 +621,8 @@ dblink_fetch(PG_FUNCTION_ARGS)
|
||||
if (PQnfields(res) != tupdesc->natts)
|
||||
ereport(ERROR,
|
||||
(errcode(ERRCODE_DATATYPE_MISMATCH),
|
||||
errmsg("remote query result rowtype does not match "
|
||||
"the specified FROM clause rowtype")));
|
||||
errmsg("remote query result rowtype does not match "
|
||||
"the specified FROM clause rowtype")));
|
||||
|
||||
/* fast track when no results */
|
||||
if (funcctx->max_calls < 1)
|
||||
@ -827,7 +827,7 @@ dblink_record_internal(FunctionCallInfo fcinfo, bool is_async, bool do_get)
|
||||
|
||||
if (!res ||
|
||||
(PQresultStatus(res) != PGRES_COMMAND_OK &&
|
||||
PQresultStatus(res) != PGRES_TUPLES_OK))
|
||||
PQresultStatus(res) != PGRES_TUPLES_OK))
|
||||
{
|
||||
if (fail)
|
||||
DBLINK_RES_ERROR("sql error");
|
||||
@ -839,33 +839,33 @@ dblink_record_internal(FunctionCallInfo fcinfo, bool is_async, bool do_get)
|
||||
SRF_RETURN_DONE(funcctx);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (PQresultStatus(res) == PGRES_COMMAND_OK)
|
||||
{
|
||||
is_sql_cmd = true;
|
||||
|
||||
|
||||
/* need a tuple descriptor representing one TEXT column */
|
||||
tupdesc = CreateTemplateTupleDesc(1, false);
|
||||
TupleDescInitEntry(tupdesc, (AttrNumber) 1, "status",
|
||||
TEXTOID, -1, 0);
|
||||
|
||||
TEXTOID, -1, 0);
|
||||
|
||||
/*
|
||||
* and save a copy of the command status string to return as our
|
||||
* result tuple
|
||||
*/
|
||||
* and save a copy of the command status string to return as
|
||||
* our result tuple
|
||||
*/
|
||||
sql_cmd_status = PQcmdStatus(res);
|
||||
funcctx->max_calls = 1;
|
||||
}
|
||||
else
|
||||
funcctx->max_calls = PQntuples(res);
|
||||
|
||||
|
||||
/* got results, keep track of them */
|
||||
funcctx->user_fctx = res;
|
||||
|
||||
|
||||
/* if needed, close the connection to the database and cleanup */
|
||||
if (freeconn)
|
||||
PQfinish(conn);
|
||||
|
||||
|
||||
if (!is_sql_cmd)
|
||||
{
|
||||
/* get a tuple descriptor for our result type */
|
||||
@ -878,26 +878,29 @@ dblink_record_internal(FunctionCallInfo fcinfo, bool is_async, bool do_get)
|
||||
/* failed to determine actual type of RECORD */
|
||||
ereport(ERROR,
|
||||
(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
|
||||
errmsg("function returning record called in context "
|
||||
"that cannot accept type record")));
|
||||
errmsg("function returning record called in context "
|
||||
"that cannot accept type record")));
|
||||
break;
|
||||
default:
|
||||
/* result type isn't composite */
|
||||
elog(ERROR, "return type must be a row type");
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
/* make sure we have a persistent copy of the tupdesc */
|
||||
tupdesc = CreateTupleDescCopy(tupdesc);
|
||||
}
|
||||
|
||||
/* check result and tuple descriptor have the same number of columns */
|
||||
|
||||
/*
|
||||
* check result and tuple descriptor have the same number of
|
||||
* columns
|
||||
*/
|
||||
if (PQnfields(res) != tupdesc->natts)
|
||||
ereport(ERROR,
|
||||
(errcode(ERRCODE_DATATYPE_MISMATCH),
|
||||
errmsg("remote query result rowtype does not match "
|
||||
"the specified FROM clause rowtype")));
|
||||
|
||||
errmsg("remote query result rowtype does not match "
|
||||
"the specified FROM clause rowtype")));
|
||||
|
||||
/* fast track when no results */
|
||||
if (funcctx->max_calls < 1)
|
||||
{
|
||||
@ -905,11 +908,11 @@ dblink_record_internal(FunctionCallInfo fcinfo, bool is_async, bool do_get)
|
||||
PQclear(res);
|
||||
SRF_RETURN_DONE(funcctx);
|
||||
}
|
||||
|
||||
|
||||
/* store needed metadata for subsequent calls */
|
||||
attinmeta = TupleDescGetAttInMetadata(tupdesc);
|
||||
funcctx->attinmeta = attinmeta;
|
||||
|
||||
|
||||
MemoryContextSwitchTo(oldcontext);
|
||||
}
|
||||
else
|
||||
@ -991,9 +994,9 @@ PG_FUNCTION_INFO_V1(dblink_get_connections);
|
||||
Datum
|
||||
dblink_get_connections(PG_FUNCTION_ARGS)
|
||||
{
|
||||
HASH_SEQ_STATUS status;
|
||||
remoteConnHashEnt *hentry;
|
||||
ArrayBuildState *astate = NULL;
|
||||
HASH_SEQ_STATUS status;
|
||||
remoteConnHashEnt *hentry;
|
||||
ArrayBuildState *astate = NULL;
|
||||
|
||||
if (remoteConnHash)
|
||||
{
|
||||
@ -1019,19 +1022,19 @@ dblink_get_connections(PG_FUNCTION_ARGS)
|
||||
*
|
||||
* Returns 1 if the connection is busy, 0 otherwise
|
||||
* Params:
|
||||
* text connection_name - name of the connection to check
|
||||
*
|
||||
* text connection_name - name of the connection to check
|
||||
*
|
||||
*/
|
||||
PG_FUNCTION_INFO_V1(dblink_is_busy);
|
||||
Datum
|
||||
dblink_is_busy(PG_FUNCTION_ARGS)
|
||||
{
|
||||
char *msg;
|
||||
PGconn *conn = NULL;
|
||||
char *conname = NULL;
|
||||
char *connstr = NULL;
|
||||
remoteConn *rconn = NULL;
|
||||
bool freeconn = false;
|
||||
char *msg;
|
||||
PGconn *conn = NULL;
|
||||
char *conname = NULL;
|
||||
char *connstr = NULL;
|
||||
remoteConn *rconn = NULL;
|
||||
bool freeconn = false;
|
||||
|
||||
DBLINK_INIT;
|
||||
DBLINK_GET_CONN;
|
||||
@ -1045,27 +1048,27 @@ dblink_is_busy(PG_FUNCTION_ARGS)
|
||||
/*
|
||||
* Cancels a running request on a connection
|
||||
*
|
||||
* Returns text:
|
||||
* Returns text:
|
||||
* "OK" if the cancel request has been sent correctly,
|
||||
* an error message otherwise
|
||||
*
|
||||
* an error message otherwise
|
||||
*
|
||||
* Params:
|
||||
* text connection_name - name of the connection to check
|
||||
*
|
||||
* text connection_name - name of the connection to check
|
||||
*
|
||||
*/
|
||||
PG_FUNCTION_INFO_V1(dblink_cancel_query);
|
||||
Datum
|
||||
dblink_cancel_query(PG_FUNCTION_ARGS)
|
||||
{
|
||||
char *msg;
|
||||
int res = 0;
|
||||
PGconn *conn = NULL;
|
||||
char *conname = NULL;
|
||||
char *connstr = NULL;
|
||||
remoteConn *rconn = NULL;
|
||||
bool freeconn = false;
|
||||
PGcancel *cancel;
|
||||
char errbuf[256];
|
||||
char *msg;
|
||||
int res = 0;
|
||||
PGconn *conn = NULL;
|
||||
char *conname = NULL;
|
||||
char *connstr = NULL;
|
||||
remoteConn *rconn = NULL;
|
||||
bool freeconn = false;
|
||||
PGcancel *cancel;
|
||||
char errbuf[256];
|
||||
|
||||
DBLINK_INIT;
|
||||
DBLINK_GET_CONN;
|
||||
@ -1077,7 +1080,7 @@ dblink_cancel_query(PG_FUNCTION_ARGS)
|
||||
PQfreeCancel(cancel);
|
||||
|
||||
if (res == 0)
|
||||
PG_RETURN_TEXT_P(GET_TEXT("OK"));
|
||||
PG_RETURN_TEXT_P(GET_TEXT("OK"));
|
||||
else
|
||||
PG_RETURN_TEXT_P(GET_TEXT(errbuf));
|
||||
}
|
||||
@ -1086,23 +1089,23 @@ dblink_cancel_query(PG_FUNCTION_ARGS)
|
||||
/*
|
||||
* Get error message from a connection
|
||||
*
|
||||
* Returns text:
|
||||
* Returns text:
|
||||
* "OK" if no error, an error message otherwise
|
||||
*
|
||||
*
|
||||
* Params:
|
||||
* text connection_name - name of the connection to check
|
||||
*
|
||||
* text connection_name - name of the connection to check
|
||||
*
|
||||
*/
|
||||
PG_FUNCTION_INFO_V1(dblink_error_message);
|
||||
Datum
|
||||
dblink_error_message(PG_FUNCTION_ARGS)
|
||||
{
|
||||
char *msg;
|
||||
PGconn *conn = NULL;
|
||||
char *conname = NULL;
|
||||
char *connstr = NULL;
|
||||
remoteConn *rconn = NULL;
|
||||
bool freeconn = false;
|
||||
char *msg;
|
||||
PGconn *conn = NULL;
|
||||
char *conname = NULL;
|
||||
char *connstr = NULL;
|
||||
remoteConn *rconn = NULL;
|
||||
bool freeconn = false;
|
||||
|
||||
DBLINK_INIT;
|
||||
DBLINK_GET_CONN;
|
||||
@ -1859,7 +1862,7 @@ get_sql_delete(Oid relid, int2vector *pkattnums, int16 pknumatts, char **tgt_pka
|
||||
char *relname;
|
||||
TupleDesc tupdesc;
|
||||
int natts;
|
||||
StringInfoData buf;
|
||||
StringInfoData buf;
|
||||
int i;
|
||||
|
||||
initStringInfo(&buf);
|
||||
|
@ -11,39 +11,42 @@
|
||||
#include "storage/bufpage.h"
|
||||
|
||||
|
||||
typedef struct {
|
||||
uint16 keylen;
|
||||
uint16 vallen;
|
||||
uint32
|
||||
valisnull:1,
|
||||
pos:31;
|
||||
} HEntry;
|
||||
typedef struct
|
||||
{
|
||||
uint16 keylen;
|
||||
uint16 vallen;
|
||||
uint32
|
||||
valisnull:1,
|
||||
pos:31;
|
||||
} HEntry;
|
||||
|
||||
|
||||
typedef struct {
|
||||
int4 len;
|
||||
int4 size;
|
||||
char data[1];
|
||||
} HStore;
|
||||
typedef struct
|
||||
{
|
||||
int4 len;
|
||||
int4 size;
|
||||
char data[1];
|
||||
} HStore;
|
||||
|
||||
#define HSHRDSIZE (2*sizeof(int4))
|
||||
#define CALCDATASIZE(x, lenstr) ( (x) * sizeof(HEntry) + HSHRDSIZE + (lenstr) )
|
||||
#define ARRPTR(x) ( (HEntry*) ( (char*)(x) + HSHRDSIZE ) )
|
||||
#define STRPTR(x) ( (char*)(x) + HSHRDSIZE + ( sizeof(HEntry) * ((HStore*)x)->size ) )
|
||||
#define ARRPTR(x) ( (HEntry*) ( (char*)(x) + HSHRDSIZE ) )
|
||||
#define STRPTR(x) ( (char*)(x) + HSHRDSIZE + ( sizeof(HEntry) * ((HStore*)x)->size ) )
|
||||
|
||||
|
||||
#define PG_GETARG_HS(x) ((HStore*)PG_DETOAST_DATUM(PG_GETARG_DATUM(x)))
|
||||
#define PG_GETARG_HS(x) ((HStore*)PG_DETOAST_DATUM(PG_GETARG_DATUM(x)))
|
||||
|
||||
typedef struct {
|
||||
char *key;
|
||||
char *val;
|
||||
uint16 keylen;
|
||||
uint16 vallen;
|
||||
bool isnull;
|
||||
bool needfree;
|
||||
} Pairs;
|
||||
typedef struct
|
||||
{
|
||||
char *key;
|
||||
char *val;
|
||||
uint16 keylen;
|
||||
uint16 vallen;
|
||||
bool isnull;
|
||||
bool needfree;
|
||||
} Pairs;
|
||||
|
||||
int comparePairs(const void *a, const void *b);
|
||||
int uniquePairs(Pairs * a, int4 l, int4 *buflen);
|
||||
int comparePairs(const void *a, const void *b);
|
||||
int uniquePairs(Pairs * a, int4 l, int4 *buflen);
|
||||
|
||||
#endif
|
||||
|
@ -7,8 +7,8 @@
|
||||
|
||||
/* bigint defines */
|
||||
#define BITBYTE 8
|
||||
#define SIGLENINT 4 /* >122 => key will toast, so very slow!!! */
|
||||
#define SIGLEN ( sizeof(int)*SIGLENINT )
|
||||
#define SIGLENINT 4 /* >122 => key will toast, so very slow!!! */
|
||||
#define SIGLEN ( sizeof(int)*SIGLENINT )
|
||||
#define SIGLENBIT (SIGLEN*BITBYTE)
|
||||
|
||||
typedef char BITVEC[SIGLEN];
|
||||
@ -36,22 +36,23 @@ typedef char *BITVECP;
|
||||
#define HASHVAL(val) (((unsigned int)(val)) % SIGLENBIT)
|
||||
#define HASH(sign, val) SETBIT((sign), HASHVAL(val))
|
||||
|
||||
typedef struct {
|
||||
int4 len;
|
||||
int4 flag;
|
||||
char data[1];
|
||||
} GISTTYPE;
|
||||
typedef struct
|
||||
{
|
||||
int4 len;
|
||||
int4 flag;
|
||||
char data[1];
|
||||
} GISTTYPE;
|
||||
|
||||
#define ALLISTRUE 0x04
|
||||
#define ALLISTRUE 0x04
|
||||
|
||||
#define ISALLTRUE(x) ( ((GISTTYPE*)x)->flag & ALLISTRUE )
|
||||
#define ISALLTRUE(x) ( ((GISTTYPE*)x)->flag & ALLISTRUE )
|
||||
|
||||
#define GTHDRSIZE ( sizeof(int4)*2 )
|
||||
#define GTHDRSIZE ( sizeof(int4)*2 )
|
||||
#define CALCGTSIZE(flag) ( GTHDRSIZE+(((flag) & ALLISTRUE) ? 0 : SIGLEN) )
|
||||
|
||||
#define GETSIGN(x) ( (BITVECP)( (char*)x+GTHDRSIZE ) )
|
||||
|
||||
#define SUMBIT(val) ( \
|
||||
#define GETSIGN(x) ( (BITVECP)( (char*)x+GTHDRSIZE ) )
|
||||
|
||||
#define SUMBIT(val) ( \
|
||||
GETBITBYTE((val),0) + \
|
||||
GETBITBYTE((val),1) + \
|
||||
GETBITBYTE((val),2) + \
|
||||
@ -67,20 +68,22 @@ typedef struct {
|
||||
#define WISH_F(a,b,c) (double)( -(double)(((a)-(b))*((a)-(b))*((a)-(b)))*(c) )
|
||||
|
||||
PG_FUNCTION_INFO_V1(ghstore_in);
|
||||
Datum ghstore_in(PG_FUNCTION_ARGS);
|
||||
Datum ghstore_in(PG_FUNCTION_ARGS);
|
||||
|
||||
PG_FUNCTION_INFO_V1(ghstore_out);
|
||||
Datum ghstore_out(PG_FUNCTION_ARGS);
|
||||
|
||||
Datum ghstore_out(PG_FUNCTION_ARGS);
|
||||
|
||||
|
||||
Datum
|
||||
ghstore_in(PG_FUNCTION_ARGS) {
|
||||
ghstore_in(PG_FUNCTION_ARGS)
|
||||
{
|
||||
elog(ERROR, "Not implemented");
|
||||
PG_RETURN_DATUM(0);
|
||||
}
|
||||
|
||||
Datum
|
||||
ghstore_out(PG_FUNCTION_ARGS) {
|
||||
ghstore_out(PG_FUNCTION_ARGS)
|
||||
{
|
||||
elog(ERROR, "Not implemented");
|
||||
PG_RETURN_DATUM(0);
|
||||
}
|
||||
@ -93,36 +96,41 @@ PG_FUNCTION_INFO_V1(ghstore_picksplit);
|
||||
PG_FUNCTION_INFO_V1(ghstore_union);
|
||||
PG_FUNCTION_INFO_V1(ghstore_same);
|
||||
|
||||
Datum ghstore_consistent(PG_FUNCTION_ARGS);
|
||||
Datum ghstore_compress(PG_FUNCTION_ARGS);
|
||||
Datum ghstore_decompress(PG_FUNCTION_ARGS);
|
||||
Datum ghstore_penalty(PG_FUNCTION_ARGS);
|
||||
Datum ghstore_picksplit(PG_FUNCTION_ARGS);
|
||||
Datum ghstore_union(PG_FUNCTION_ARGS);
|
||||
Datum ghstore_same(PG_FUNCTION_ARGS);
|
||||
Datum ghstore_consistent(PG_FUNCTION_ARGS);
|
||||
Datum ghstore_compress(PG_FUNCTION_ARGS);
|
||||
Datum ghstore_decompress(PG_FUNCTION_ARGS);
|
||||
Datum ghstore_penalty(PG_FUNCTION_ARGS);
|
||||
Datum ghstore_picksplit(PG_FUNCTION_ARGS);
|
||||
Datum ghstore_union(PG_FUNCTION_ARGS);
|
||||
Datum ghstore_same(PG_FUNCTION_ARGS);
|
||||
|
||||
Datum
|
||||
ghstore_compress(PG_FUNCTION_ARGS) {
|
||||
ghstore_compress(PG_FUNCTION_ARGS)
|
||||
{
|
||||
GISTENTRY *entry = (GISTENTRY *) PG_GETARG_POINTER(0);
|
||||
GISTENTRY *retval = entry;
|
||||
|
||||
if (entry->leafkey) {
|
||||
GISTTYPE *res = (GISTTYPE*)palloc(CALCGTSIZE(0));
|
||||
HStore *toastedval = (HStore *) DatumGetPointer(entry->key);
|
||||
HStore *val = (HStore *) DatumGetPointer(PG_DETOAST_DATUM(entry->key));
|
||||
HEntry *ptr = ARRPTR(val);
|
||||
char *words = STRPTR(val);
|
||||
|
||||
memset(res,0,CALCGTSIZE(0));
|
||||
res->len=CALCGTSIZE(0);
|
||||
|
||||
while(ptr-ARRPTR(val) < val->size) {
|
||||
int h;
|
||||
h = crc32_sz((char*)(words+ptr->pos), ptr->keylen);
|
||||
HASH( GETSIGN(res), h);
|
||||
if ( !ptr->valisnull ) {
|
||||
h = crc32_sz((char *)(words+ptr->pos+ptr->keylen), ptr->vallen);
|
||||
HASH( GETSIGN(res), h);
|
||||
if (entry->leafkey)
|
||||
{
|
||||
GISTTYPE *res = (GISTTYPE *) palloc(CALCGTSIZE(0));
|
||||
HStore *toastedval = (HStore *) DatumGetPointer(entry->key);
|
||||
HStore *val = (HStore *) DatumGetPointer(PG_DETOAST_DATUM(entry->key));
|
||||
HEntry *ptr = ARRPTR(val);
|
||||
char *words = STRPTR(val);
|
||||
|
||||
memset(res, 0, CALCGTSIZE(0));
|
||||
res->len = CALCGTSIZE(0);
|
||||
|
||||
while (ptr - ARRPTR(val) < val->size)
|
||||
{
|
||||
int h;
|
||||
|
||||
h = crc32_sz((char *) (words + ptr->pos), ptr->keylen);
|
||||
HASH(GETSIGN(res), h);
|
||||
if (!ptr->valisnull)
|
||||
{
|
||||
h = crc32_sz((char *) (words + ptr->pos + ptr->keylen), ptr->vallen);
|
||||
HASH(GETSIGN(res), h);
|
||||
}
|
||||
ptr++;
|
||||
}
|
||||
@ -135,14 +143,16 @@ ghstore_compress(PG_FUNCTION_ARGS) {
|
||||
entry->rel, entry->page,
|
||||
entry->offset,
|
||||
FALSE);
|
||||
} else if ( !ISALLTRUE(DatumGetPointer(entry->key)) ) {
|
||||
int4 i;
|
||||
}
|
||||
else if (!ISALLTRUE(DatumGetPointer(entry->key)))
|
||||
{
|
||||
int4 i;
|
||||
GISTTYPE *res;
|
||||
BITVECP sign = GETSIGN(DatumGetPointer(entry->key));
|
||||
|
||||
BITVECP sign = GETSIGN(DatumGetPointer(entry->key));
|
||||
|
||||
LOOPBYTE(
|
||||
if ((sign[i] & 0xff) != 0xff)
|
||||
PG_RETURN_POINTER(retval);
|
||||
if ((sign[i] & 0xff) != 0xff)
|
||||
PG_RETURN_POINTER(retval);
|
||||
);
|
||||
|
||||
res = (GISTTYPE *) palloc(CALCGTSIZE(ALLISTRUE));
|
||||
@ -152,7 +162,7 @@ ghstore_compress(PG_FUNCTION_ARGS) {
|
||||
retval = (GISTENTRY *) palloc(sizeof(GISTENTRY));
|
||||
gistentryinit(*retval, PointerGetDatum(res),
|
||||
entry->rel, entry->page,
|
||||
entry->offset,
|
||||
entry->offset,
|
||||
FALSE);
|
||||
}
|
||||
|
||||
@ -160,15 +170,17 @@ ghstore_compress(PG_FUNCTION_ARGS) {
|
||||
}
|
||||
|
||||
Datum
|
||||
ghstore_decompress(PG_FUNCTION_ARGS) {
|
||||
ghstore_decompress(PG_FUNCTION_ARGS)
|
||||
{
|
||||
PG_RETURN_DATUM(PG_GETARG_DATUM(0));
|
||||
}
|
||||
|
||||
Datum
|
||||
ghstore_same(PG_FUNCTION_ARGS) {
|
||||
ghstore_same(PG_FUNCTION_ARGS)
|
||||
{
|
||||
GISTTYPE *a = (GISTTYPE *) PG_GETARG_POINTER(0);
|
||||
GISTTYPE *b = (GISTTYPE *) PG_GETARG_POINTER(1);
|
||||
bool *result = (bool *) PG_GETARG_POINTER(2);
|
||||
bool *result = (bool *) PG_GETARG_POINTER(2);
|
||||
|
||||
if (ISALLTRUE(a) && ISALLTRUE(b))
|
||||
*result = true;
|
||||
@ -176,83 +188,97 @@ ghstore_same(PG_FUNCTION_ARGS) {
|
||||
*result = false;
|
||||
else if (ISALLTRUE(b))
|
||||
*result = false;
|
||||
else {
|
||||
int4 i;
|
||||
BITVECP sa = GETSIGN(a),
|
||||
sb = GETSIGN(b);
|
||||
else
|
||||
{
|
||||
int4 i;
|
||||
BITVECP sa = GETSIGN(a),
|
||||
sb = GETSIGN(b);
|
||||
|
||||
*result = true;
|
||||
LOOPBYTE(
|
||||
if (sa[i] != sb[i]) {
|
||||
*result = false;
|
||||
break;
|
||||
}
|
||||
if (sa[i] != sb[i])
|
||||
{
|
||||
*result = false;
|
||||
break;
|
||||
}
|
||||
);
|
||||
}
|
||||
PG_RETURN_POINTER(result);
|
||||
}
|
||||
|
||||
static int4
|
||||
sizebitvec(BITVECP sign) {
|
||||
int4 size = 0, i;
|
||||
sizebitvec(BITVECP sign)
|
||||
{
|
||||
int4 size = 0,
|
||||
i;
|
||||
|
||||
LOOPBYTE(
|
||||
size += SUMBIT(sign);
|
||||
sign = (BITVECP) (((char *) sign) + 1);
|
||||
size += SUMBIT(sign);
|
||||
sign = (BITVECP) (((char *) sign) + 1);
|
||||
);
|
||||
return size;
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
hemdistsign(BITVECP a, BITVECP b) {
|
||||
int i,dist=0;
|
||||
hemdistsign(BITVECP a, BITVECP b)
|
||||
{
|
||||
int i,
|
||||
dist = 0;
|
||||
|
||||
LOOPBIT(
|
||||
if ( GETBIT(a,i) != GETBIT(b,i) )
|
||||
if (GETBIT(a, i) != GETBIT(b, i))
|
||||
dist++;
|
||||
);
|
||||
return dist;
|
||||
}
|
||||
|
||||
static int
|
||||
hemdist(GISTTYPE *a, GISTTYPE *b) {
|
||||
if ( ISALLTRUE(a) ) {
|
||||
hemdist(GISTTYPE * a, GISTTYPE * b)
|
||||
{
|
||||
if (ISALLTRUE(a))
|
||||
{
|
||||
if (ISALLTRUE(b))
|
||||
return 0;
|
||||
else
|
||||
return SIGLENBIT-sizebitvec(GETSIGN(b));
|
||||
} else if (ISALLTRUE(b))
|
||||
return SIGLENBIT-sizebitvec(GETSIGN(a));
|
||||
return SIGLENBIT - sizebitvec(GETSIGN(b));
|
||||
}
|
||||
else if (ISALLTRUE(b))
|
||||
return SIGLENBIT - sizebitvec(GETSIGN(a));
|
||||
|
||||
return hemdistsign( GETSIGN(a), GETSIGN(b) );
|
||||
return hemdistsign(GETSIGN(a), GETSIGN(b));
|
||||
}
|
||||
|
||||
static int4
|
||||
unionkey(BITVECP sbase, GISTTYPE * add)
|
||||
{
|
||||
int4 i;
|
||||
BITVECP sadd = GETSIGN(add);
|
||||
int4 i;
|
||||
BITVECP sadd = GETSIGN(add);
|
||||
|
||||
if (ISALLTRUE(add))
|
||||
return 1;
|
||||
LOOPBYTE(
|
||||
sbase[i] |= sadd[i];
|
||||
sbase[i] |= sadd[i];
|
||||
);
|
||||
return 0;
|
||||
}
|
||||
|
||||
Datum
|
||||
ghstore_union(PG_FUNCTION_ARGS) {
|
||||
GistEntryVector *entryvec = (GistEntryVector *) PG_GETARG_POINTER(0);
|
||||
int4 len = entryvec->n;
|
||||
ghstore_union(PG_FUNCTION_ARGS)
|
||||
{
|
||||
GistEntryVector *entryvec = (GistEntryVector *) PG_GETARG_POINTER(0);
|
||||
int4 len = entryvec->n;
|
||||
|
||||
int *size = (int *) PG_GETARG_POINTER(1);
|
||||
BITVEC base;
|
||||
int4 i;
|
||||
int4 flag = 0;
|
||||
int *size = (int *) PG_GETARG_POINTER(1);
|
||||
BITVEC base;
|
||||
int4 i;
|
||||
int4 flag = 0;
|
||||
GISTTYPE *result;
|
||||
|
||||
MemSet((void *) base, 0, sizeof(BITVEC));
|
||||
for (i = 0; i < len; i++) {
|
||||
if (unionkey(base, GETENTRY(entryvec, i))) {
|
||||
for (i = 0; i < len; i++)
|
||||
{
|
||||
if (unionkey(base, GETENTRY(entryvec, i)))
|
||||
{
|
||||
flag = ALLISTRUE;
|
||||
break;
|
||||
}
|
||||
@ -269,64 +295,72 @@ ghstore_union(PG_FUNCTION_ARGS) {
|
||||
}
|
||||
|
||||
Datum
|
||||
ghstore_penalty(PG_FUNCTION_ARGS) {
|
||||
ghstore_penalty(PG_FUNCTION_ARGS)
|
||||
{
|
||||
GISTENTRY *origentry = (GISTENTRY *) PG_GETARG_POINTER(0); /* always ISSIGNKEY */
|
||||
GISTENTRY *newentry = (GISTENTRY *) PG_GETARG_POINTER(1);
|
||||
float *penalty = (float *) PG_GETARG_POINTER(2);
|
||||
float *penalty = (float *) PG_GETARG_POINTER(2);
|
||||
GISTTYPE *origval = (GISTTYPE *) DatumGetPointer(origentry->key);
|
||||
GISTTYPE *newval = (GISTTYPE *) DatumGetPointer(newentry->key);
|
||||
|
||||
*penalty=hemdist(origval,newval);
|
||||
*penalty = hemdist(origval, newval);
|
||||
PG_RETURN_POINTER(penalty);
|
||||
}
|
||||
|
||||
|
||||
typedef struct {
|
||||
typedef struct
|
||||
{
|
||||
OffsetNumber pos;
|
||||
int4 cost;
|
||||
} SPLITCOST;
|
||||
int4 cost;
|
||||
} SPLITCOST;
|
||||
|
||||
static int
|
||||
comparecost(const void *a, const void *b) {
|
||||
comparecost(const void *a, const void *b)
|
||||
{
|
||||
return ((SPLITCOST *) a)->cost - ((SPLITCOST *) b)->cost;
|
||||
}
|
||||
|
||||
|
||||
Datum
|
||||
ghstore_picksplit(PG_FUNCTION_ARGS) {
|
||||
GistEntryVector *entryvec = (GistEntryVector *) PG_GETARG_POINTER(0);
|
||||
ghstore_picksplit(PG_FUNCTION_ARGS)
|
||||
{
|
||||
GistEntryVector *entryvec = (GistEntryVector *) PG_GETARG_POINTER(0);
|
||||
OffsetNumber maxoff = entryvec->n - 2;
|
||||
|
||||
GIST_SPLITVEC *v = (GIST_SPLITVEC *) PG_GETARG_POINTER(1);
|
||||
OffsetNumber k,
|
||||
j;
|
||||
GISTTYPE *datum_l,
|
||||
GISTTYPE *datum_l,
|
||||
*datum_r;
|
||||
BITVECP union_l,
|
||||
BITVECP union_l,
|
||||
union_r;
|
||||
int4 size_alpha, size_beta;
|
||||
int4 size_waste,
|
||||
int4 size_alpha,
|
||||
size_beta;
|
||||
int4 size_waste,
|
||||
waste = -1;
|
||||
int4 nbytes;
|
||||
int4 nbytes;
|
||||
OffsetNumber seed_1 = 0,
|
||||
seed_2 = 0;
|
||||
OffsetNumber *left,
|
||||
*right;
|
||||
BITVECP ptr;
|
||||
int i;
|
||||
BITVECP ptr;
|
||||
int i;
|
||||
SPLITCOST *costvector;
|
||||
GISTTYPE *_k,
|
||||
GISTTYPE *_k,
|
||||
*_j;
|
||||
|
||||
nbytes = (maxoff + 2) * sizeof(OffsetNumber);
|
||||
v->spl_left = (OffsetNumber *) palloc(nbytes);
|
||||
v->spl_right = (OffsetNumber *) palloc(nbytes);
|
||||
|
||||
for (k = FirstOffsetNumber; k < maxoff; k = OffsetNumberNext(k)) {
|
||||
for (k = FirstOffsetNumber; k < maxoff; k = OffsetNumberNext(k))
|
||||
{
|
||||
_k = GETENTRY(entryvec, k);
|
||||
for (j = OffsetNumberNext(k); j <= maxoff; j = OffsetNumberNext(j)) {
|
||||
size_waste=hemdist(_k, GETENTRY(entryvec, j));
|
||||
if (size_waste > waste ) {
|
||||
for (j = OffsetNumberNext(k); j <= maxoff; j = OffsetNumberNext(j))
|
||||
{
|
||||
size_waste = hemdist(_k, GETENTRY(entryvec, j));
|
||||
if (size_waste > waste)
|
||||
{
|
||||
waste = size_waste;
|
||||
seed_1 = k;
|
||||
seed_2 = j;
|
||||
@ -346,26 +380,32 @@ ghstore_picksplit(PG_FUNCTION_ARGS) {
|
||||
}
|
||||
|
||||
/* form initial .. */
|
||||
if (ISALLTRUE(GETENTRY(entryvec, seed_1))) {
|
||||
if (ISALLTRUE(GETENTRY(entryvec, seed_1)))
|
||||
{
|
||||
datum_l = (GISTTYPE *) palloc(GTHDRSIZE);
|
||||
datum_l->len = GTHDRSIZE;
|
||||
datum_l->flag = ALLISTRUE;
|
||||
} else {
|
||||
}
|
||||
else
|
||||
{
|
||||
datum_l = (GISTTYPE *) palloc(GTHDRSIZE + SIGLEN);
|
||||
datum_l->len = GTHDRSIZE + SIGLEN;
|
||||
datum_l->flag = 0;
|
||||
memcpy((void *) GETSIGN(datum_l), (void *) GETSIGN(GETENTRY(entryvec, seed_1)), sizeof(BITVEC))
|
||||
;
|
||||
;
|
||||
}
|
||||
if (ISALLTRUE(GETENTRY(entryvec, seed_2))) {
|
||||
if (ISALLTRUE(GETENTRY(entryvec, seed_2)))
|
||||
{
|
||||
datum_r = (GISTTYPE *) palloc(GTHDRSIZE);
|
||||
datum_r->len = GTHDRSIZE;
|
||||
datum_r->flag = ALLISTRUE;
|
||||
} else {
|
||||
}
|
||||
else
|
||||
{
|
||||
datum_r = (GISTTYPE *) palloc(GTHDRSIZE + SIGLEN);
|
||||
datum_r->len = GTHDRSIZE + SIGLEN;
|
||||
datum_r->flag = 0;
|
||||
memcpy((void *) GETSIGN(datum_r), (void *) GETSIGN(GETENTRY(entryvec, seed_2)), sizeof(BITVEC)) ;
|
||||
memcpy((void *) GETSIGN(datum_r), (void *) GETSIGN(GETENTRY(entryvec, seed_2)), sizeof(BITVEC));
|
||||
}
|
||||
|
||||
maxoff = OffsetNumberNext(maxoff);
|
||||
@ -375,50 +415,63 @@ ghstore_picksplit(PG_FUNCTION_ARGS) {
|
||||
{
|
||||
costvector[j - 1].pos = j;
|
||||
_j = GETENTRY(entryvec, j);
|
||||
size_alpha = hemdist(datum_l,_j);
|
||||
size_beta = hemdist(datum_r,_j);
|
||||
size_alpha = hemdist(datum_l, _j);
|
||||
size_beta = hemdist(datum_r, _j);
|
||||
costvector[j - 1].cost = abs(size_alpha - size_beta);
|
||||
}
|
||||
qsort((void *) costvector, maxoff, sizeof(SPLITCOST), comparecost);
|
||||
|
||||
union_l=GETSIGN(datum_l);
|
||||
union_r=GETSIGN(datum_r);
|
||||
union_l = GETSIGN(datum_l);
|
||||
union_r = GETSIGN(datum_r);
|
||||
|
||||
for (k = 0; k < maxoff; k++) {
|
||||
for (k = 0; k < maxoff; k++)
|
||||
{
|
||||
j = costvector[k].pos;
|
||||
if (j == seed_1) {
|
||||
if (j == seed_1)
|
||||
{
|
||||
*left++ = j;
|
||||
v->spl_nleft++;
|
||||
continue;
|
||||
} else if (j == seed_2) {
|
||||
}
|
||||
else if (j == seed_2)
|
||||
{
|
||||
*right++ = j;
|
||||
v->spl_nright++;
|
||||
continue;
|
||||
}
|
||||
_j = GETENTRY(entryvec, j);
|
||||
size_alpha = hemdist(datum_l,_j);
|
||||
size_beta = hemdist(datum_r,_j);
|
||||
size_alpha = hemdist(datum_l, _j);
|
||||
size_beta = hemdist(datum_r, _j);
|
||||
|
||||
if (size_alpha < size_beta + WISH_F(v->spl_nleft, v->spl_nright, 0.0001)) {
|
||||
if (ISALLTRUE(datum_l) || ISALLTRUE(_j) ) {
|
||||
if (size_alpha < size_beta + WISH_F(v->spl_nleft, v->spl_nright, 0.0001))
|
||||
{
|
||||
if (ISALLTRUE(datum_l) || ISALLTRUE(_j))
|
||||
{
|
||||
if (!ISALLTRUE(datum_l))
|
||||
MemSet((void *) union_l, 0xff, sizeof(BITVEC));
|
||||
} else {
|
||||
ptr=GETSIGN(_j);
|
||||
}
|
||||
else
|
||||
{
|
||||
ptr = GETSIGN(_j);
|
||||
LOOPBYTE(
|
||||
union_l[i] |= ptr[i];
|
||||
union_l[i] |= ptr[i];
|
||||
);
|
||||
}
|
||||
*left++ = j;
|
||||
v->spl_nleft++;
|
||||
} else {
|
||||
if (ISALLTRUE(datum_r) || ISALLTRUE(_j) ) {
|
||||
}
|
||||
else
|
||||
{
|
||||
if (ISALLTRUE(datum_r) || ISALLTRUE(_j))
|
||||
{
|
||||
if (!ISALLTRUE(datum_r))
|
||||
MemSet((void *) union_r, 0xff, sizeof(BITVEC));
|
||||
} else {
|
||||
ptr=GETSIGN(_j);
|
||||
}
|
||||
else
|
||||
{
|
||||
ptr = GETSIGN(_j);
|
||||
LOOPBYTE(
|
||||
union_r[i] |= ptr[i];
|
||||
union_r[i] |= ptr[i];
|
||||
);
|
||||
}
|
||||
*right++ = j;
|
||||
@ -436,36 +489,41 @@ ghstore_picksplit(PG_FUNCTION_ARGS) {
|
||||
}
|
||||
|
||||
|
||||
Datum
|
||||
ghstore_consistent(PG_FUNCTION_ARGS) {
|
||||
GISTTYPE *entry = (GISTTYPE*) DatumGetPointer( ((GISTENTRY *) PG_GETARG_POINTER(0))->key );
|
||||
HStore *query=PG_GETARG_HS(1);
|
||||
bool res=true;
|
||||
HEntry *qe = ARRPTR(query);
|
||||
char *qv = STRPTR(query);
|
||||
BITVECP sign;
|
||||
Datum
|
||||
ghstore_consistent(PG_FUNCTION_ARGS)
|
||||
{
|
||||
GISTTYPE *entry = (GISTTYPE *) DatumGetPointer(((GISTENTRY *) PG_GETARG_POINTER(0))->key);
|
||||
HStore *query = PG_GETARG_HS(1);
|
||||
bool res = true;
|
||||
HEntry *qe = ARRPTR(query);
|
||||
char *qv = STRPTR(query);
|
||||
BITVECP sign;
|
||||
|
||||
if ( ISALLTRUE(entry) ) {
|
||||
PG_FREE_IF_COPY(query,1);
|
||||
if (ISALLTRUE(entry))
|
||||
{
|
||||
PG_FREE_IF_COPY(query, 1);
|
||||
PG_RETURN_BOOL(true);
|
||||
}
|
||||
|
||||
sign=GETSIGN(entry);
|
||||
while(res && qe-ARRPTR(query) < query->size) {
|
||||
int crc = crc32_sz((char *)(qv + qe->pos), qe->keylen);
|
||||
if (GETBIT(sign,HASHVAL(crc))) {
|
||||
if ( !qe->valisnull ) {
|
||||
crc = crc32_sz((char *)(qv + qe->pos + qe->keylen), qe->vallen);
|
||||
if ( !GETBIT(sign,HASHVAL(crc)) )
|
||||
res=false;
|
||||
sign = GETSIGN(entry);
|
||||
while (res && qe - ARRPTR(query) < query->size)
|
||||
{
|
||||
int crc = crc32_sz((char *) (qv + qe->pos), qe->keylen);
|
||||
|
||||
if (GETBIT(sign, HASHVAL(crc)))
|
||||
{
|
||||
if (!qe->valisnull)
|
||||
{
|
||||
crc = crc32_sz((char *) (qv + qe->pos + qe->keylen), qe->vallen);
|
||||
if (!GETBIT(sign, HASHVAL(crc)))
|
||||
res = false;
|
||||
}
|
||||
} else
|
||||
res=false;
|
||||
}
|
||||
else
|
||||
res = false;
|
||||
qe++;
|
||||
}
|
||||
|
||||
PG_FREE_IF_COPY(query,1);
|
||||
PG_FREE_IF_COPY(query, 1);
|
||||
PG_RETURN_BOOL(res);
|
||||
}
|
||||
|
||||
|
||||
|
@ -3,304 +3,396 @@
|
||||
|
||||
PG_MODULE_MAGIC;
|
||||
|
||||
typedef struct {
|
||||
char *begin;
|
||||
char *ptr;
|
||||
char *cur;
|
||||
char *word;
|
||||
int wordlen;
|
||||
typedef struct
|
||||
{
|
||||
char *begin;
|
||||
char *ptr;
|
||||
char *cur;
|
||||
char *word;
|
||||
int wordlen;
|
||||
|
||||
Pairs *pairs;
|
||||
int pcur;
|
||||
int plen;
|
||||
} HSParser;
|
||||
Pairs *pairs;
|
||||
int pcur;
|
||||
int plen;
|
||||
} HSParser;
|
||||
|
||||
#define RESIZEPRSBUF \
|
||||
do { \
|
||||
if ( state->cur - state->word + 1 >= state->wordlen ) \
|
||||
{ \
|
||||
int4 clen = state->cur - state->word; \
|
||||
state->wordlen *= 2; \
|
||||
state->word = (char*)repalloc( (void*)state->word, state->wordlen ); \
|
||||
state->cur = state->word + clen; \
|
||||
} \
|
||||
if ( state->cur - state->word + 1 >= state->wordlen ) \
|
||||
{ \
|
||||
int4 clen = state->cur - state->word; \
|
||||
state->wordlen *= 2; \
|
||||
state->word = (char*)repalloc( (void*)state->word, state->wordlen ); \
|
||||
state->cur = state->word + clen; \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
|
||||
#define GV_WAITVAL 0
|
||||
#define GV_INVAL 1
|
||||
#define GV_INESCVAL 2
|
||||
#define GV_WAITESCIN 3
|
||||
#define GV_WAITESCESCIN 4
|
||||
#define GV_WAITVAL 0
|
||||
#define GV_INVAL 1
|
||||
#define GV_INESCVAL 2
|
||||
#define GV_WAITESCIN 3
|
||||
#define GV_WAITESCESCIN 4
|
||||
|
||||
static bool
|
||||
get_val( HSParser *state, bool ignoreeq, bool *escaped ) {
|
||||
int st = GV_WAITVAL;
|
||||
state->wordlen=32;
|
||||
state->cur = state->word = palloc( state->wordlen );
|
||||
*escaped=false;
|
||||
get_val(HSParser * state, bool ignoreeq, bool *escaped)
|
||||
{
|
||||
int st = GV_WAITVAL;
|
||||
|
||||
while(1) {
|
||||
if ( st == GV_WAITVAL ) {
|
||||
if ( *(state->ptr) == '"' ) {
|
||||
*escaped=true;
|
||||
state->wordlen = 32;
|
||||
state->cur = state->word = palloc(state->wordlen);
|
||||
*escaped = false;
|
||||
|
||||
while (1)
|
||||
{
|
||||
if (st == GV_WAITVAL)
|
||||
{
|
||||
if (*(state->ptr) == '"')
|
||||
{
|
||||
*escaped = true;
|
||||
st = GV_INESCVAL;
|
||||
} else if ( *(state->ptr) == '\0' ) {
|
||||
}
|
||||
else if (*(state->ptr) == '\0')
|
||||
{
|
||||
return false;
|
||||
} else if ( *(state->ptr) == '=' && !ignoreeq ) {
|
||||
elog(ERROR,"Syntax error near '%c' at postion %d", *(state->ptr), (int4)(state->ptr-state->begin));
|
||||
} else if ( *(state->ptr) == '\\' ) {
|
||||
}
|
||||
else if (*(state->ptr) == '=' && !ignoreeq)
|
||||
{
|
||||
elog(ERROR, "Syntax error near '%c' at postion %d", *(state->ptr), (int4) (state->ptr - state->begin));
|
||||
}
|
||||
else if (*(state->ptr) == '\\')
|
||||
{
|
||||
st = GV_WAITESCIN;
|
||||
} else if ( !isspace((unsigned char) *(state->ptr)) ) {
|
||||
}
|
||||
else if (!isspace((unsigned char) *(state->ptr)))
|
||||
{
|
||||
*(state->cur) = *(state->ptr);
|
||||
state->cur++;
|
||||
st = GV_INVAL;
|
||||
}
|
||||
} else if ( st == GV_INVAL ) {
|
||||
if ( *(state->ptr) == '\\' ) {
|
||||
}
|
||||
else if (st == GV_INVAL)
|
||||
{
|
||||
if (*(state->ptr) == '\\')
|
||||
{
|
||||
st = GV_WAITESCIN;
|
||||
} else if ( *(state->ptr) == '=' && !ignoreeq ) {
|
||||
}
|
||||
else if (*(state->ptr) == '=' && !ignoreeq)
|
||||
{
|
||||
state->ptr--;
|
||||
return true;
|
||||
} else if ( *(state->ptr) == ',' && ignoreeq ) {
|
||||
}
|
||||
else if (*(state->ptr) == ',' && ignoreeq)
|
||||
{
|
||||
state->ptr--;
|
||||
return true;
|
||||
} else if ( isspace((unsigned char) *(state->ptr)) ) {
|
||||
}
|
||||
else if (isspace((unsigned char) *(state->ptr)))
|
||||
{
|
||||
return true;
|
||||
} else if ( *(state->ptr) == '\0' ) {
|
||||
}
|
||||
else if (*(state->ptr) == '\0')
|
||||
{
|
||||
state->ptr--;
|
||||
return true;
|
||||
} else {
|
||||
}
|
||||
else
|
||||
{
|
||||
RESIZEPRSBUF;
|
||||
*(state->cur) = *(state->ptr);
|
||||
state->cur++;
|
||||
}
|
||||
} else if ( st == GV_INESCVAL ) {
|
||||
if ( *(state->ptr) == '\\' ) {
|
||||
}
|
||||
else if (st == GV_INESCVAL)
|
||||
{
|
||||
if (*(state->ptr) == '\\')
|
||||
{
|
||||
st = GV_WAITESCESCIN;
|
||||
} else if ( *(state->ptr) == '"' ) {
|
||||
}
|
||||
else if (*(state->ptr) == '"')
|
||||
{
|
||||
return true;
|
||||
} else if ( *(state->ptr) == '\0' ) {
|
||||
elog(ERROR,"Unexpected end of string");
|
||||
} else {
|
||||
}
|
||||
else if (*(state->ptr) == '\0')
|
||||
{
|
||||
elog(ERROR, "Unexpected end of string");
|
||||
}
|
||||
else
|
||||
{
|
||||
RESIZEPRSBUF;
|
||||
*(state->cur) = *(state->ptr);
|
||||
state->cur++;
|
||||
}
|
||||
} else if ( st == GV_WAITESCIN ) {
|
||||
if ( *(state->ptr) == '\0' )
|
||||
elog(ERROR,"Unexpected end of string");
|
||||
}
|
||||
else if (st == GV_WAITESCIN)
|
||||
{
|
||||
if (*(state->ptr) == '\0')
|
||||
elog(ERROR, "Unexpected end of string");
|
||||
RESIZEPRSBUF;
|
||||
*(state->cur) = *(state->ptr);
|
||||
state->cur++;
|
||||
st = GV_INVAL;
|
||||
} else if ( st == GV_WAITESCESCIN ) {
|
||||
if ( *(state->ptr) == '\0' )
|
||||
elog(ERROR,"Unexpected end of string");
|
||||
st = GV_INVAL;
|
||||
}
|
||||
else if (st == GV_WAITESCESCIN)
|
||||
{
|
||||
if (*(state->ptr) == '\0')
|
||||
elog(ERROR, "Unexpected end of string");
|
||||
RESIZEPRSBUF;
|
||||
*(state->cur) = *(state->ptr);
|
||||
state->cur++;
|
||||
st = GV_INESCVAL;
|
||||
} else
|
||||
elog(ERROR,"Unknown state %d at postion line %d in file '%s'", st, __LINE__, __FILE__);
|
||||
}
|
||||
else
|
||||
elog(ERROR, "Unknown state %d at postion line %d in file '%s'", st, __LINE__, __FILE__);
|
||||
|
||||
state->ptr++;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
#define WKEY 0
|
||||
#define WVAL 1
|
||||
#define WEQ 2
|
||||
#define WGT 3
|
||||
#define WEQ 2
|
||||
#define WGT 3
|
||||
#define WDEL 4
|
||||
|
||||
|
||||
static void
|
||||
parse_hstore( HSParser *state ) {
|
||||
int st = WKEY;
|
||||
bool escaped=false;
|
||||
parse_hstore(HSParser * state)
|
||||
{
|
||||
int st = WKEY;
|
||||
bool escaped = false;
|
||||
|
||||
state->plen=16;
|
||||
state->pairs = (Pairs*)palloc( sizeof(Pairs) * state->plen );
|
||||
state->pcur=0;
|
||||
state->plen = 16;
|
||||
state->pairs = (Pairs *) palloc(sizeof(Pairs) * state->plen);
|
||||
state->pcur = 0;
|
||||
state->ptr = state->begin;
|
||||
state->word=NULL;
|
||||
state->word = NULL;
|
||||
|
||||
while(1) {
|
||||
if (st == WKEY) {
|
||||
if ( !get_val(state, false, &escaped) )
|
||||
while (1)
|
||||
{
|
||||
if (st == WKEY)
|
||||
{
|
||||
if (!get_val(state, false, &escaped))
|
||||
return;
|
||||
if ( state->pcur >= state->plen ) {
|
||||
if (state->pcur >= state->plen)
|
||||
{
|
||||
state->plen *= 2;
|
||||
state->pairs = (Pairs*)repalloc( state->pairs, sizeof(Pairs) * state->plen );
|
||||
state->pairs = (Pairs *) repalloc(state->pairs, sizeof(Pairs) * state->plen);
|
||||
}
|
||||
state->pairs[ state->pcur ].key = state->word;
|
||||
state->pairs[ state->pcur ].keylen = state->cur - state->word;
|
||||
state->pairs[ state->pcur ].val=NULL;
|
||||
state->word=NULL;
|
||||
state->pairs[state->pcur].key = state->word;
|
||||
state->pairs[state->pcur].keylen = state->cur - state->word;
|
||||
state->pairs[state->pcur].val = NULL;
|
||||
state->word = NULL;
|
||||
st = WEQ;
|
||||
} else if ( st == WEQ ) {
|
||||
if ( *(state->ptr) == '=' ) {
|
||||
}
|
||||
else if (st == WEQ)
|
||||
{
|
||||
if (*(state->ptr) == '=')
|
||||
{
|
||||
st = WGT;
|
||||
} else if ( *(state->ptr) == '\0' ) {
|
||||
elog(ERROR,"Unexpectd end of string");
|
||||
} else if (!isspace((unsigned char) *(state->ptr))) {
|
||||
elog(ERROR,"Syntax error near '%c' at postion %d", *(state->ptr), (int4)(state->ptr-state->begin));
|
||||
}
|
||||
} else if ( st == WGT ) {
|
||||
if ( *(state->ptr) == '>' ) {
|
||||
else if (*(state->ptr) == '\0')
|
||||
{
|
||||
elog(ERROR, "Unexpectd end of string");
|
||||
}
|
||||
else if (!isspace((unsigned char) *(state->ptr)))
|
||||
{
|
||||
elog(ERROR, "Syntax error near '%c' at postion %d", *(state->ptr), (int4) (state->ptr - state->begin));
|
||||
}
|
||||
}
|
||||
else if (st == WGT)
|
||||
{
|
||||
if (*(state->ptr) == '>')
|
||||
{
|
||||
st = WVAL;
|
||||
} else if ( *(state->ptr) == '\0' ) {
|
||||
elog(ERROR,"Unexpectd end of string");
|
||||
} else {
|
||||
elog(ERROR,"Syntax error near '%c' at postion %d", *(state->ptr), (int4)(state->ptr-state->begin));
|
||||
}
|
||||
} else if ( st == WVAL ) {
|
||||
if ( !get_val(state, true, &escaped) )
|
||||
elog(ERROR,"Unexpected end of string");
|
||||
state->pairs[ state->pcur ].val = state->word;
|
||||
state->pairs[ state->pcur ].vallen = state->cur - state->word;
|
||||
state->pairs[ state->pcur ].isnull = false;
|
||||
state->pairs[ state->pcur ].needfree = true;
|
||||
if ( state->cur - state->word == 4 && !escaped) {
|
||||
else if (*(state->ptr) == '\0')
|
||||
{
|
||||
elog(ERROR, "Unexpectd end of string");
|
||||
}
|
||||
else
|
||||
{
|
||||
elog(ERROR, "Syntax error near '%c' at postion %d", *(state->ptr), (int4) (state->ptr - state->begin));
|
||||
}
|
||||
}
|
||||
else if (st == WVAL)
|
||||
{
|
||||
if (!get_val(state, true, &escaped))
|
||||
elog(ERROR, "Unexpected end of string");
|
||||
state->pairs[state->pcur].val = state->word;
|
||||
state->pairs[state->pcur].vallen = state->cur - state->word;
|
||||
state->pairs[state->pcur].isnull = false;
|
||||
state->pairs[state->pcur].needfree = true;
|
||||
if (state->cur - state->word == 4 && !escaped)
|
||||
{
|
||||
state->word[4] = '\0';
|
||||
if ( 0==pg_strcasecmp(state->word, "null") )
|
||||
state->pairs[ state->pcur ].isnull=true;
|
||||
}
|
||||
state->word=NULL;
|
||||
if (0 == pg_strcasecmp(state->word, "null"))
|
||||
state->pairs[state->pcur].isnull = true;
|
||||
}
|
||||
state->word = NULL;
|
||||
state->pcur++;
|
||||
st = WDEL;
|
||||
} else if ( st == WDEL ) {
|
||||
if ( *(state->ptr) == ',' ) {
|
||||
}
|
||||
else if (st == WDEL)
|
||||
{
|
||||
if (*(state->ptr) == ',')
|
||||
{
|
||||
st = WKEY;
|
||||
} else if ( *(state->ptr) == '\0' ) {
|
||||
return;
|
||||
} else if (!isspace((unsigned char) *(state->ptr))) {
|
||||
elog(ERROR,"Syntax error near '%c' at postion %d", *(state->ptr), (int4)(state->ptr-state->begin));
|
||||
}
|
||||
} else
|
||||
elog(ERROR,"Unknown state %d at line %d in file '%s'", st, __LINE__, __FILE__);
|
||||
else if (*(state->ptr) == '\0')
|
||||
{
|
||||
return;
|
||||
}
|
||||
else if (!isspace((unsigned char) *(state->ptr)))
|
||||
{
|
||||
elog(ERROR, "Syntax error near '%c' at postion %d", *(state->ptr), (int4) (state->ptr - state->begin));
|
||||
}
|
||||
}
|
||||
else
|
||||
elog(ERROR, "Unknown state %d at line %d in file '%s'", st, __LINE__, __FILE__);
|
||||
|
||||
state->ptr++;
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
comparePairs(const void *a, const void *b) {
|
||||
if ( ((Pairs*)a)->keylen == ((Pairs*)b)->keylen ) {
|
||||
int res = strncmp(
|
||||
((Pairs*)a)->key,
|
||||
((Pairs*)b)->key,
|
||||
((Pairs*)a)->keylen
|
||||
);
|
||||
if ( res )
|
||||
return res;
|
||||
|
||||
/* guarantee that neddfree willl be later */
|
||||
if ( ((Pairs*)b)->needfree == ((Pairs*)a)->needfree )
|
||||
return 0;
|
||||
else if ( ((Pairs*)a)->needfree )
|
||||
return 1;
|
||||
else
|
||||
return -1;
|
||||
}
|
||||
return ( ((Pairs*)a)->keylen > ((Pairs*)b)->keylen ) ? 1 : -1;
|
||||
}
|
||||
|
||||
int
|
||||
uniquePairs(Pairs * a, int4 l, int4 *buflen) {
|
||||
Pairs *ptr, *res;
|
||||
comparePairs(const void *a, const void *b)
|
||||
{
|
||||
if (((Pairs *) a)->keylen == ((Pairs *) b)->keylen)
|
||||
{
|
||||
int res = strncmp(
|
||||
((Pairs *) a)->key,
|
||||
((Pairs *) b)->key,
|
||||
((Pairs *) a)->keylen
|
||||
);
|
||||
|
||||
*buflen=0;
|
||||
if ( l < 2 ) {
|
||||
if ( l==1 )
|
||||
*buflen = a->keylen + ((a->isnull) ? 0 : a->vallen) ;
|
||||
if (res)
|
||||
return res;
|
||||
|
||||
/* guarantee that neddfree willl be later */
|
||||
if (((Pairs *) b)->needfree == ((Pairs *) a)->needfree)
|
||||
return 0;
|
||||
else if (((Pairs *) a)->needfree)
|
||||
return 1;
|
||||
else
|
||||
return -1;
|
||||
}
|
||||
return (((Pairs *) a)->keylen > ((Pairs *) b)->keylen) ? 1 : -1;
|
||||
}
|
||||
|
||||
int
|
||||
uniquePairs(Pairs * a, int4 l, int4 *buflen)
|
||||
{
|
||||
Pairs *ptr,
|
||||
*res;
|
||||
|
||||
*buflen = 0;
|
||||
if (l < 2)
|
||||
{
|
||||
if (l == 1)
|
||||
*buflen = a->keylen + ((a->isnull) ? 0 : a->vallen);
|
||||
return l;
|
||||
}
|
||||
|
||||
qsort((void *) a, l, sizeof(Pairs), comparePairs);
|
||||
ptr=a+1;
|
||||
res=a;
|
||||
while( ptr - a < l ) {
|
||||
if ( ptr->keylen == res->keylen && strncmp( ptr->key, res->key, res->keylen )==0 ) {
|
||||
if ( ptr->needfree ) {
|
||||
ptr = a + 1;
|
||||
res = a;
|
||||
while (ptr - a < l)
|
||||
{
|
||||
if (ptr->keylen == res->keylen && strncmp(ptr->key, res->key, res->keylen) == 0)
|
||||
{
|
||||
if (ptr->needfree)
|
||||
{
|
||||
pfree(ptr->key);
|
||||
pfree(ptr->val);
|
||||
}
|
||||
} else {
|
||||
*buflen += res->keylen + (( res->isnull ) ? 0 : res->vallen);
|
||||
}
|
||||
else
|
||||
{
|
||||
*buflen += res->keylen + ((res->isnull) ? 0 : res->vallen);
|
||||
res++;
|
||||
memcpy(res,ptr,sizeof(Pairs));
|
||||
memcpy(res, ptr, sizeof(Pairs));
|
||||
}
|
||||
|
||||
ptr++;
|
||||
}
|
||||
|
||||
*buflen += res->keylen + (( res->isnull ) ? 0 : res->vallen);
|
||||
*buflen += res->keylen + ((res->isnull) ? 0 : res->vallen);
|
||||
return res + 1 - a;
|
||||
}
|
||||
|
||||
static void
|
||||
freeHSParse(HSParser *state) {
|
||||
int i;
|
||||
freeHSParse(HSParser * state)
|
||||
{
|
||||
int i;
|
||||
|
||||
if ( state->word ) pfree( state->word );
|
||||
for (i=0;i<state->pcur;i++)
|
||||
if ( state->pairs[i].needfree ) {
|
||||
if (state->pairs[i].key) pfree(state->pairs[i].key);
|
||||
if (state->pairs[i].val) pfree(state->pairs[i].val);
|
||||
if (state->word)
|
||||
pfree(state->word);
|
||||
for (i = 0; i < state->pcur; i++)
|
||||
if (state->pairs[i].needfree)
|
||||
{
|
||||
if (state->pairs[i].key)
|
||||
pfree(state->pairs[i].key);
|
||||
if (state->pairs[i].val)
|
||||
pfree(state->pairs[i].val);
|
||||
}
|
||||
pfree( state->pairs );
|
||||
pfree(state->pairs);
|
||||
}
|
||||
|
||||
PG_FUNCTION_INFO_V1(hstore_in);
|
||||
Datum hstore_in(PG_FUNCTION_ARGS);
|
||||
Datum hstore_in(PG_FUNCTION_ARGS);
|
||||
Datum
|
||||
hstore_in(PG_FUNCTION_ARGS) {
|
||||
HSParser state;
|
||||
int4 len,buflen,i;
|
||||
HStore *out;
|
||||
HEntry *entries;
|
||||
char *ptr;
|
||||
hstore_in(PG_FUNCTION_ARGS)
|
||||
{
|
||||
HSParser state;
|
||||
int4 len,
|
||||
buflen,
|
||||
i;
|
||||
HStore *out;
|
||||
HEntry *entries;
|
||||
char *ptr;
|
||||
|
||||
state.begin = PG_GETARG_CSTRING(0);
|
||||
state.begin = PG_GETARG_CSTRING(0);
|
||||
|
||||
parse_hstore(&state);
|
||||
|
||||
if ( state.pcur == 0 ) {
|
||||
if (state.pcur == 0)
|
||||
{
|
||||
freeHSParse(&state);
|
||||
len = CALCDATASIZE(0,0);
|
||||
len = CALCDATASIZE(0, 0);
|
||||
out = palloc(len);
|
||||
out->len=len;
|
||||
out->size=0;
|
||||
out->len = len;
|
||||
out->size = 0;
|
||||
PG_RETURN_POINTER(out);
|
||||
}
|
||||
|
||||
state.pcur = uniquePairs(state.pairs, state.pcur, &buflen);
|
||||
|
||||
len=CALCDATASIZE(state.pcur, buflen);
|
||||
len = CALCDATASIZE(state.pcur, buflen);
|
||||
out = palloc(len);
|
||||
out->len=len;
|
||||
out->size=state.pcur;
|
||||
out->len = len;
|
||||
out->size = state.pcur;
|
||||
|
||||
entries=ARRPTR(out);
|
||||
entries = ARRPTR(out);
|
||||
ptr = STRPTR(out);
|
||||
|
||||
for(i=0;i<out->size;i++) {
|
||||
for (i = 0; i < out->size; i++)
|
||||
{
|
||||
entries[i].keylen = state.pairs[i].keylen;
|
||||
entries[i].pos = ptr - STRPTR(out);
|
||||
memcpy(ptr, state.pairs[i].key, state.pairs[i].keylen);
|
||||
ptr+=entries[i].keylen;
|
||||
ptr += entries[i].keylen;
|
||||
|
||||
entries[i].valisnull = state.pairs[i].isnull;
|
||||
if ( entries[i].valisnull )
|
||||
entries[i].vallen=4; /* null */
|
||||
else {
|
||||
if (entries[i].valisnull)
|
||||
entries[i].vallen = 4; /* null */
|
||||
else
|
||||
{
|
||||
entries[i].vallen = state.pairs[i].vallen;
|
||||
memcpy(ptr, state.pairs[i].val,state.pairs[i].vallen);
|
||||
ptr+=entries[i].vallen;
|
||||
memcpy(ptr, state.pairs[i].val, state.pairs[i].vallen);
|
||||
ptr += entries[i].vallen;
|
||||
}
|
||||
}
|
||||
|
||||
@ -308,63 +400,74 @@ hstore_in(PG_FUNCTION_ARGS) {
|
||||
PG_RETURN_POINTER(out);
|
||||
}
|
||||
|
||||
static char*
|
||||
cpw(char *dst, char *src, int len) {
|
||||
char *ptr = src;
|
||||
static char *
|
||||
cpw(char *dst, char *src, int len)
|
||||
{
|
||||
char *ptr = src;
|
||||
|
||||
while(ptr-src<len) {
|
||||
if ( *ptr == '"' || *ptr == '\\' )
|
||||
*dst++='\\';
|
||||
while (ptr - src < len)
|
||||
{
|
||||
if (*ptr == '"' || *ptr == '\\')
|
||||
*dst++ = '\\';
|
||||
*dst++ = *ptr++;
|
||||
}
|
||||
return dst;
|
||||
}
|
||||
|
||||
PG_FUNCTION_INFO_V1(hstore_out);
|
||||
Datum hstore_out(PG_FUNCTION_ARGS);
|
||||
Datum hstore_out(PG_FUNCTION_ARGS);
|
||||
Datum
|
||||
hstore_out(PG_FUNCTION_ARGS) {
|
||||
HStore *in = PG_GETARG_HS(0);
|
||||
int buflen,i;
|
||||
char *out,*ptr;
|
||||
char *base = STRPTR(in);
|
||||
HEntry *entries = ARRPTR(in);
|
||||
hstore_out(PG_FUNCTION_ARGS)
|
||||
{
|
||||
HStore *in = PG_GETARG_HS(0);
|
||||
int buflen,
|
||||
i;
|
||||
char *out,
|
||||
*ptr;
|
||||
char *base = STRPTR(in);
|
||||
HEntry *entries = ARRPTR(in);
|
||||
|
||||
if ( in->size==0 ) {
|
||||
out=palloc(1);
|
||||
*out='\0';
|
||||
PG_FREE_IF_COPY(in,0);
|
||||
if (in->size == 0)
|
||||
{
|
||||
out = palloc(1);
|
||||
*out = '\0';
|
||||
PG_FREE_IF_COPY(in, 0);
|
||||
PG_RETURN_CSTRING(out);
|
||||
}
|
||||
|
||||
buflen = ( 4 /* " */ + 2 /* => */ + 2 /*, */ )*in->size +
|
||||
2 /* esc */ * ( in->len - CALCDATASIZE(in->size,0) );
|
||||
buflen = (4 /* " */ + 2 /* => */ + 2 /* , */ ) * in->size +
|
||||
2 /* esc */ * (in->len - CALCDATASIZE(in->size, 0));
|
||||
|
||||
out=ptr=palloc(buflen);
|
||||
for(i=0;i<in->size;i++) {
|
||||
*ptr++='"';
|
||||
ptr = cpw( ptr, base + entries[i].pos, entries[i].keylen );
|
||||
*ptr++='"';
|
||||
*ptr++='=';
|
||||
*ptr++='>';
|
||||
if ( entries[i].valisnull ) {
|
||||
*ptr++='N';
|
||||
*ptr++='U';
|
||||
*ptr++='L';
|
||||
*ptr++='L';
|
||||
} else {
|
||||
*ptr++='"';
|
||||
ptr = cpw( ptr, base + entries[i].pos + entries[i].keylen, entries[i].vallen );
|
||||
*ptr++='"';
|
||||
out = ptr = palloc(buflen);
|
||||
for (i = 0; i < in->size; i++)
|
||||
{
|
||||
*ptr++ = '"';
|
||||
ptr = cpw(ptr, base + entries[i].pos, entries[i].keylen);
|
||||
*ptr++ = '"';
|
||||
*ptr++ = '=';
|
||||
*ptr++ = '>';
|
||||
if (entries[i].valisnull)
|
||||
{
|
||||
*ptr++ = 'N';
|
||||
*ptr++ = 'U';
|
||||
*ptr++ = 'L';
|
||||
*ptr++ = 'L';
|
||||
}
|
||||
else
|
||||
{
|
||||
*ptr++ = '"';
|
||||
ptr = cpw(ptr, base + entries[i].pos + entries[i].keylen, entries[i].vallen);
|
||||
*ptr++ = '"';
|
||||
}
|
||||
|
||||
if ( i+1 != in->size ) {
|
||||
*ptr++=',';
|
||||
*ptr++=' ';
|
||||
if (i + 1 != in->size)
|
||||
{
|
||||
*ptr++ = ',';
|
||||
*ptr++ = ' ';
|
||||
}
|
||||
}
|
||||
*ptr='\0';
|
||||
*ptr = '\0';
|
||||
|
||||
PG_FREE_IF_COPY(in,0);
|
||||
PG_FREE_IF_COPY(in, 0);
|
||||
PG_RETURN_CSTRING(out);
|
||||
}
|
||||
|
@ -7,20 +7,22 @@
|
||||
|
||||
|
||||
static HEntry *
|
||||
findkey(HStore *hs, char *key, int keylen) {
|
||||
HEntry *StopLow = ARRPTR(hs);
|
||||
HEntry *StopHigh = StopLow + hs->size;
|
||||
HEntry *StopMiddle;
|
||||
int difference;
|
||||
char *base = STRPTR(hs);
|
||||
findkey(HStore * hs, char *key, int keylen)
|
||||
{
|
||||
HEntry *StopLow = ARRPTR(hs);
|
||||
HEntry *StopHigh = StopLow + hs->size;
|
||||
HEntry *StopMiddle;
|
||||
int difference;
|
||||
char *base = STRPTR(hs);
|
||||
|
||||
while (StopLow < StopHigh) {
|
||||
while (StopLow < StopHigh)
|
||||
{
|
||||
StopMiddle = StopLow + (StopHigh - StopLow) / 2;
|
||||
|
||||
if ( StopMiddle->keylen == keylen )
|
||||
difference=strncmp(base+StopMiddle->pos, key, StopMiddle->keylen);
|
||||
if (StopMiddle->keylen == keylen)
|
||||
difference = strncmp(base + StopMiddle->pos, key, StopMiddle->keylen);
|
||||
else
|
||||
difference=(StopMiddle->keylen > keylen) ? 1 : -1;
|
||||
difference = (StopMiddle->keylen > keylen) ? 1 : -1;
|
||||
|
||||
if (difference == 0)
|
||||
return StopMiddle;
|
||||
@ -29,520 +31,583 @@ findkey(HStore *hs, char *key, int keylen) {
|
||||
else
|
||||
StopHigh = StopMiddle;
|
||||
}
|
||||
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
PG_FUNCTION_INFO_V1(fetchval);
|
||||
Datum fetchval(PG_FUNCTION_ARGS);
|
||||
Datum fetchval(PG_FUNCTION_ARGS);
|
||||
Datum
|
||||
fetchval(PG_FUNCTION_ARGS) {
|
||||
HStore *hs = PG_GETARG_HS(0);
|
||||
text *key = PG_GETARG_TEXT_P(1);
|
||||
HEntry *entry;
|
||||
text *out;
|
||||
fetchval(PG_FUNCTION_ARGS)
|
||||
{
|
||||
HStore *hs = PG_GETARG_HS(0);
|
||||
text *key = PG_GETARG_TEXT_P(1);
|
||||
HEntry *entry;
|
||||
text *out;
|
||||
|
||||
if ((entry=findkey(hs,VARDATA(key), VARSIZE(key)-VARHDRSZ))==NULL || entry->valisnull) {
|
||||
PG_FREE_IF_COPY(hs,0);
|
||||
PG_FREE_IF_COPY(key,1);
|
||||
if ((entry = findkey(hs, VARDATA(key), VARSIZE(key) - VARHDRSZ)) == NULL || entry->valisnull)
|
||||
{
|
||||
PG_FREE_IF_COPY(hs, 0);
|
||||
PG_FREE_IF_COPY(key, 1);
|
||||
PG_RETURN_NULL();
|
||||
}
|
||||
|
||||
out=palloc(VARHDRSZ+entry->vallen);
|
||||
memcpy(VARDATA(out),STRPTR(hs) + entry->pos + entry->keylen, entry->vallen);
|
||||
VARATT_SIZEP(out) = VARHDRSZ+entry->vallen;
|
||||
out = palloc(VARHDRSZ + entry->vallen);
|
||||
memcpy(VARDATA(out), STRPTR(hs) + entry->pos + entry->keylen, entry->vallen);
|
||||
VARATT_SIZEP(out) = VARHDRSZ + entry->vallen;
|
||||
|
||||
PG_FREE_IF_COPY(hs,0);
|
||||
PG_FREE_IF_COPY(key,1);
|
||||
PG_FREE_IF_COPY(hs, 0);
|
||||
PG_FREE_IF_COPY(key, 1);
|
||||
PG_RETURN_POINTER(out);
|
||||
}
|
||||
|
||||
PG_FUNCTION_INFO_V1(exists);
|
||||
Datum exists(PG_FUNCTION_ARGS);
|
||||
Datum exists(PG_FUNCTION_ARGS);
|
||||
Datum
|
||||
exists(PG_FUNCTION_ARGS) {
|
||||
HStore *hs = PG_GETARG_HS(0);
|
||||
text *key = PG_GETARG_TEXT_P(1);
|
||||
HEntry *entry;
|
||||
exists(PG_FUNCTION_ARGS)
|
||||
{
|
||||
HStore *hs = PG_GETARG_HS(0);
|
||||
text *key = PG_GETARG_TEXT_P(1);
|
||||
HEntry *entry;
|
||||
|
||||
entry=findkey(hs,VARDATA(key), VARSIZE(key)-VARHDRSZ);
|
||||
entry = findkey(hs, VARDATA(key), VARSIZE(key) - VARHDRSZ);
|
||||
|
||||
PG_FREE_IF_COPY(hs,0);
|
||||
PG_FREE_IF_COPY(key,1);
|
||||
PG_FREE_IF_COPY(hs, 0);
|
||||
PG_FREE_IF_COPY(key, 1);
|
||||
|
||||
PG_RETURN_BOOL(entry);
|
||||
}
|
||||
|
||||
PG_FUNCTION_INFO_V1(defined);
|
||||
Datum defined(PG_FUNCTION_ARGS);
|
||||
Datum defined(PG_FUNCTION_ARGS);
|
||||
Datum
|
||||
defined(PG_FUNCTION_ARGS) {
|
||||
HStore *hs = PG_GETARG_HS(0);
|
||||
text *key = PG_GETARG_TEXT_P(1);
|
||||
HEntry *entry;
|
||||
bool res;
|
||||
defined(PG_FUNCTION_ARGS)
|
||||
{
|
||||
HStore *hs = PG_GETARG_HS(0);
|
||||
text *key = PG_GETARG_TEXT_P(1);
|
||||
HEntry *entry;
|
||||
bool res;
|
||||
|
||||
entry=findkey(hs,VARDATA(key), VARSIZE(key)-VARHDRSZ);
|
||||
entry = findkey(hs, VARDATA(key), VARSIZE(key) - VARHDRSZ);
|
||||
|
||||
res = ( entry && !entry->valisnull ) ? true : false;
|
||||
res = (entry && !entry->valisnull) ? true : false;
|
||||
|
||||
PG_FREE_IF_COPY(hs,0);
|
||||
PG_FREE_IF_COPY(key,1);
|
||||
PG_FREE_IF_COPY(hs, 0);
|
||||
PG_FREE_IF_COPY(key, 1);
|
||||
|
||||
PG_RETURN_BOOL(res);
|
||||
}
|
||||
|
||||
PG_FUNCTION_INFO_V1(delete);
|
||||
Datum delete(PG_FUNCTION_ARGS);
|
||||
Datum delete(PG_FUNCTION_ARGS);
|
||||
Datum
|
||||
delete(PG_FUNCTION_ARGS) {
|
||||
HStore *hs = PG_GETARG_HS(0);
|
||||
text *key = PG_GETARG_TEXT_P(1);
|
||||
HStore *out = palloc(hs->len);
|
||||
char *ptrs, *ptrd;
|
||||
HEntry *es, *ed;
|
||||
delete(PG_FUNCTION_ARGS)
|
||||
{
|
||||
HStore *hs = PG_GETARG_HS(0);
|
||||
text *key = PG_GETARG_TEXT_P(1);
|
||||
HStore *out = palloc(hs->len);
|
||||
char *ptrs,
|
||||
*ptrd;
|
||||
HEntry *es,
|
||||
*ed;
|
||||
|
||||
out->len=hs->len;
|
||||
out->size=hs->size; /* temprorary! */
|
||||
out->len = hs->len;
|
||||
out->size = hs->size; /* temprorary! */
|
||||
|
||||
ptrs=STRPTR(hs);
|
||||
es =ARRPTR(hs);
|
||||
ptrd=STRPTR(out);
|
||||
ed =ARRPTR(out);
|
||||
ptrs = STRPTR(hs);
|
||||
es = ARRPTR(hs);
|
||||
ptrd = STRPTR(out);
|
||||
ed = ARRPTR(out);
|
||||
|
||||
while( es - ARRPTR(hs) < hs->size ) {
|
||||
if ( !(es->keylen == VARSIZE(key) - VARHDRSZ && strncmp(ptrs, VARDATA(key), es->keylen)==0) ) {
|
||||
memcpy( ed, es, sizeof(HEntry) );
|
||||
memcpy( ptrd, ptrs, es->keylen + ( (es->valisnull) ? 0 : es->vallen ) );
|
||||
while (es - ARRPTR(hs) < hs->size)
|
||||
{
|
||||
if (!(es->keylen == VARSIZE(key) - VARHDRSZ && strncmp(ptrs, VARDATA(key), es->keylen) == 0))
|
||||
{
|
||||
memcpy(ed, es, sizeof(HEntry));
|
||||
memcpy(ptrd, ptrs, es->keylen + ((es->valisnull) ? 0 : es->vallen));
|
||||
ed->pos = ptrd - STRPTR(out);
|
||||
ptrd += es->keylen + ( (es->valisnull) ? 0 : es->vallen );
|
||||
ptrd += es->keylen + ((es->valisnull) ? 0 : es->vallen);
|
||||
ed++;
|
||||
}
|
||||
ptrs += es->keylen + ( (es->valisnull) ? 0 : es->vallen );
|
||||
ptrs += es->keylen + ((es->valisnull) ? 0 : es->vallen);
|
||||
es++;
|
||||
}
|
||||
|
||||
if ( ed - ARRPTR(out) != out->size ) {
|
||||
int buflen=ptrd-STRPTR(out);
|
||||
if (ed - ARRPTR(out) != out->size)
|
||||
{
|
||||
int buflen = ptrd - STRPTR(out);
|
||||
|
||||
ptrd = STRPTR(out);
|
||||
|
||||
out->size = ed - ARRPTR(out);
|
||||
|
||||
memmove( STRPTR(out), ptrd, buflen);
|
||||
memmove(STRPTR(out), ptrd, buflen);
|
||||
out->len = CALCDATASIZE(out->size, buflen);
|
||||
}
|
||||
|
||||
|
||||
PG_FREE_IF_COPY(hs,0);
|
||||
PG_FREE_IF_COPY(key,1);
|
||||
|
||||
PG_FREE_IF_COPY(hs, 0);
|
||||
PG_FREE_IF_COPY(key, 1);
|
||||
|
||||
PG_RETURN_POINTER(out);
|
||||
}
|
||||
|
||||
PG_FUNCTION_INFO_V1(hs_concat);
|
||||
Datum hs_concat(PG_FUNCTION_ARGS);
|
||||
Datum hs_concat(PG_FUNCTION_ARGS);
|
||||
Datum
|
||||
hs_concat(PG_FUNCTION_ARGS) {
|
||||
HStore *s1 = PG_GETARG_HS(0);
|
||||
HStore *s2 = PG_GETARG_HS(1);
|
||||
HStore *out = palloc( s1->len + s2->len );
|
||||
char *ps1, *ps2, *pd;
|
||||
HEntry *es1, *es2, *ed;
|
||||
hs_concat(PG_FUNCTION_ARGS)
|
||||
{
|
||||
HStore *s1 = PG_GETARG_HS(0);
|
||||
HStore *s2 = PG_GETARG_HS(1);
|
||||
HStore *out = palloc(s1->len + s2->len);
|
||||
char *ps1,
|
||||
*ps2,
|
||||
*pd;
|
||||
HEntry *es1,
|
||||
*es2,
|
||||
*ed;
|
||||
|
||||
out->len = s1->len + s2->len;
|
||||
out->size = s1->size + s2->size;
|
||||
|
||||
ps1=STRPTR(s1);
|
||||
ps2=STRPTR(s2);
|
||||
pd=STRPTR(out);
|
||||
es1=ARRPTR(s1);
|
||||
es2=ARRPTR(s2);
|
||||
ed=ARRPTR(out);
|
||||
ps1 = STRPTR(s1);
|
||||
ps2 = STRPTR(s2);
|
||||
pd = STRPTR(out);
|
||||
es1 = ARRPTR(s1);
|
||||
es2 = ARRPTR(s2);
|
||||
ed = ARRPTR(out);
|
||||
|
||||
while( es1 - ARRPTR(s1) < s1->size && es2 - ARRPTR(s2) < s2->size ) {
|
||||
int difference;
|
||||
if ( es1->keylen == es2->keylen )
|
||||
difference=strncmp(ps1, ps2, es1->keylen);
|
||||
while (es1 - ARRPTR(s1) < s1->size && es2 - ARRPTR(s2) < s2->size)
|
||||
{
|
||||
int difference;
|
||||
|
||||
if (es1->keylen == es2->keylen)
|
||||
difference = strncmp(ps1, ps2, es1->keylen);
|
||||
else
|
||||
difference=(es1->keylen > es2->keylen) ? 1 : -1;
|
||||
difference = (es1->keylen > es2->keylen) ? 1 : -1;
|
||||
|
||||
if ( difference == 0 ) {
|
||||
memcpy( ed, es2, sizeof(HEntry) );
|
||||
memcpy( pd, ps2, es2->keylen + ( (es2->valisnull) ? 0 : es2->vallen ) );
|
||||
if (difference == 0)
|
||||
{
|
||||
memcpy(ed, es2, sizeof(HEntry));
|
||||
memcpy(pd, ps2, es2->keylen + ((es2->valisnull) ? 0 : es2->vallen));
|
||||
ed->pos = pd - STRPTR(out);
|
||||
pd += es2->keylen + ( (es2->valisnull) ? 0 : es2->vallen );
|
||||
pd += es2->keylen + ((es2->valisnull) ? 0 : es2->vallen);
|
||||
ed++;
|
||||
|
||||
ps1 += es1->keylen + ( (es1->valisnull) ? 0 : es1->vallen );
|
||||
|
||||
ps1 += es1->keylen + ((es1->valisnull) ? 0 : es1->vallen);
|
||||
es1++;
|
||||
ps2 += es2->keylen + ( (es2->valisnull) ? 0 : es2->vallen );
|
||||
ps2 += es2->keylen + ((es2->valisnull) ? 0 : es2->vallen);
|
||||
es2++;
|
||||
} else if ( difference > 0 ) {
|
||||
memcpy( ed, es2, sizeof(HEntry) );
|
||||
memcpy( pd, ps2, es2->keylen + ( (es2->valisnull) ? 0 : es2->vallen ) );
|
||||
}
|
||||
else if (difference > 0)
|
||||
{
|
||||
memcpy(ed, es2, sizeof(HEntry));
|
||||
memcpy(pd, ps2, es2->keylen + ((es2->valisnull) ? 0 : es2->vallen));
|
||||
ed->pos = pd - STRPTR(out);
|
||||
pd += es2->keylen + ( (es2->valisnull) ? 0 : es2->vallen );
|
||||
pd += es2->keylen + ((es2->valisnull) ? 0 : es2->vallen);
|
||||
ed++;
|
||||
|
||||
ps2 += es2->keylen + ( (es2->valisnull) ? 0 : es2->vallen );
|
||||
|
||||
ps2 += es2->keylen + ((es2->valisnull) ? 0 : es2->vallen);
|
||||
es2++;
|
||||
} else {
|
||||
memcpy( ed, es1, sizeof(HEntry) );
|
||||
memcpy( pd, ps1, es1->keylen + ( (es1->valisnull) ? 0 : es1->vallen ) );
|
||||
}
|
||||
else
|
||||
{
|
||||
memcpy(ed, es1, sizeof(HEntry));
|
||||
memcpy(pd, ps1, es1->keylen + ((es1->valisnull) ? 0 : es1->vallen));
|
||||
ed->pos = pd - STRPTR(out);
|
||||
pd += es1->keylen + ( (es1->valisnull) ? 0 : es1->vallen );
|
||||
pd += es1->keylen + ((es1->valisnull) ? 0 : es1->vallen);
|
||||
ed++;
|
||||
|
||||
ps1 += es1->keylen + ( (es1->valisnull) ? 0 : es1->vallen );
|
||||
|
||||
ps1 += es1->keylen + ((es1->valisnull) ? 0 : es1->vallen);
|
||||
es1++;
|
||||
}
|
||||
}
|
||||
|
||||
while( es1 - ARRPTR(s1) < s1->size ) {
|
||||
memcpy( ed, es1, sizeof(HEntry) );
|
||||
memcpy( pd, ps1, es1->keylen + ( (es1->valisnull) ? 0 : es1->vallen ) );
|
||||
while (es1 - ARRPTR(s1) < s1->size)
|
||||
{
|
||||
memcpy(ed, es1, sizeof(HEntry));
|
||||
memcpy(pd, ps1, es1->keylen + ((es1->valisnull) ? 0 : es1->vallen));
|
||||
ed->pos = pd - STRPTR(out);
|
||||
pd += es1->keylen + ( (es1->valisnull) ? 0 : es1->vallen );
|
||||
pd += es1->keylen + ((es1->valisnull) ? 0 : es1->vallen);
|
||||
ed++;
|
||||
|
||||
ps1 += es1->keylen + ( (es1->valisnull) ? 0 : es1->vallen );
|
||||
|
||||
ps1 += es1->keylen + ((es1->valisnull) ? 0 : es1->vallen);
|
||||
es1++;
|
||||
}
|
||||
|
||||
while( es2 - ARRPTR(s2) < s2->size ) {
|
||||
memcpy( ed, es2, sizeof(HEntry) );
|
||||
memcpy( pd, ps2, es2->keylen + ( (es2->valisnull) ? 0 : es2->vallen ) );
|
||||
while (es2 - ARRPTR(s2) < s2->size)
|
||||
{
|
||||
memcpy(ed, es2, sizeof(HEntry));
|
||||
memcpy(pd, ps2, es2->keylen + ((es2->valisnull) ? 0 : es2->vallen));
|
||||
ed->pos = pd - STRPTR(out);
|
||||
pd += es2->keylen + ( (es2->valisnull) ? 0 : es2->vallen );
|
||||
pd += es2->keylen + ((es2->valisnull) ? 0 : es2->vallen);
|
||||
ed++;
|
||||
|
||||
ps2 += es2->keylen + ( (es2->valisnull) ? 0 : es2->vallen );
|
||||
|
||||
ps2 += es2->keylen + ((es2->valisnull) ? 0 : es2->vallen);
|
||||
es2++;
|
||||
}
|
||||
|
||||
if ( ed - ARRPTR(out) != out->size ) {
|
||||
int buflen=pd-STRPTR(out);
|
||||
if (ed - ARRPTR(out) != out->size)
|
||||
{
|
||||
int buflen = pd - STRPTR(out);
|
||||
|
||||
pd = STRPTR(out);
|
||||
|
||||
out->size = ed - ARRPTR(out);
|
||||
|
||||
memmove( STRPTR(out), pd, buflen);
|
||||
memmove(STRPTR(out), pd, buflen);
|
||||
out->len = CALCDATASIZE(out->size, buflen);
|
||||
}
|
||||
|
||||
PG_FREE_IF_COPY(s1,0);
|
||||
PG_FREE_IF_COPY(s2,1);
|
||||
|
||||
PG_FREE_IF_COPY(s1, 0);
|
||||
PG_FREE_IF_COPY(s2, 1);
|
||||
|
||||
PG_RETURN_POINTER(out);
|
||||
}
|
||||
|
||||
PG_FUNCTION_INFO_V1(tconvert);
|
||||
Datum tconvert(PG_FUNCTION_ARGS);
|
||||
Datum tconvert(PG_FUNCTION_ARGS);
|
||||
Datum
|
||||
tconvert(PG_FUNCTION_ARGS) {
|
||||
text *key = PG_GETARG_TEXT_P(0);
|
||||
text *val = PG_GETARG_TEXT_P(1);
|
||||
int len;
|
||||
HStore *out;
|
||||
tconvert(PG_FUNCTION_ARGS)
|
||||
{
|
||||
text *key = PG_GETARG_TEXT_P(0);
|
||||
text *val = PG_GETARG_TEXT_P(1);
|
||||
int len;
|
||||
HStore *out;
|
||||
|
||||
len=CALCDATASIZE(1, VARSIZE(key) + VARSIZE(val) - 2*VARHDRSZ);
|
||||
len = CALCDATASIZE(1, VARSIZE(key) + VARSIZE(val) - 2 * VARHDRSZ);
|
||||
out = palloc(len);
|
||||
out->len=len;
|
||||
out->size=1;
|
||||
out->len = len;
|
||||
out->size = 1;
|
||||
|
||||
ARRPTR(out)->keylen = VARSIZE(key) - VARHDRSZ;
|
||||
ARRPTR(out)->vallen = VARSIZE(val) - VARHDRSZ;
|
||||
ARRPTR(out)->valisnull = false;
|
||||
ARRPTR(out)->pos=0;
|
||||
ARRPTR(out)->pos = 0;
|
||||
|
||||
memcpy( STRPTR(out), VARDATA(key), ARRPTR(out)->keylen );
|
||||
memcpy( STRPTR(out) + ARRPTR(out)->keylen, VARDATA(val), ARRPTR(out)->vallen );
|
||||
|
||||
PG_FREE_IF_COPY(key,0);
|
||||
PG_FREE_IF_COPY(val,1);
|
||||
memcpy(STRPTR(out), VARDATA(key), ARRPTR(out)->keylen);
|
||||
memcpy(STRPTR(out) + ARRPTR(out)->keylen, VARDATA(val), ARRPTR(out)->vallen);
|
||||
|
||||
PG_FREE_IF_COPY(key, 0);
|
||||
PG_FREE_IF_COPY(val, 1);
|
||||
|
||||
PG_RETURN_POINTER(out);
|
||||
}
|
||||
|
||||
PG_FUNCTION_INFO_V1(akeys);
|
||||
Datum akeys(PG_FUNCTION_ARGS);
|
||||
Datum akeys(PG_FUNCTION_ARGS);
|
||||
Datum
|
||||
akeys(PG_FUNCTION_ARGS) {
|
||||
HStore *hs = PG_GETARG_HS(0);
|
||||
Datum *d;
|
||||
ArrayType *a;
|
||||
HEntry *ptr=ARRPTR(hs);
|
||||
char *base=STRPTR(hs);
|
||||
akeys(PG_FUNCTION_ARGS)
|
||||
{
|
||||
HStore *hs = PG_GETARG_HS(0);
|
||||
Datum *d;
|
||||
ArrayType *a;
|
||||
HEntry *ptr = ARRPTR(hs);
|
||||
char *base = STRPTR(hs);
|
||||
|
||||
d=(Datum*)palloc(sizeof(Datum)*(hs->size+1));
|
||||
while( ptr-ARRPTR(hs) < hs->size ) {
|
||||
text *item=(text*)palloc(VARHDRSZ + ptr->keylen);
|
||||
VARATT_SIZEP(item) = VARHDRSZ+ptr->keylen;
|
||||
d = (Datum *) palloc(sizeof(Datum) * (hs->size + 1));
|
||||
while (ptr - ARRPTR(hs) < hs->size)
|
||||
{
|
||||
text *item = (text *) palloc(VARHDRSZ + ptr->keylen);
|
||||
|
||||
VARATT_SIZEP(item) = VARHDRSZ + ptr->keylen;
|
||||
memcpy(VARDATA(item), base + ptr->pos, ptr->keylen);
|
||||
d[ ptr-ARRPTR(hs) ] = PointerGetDatum(item);
|
||||
d[ptr - ARRPTR(hs)] = PointerGetDatum(item);
|
||||
ptr++;
|
||||
}
|
||||
|
||||
a = construct_array(
|
||||
d,
|
||||
hs->size,
|
||||
TEXTOID,
|
||||
-1,
|
||||
false,
|
||||
'i'
|
||||
);
|
||||
|
||||
ptr=ARRPTR(hs);
|
||||
while( ptr-ARRPTR(hs) < hs->size ) {
|
||||
pfree(DatumGetPointer(d[ ptr-ARRPTR(hs) ]));
|
||||
a = construct_array(
|
||||
d,
|
||||
hs->size,
|
||||
TEXTOID,
|
||||
-1,
|
||||
false,
|
||||
'i'
|
||||
);
|
||||
|
||||
ptr = ARRPTR(hs);
|
||||
while (ptr - ARRPTR(hs) < hs->size)
|
||||
{
|
||||
pfree(DatumGetPointer(d[ptr - ARRPTR(hs)]));
|
||||
ptr++;
|
||||
}
|
||||
|
||||
pfree(d);
|
||||
PG_FREE_IF_COPY(hs,0);
|
||||
PG_FREE_IF_COPY(hs, 0);
|
||||
|
||||
PG_RETURN_POINTER(a);
|
||||
}
|
||||
|
||||
PG_FUNCTION_INFO_V1(avals);
|
||||
Datum avals(PG_FUNCTION_ARGS);
|
||||
Datum avals(PG_FUNCTION_ARGS);
|
||||
Datum
|
||||
avals(PG_FUNCTION_ARGS) {
|
||||
HStore *hs = PG_GETARG_HS(0);
|
||||
Datum *d;
|
||||
ArrayType *a;
|
||||
HEntry *ptr=ARRPTR(hs);
|
||||
char *base=STRPTR(hs);
|
||||
avals(PG_FUNCTION_ARGS)
|
||||
{
|
||||
HStore *hs = PG_GETARG_HS(0);
|
||||
Datum *d;
|
||||
ArrayType *a;
|
||||
HEntry *ptr = ARRPTR(hs);
|
||||
char *base = STRPTR(hs);
|
||||
|
||||
d=(Datum*)palloc(sizeof(Datum)*(hs->size+1));
|
||||
while( ptr-ARRPTR(hs) < hs->size ) {
|
||||
int vallen = (ptr->valisnull) ? 0 : ptr->vallen;
|
||||
text *item=(text*)palloc(VARHDRSZ + vallen);
|
||||
VARATT_SIZEP(item) = VARHDRSZ+vallen;
|
||||
d = (Datum *) palloc(sizeof(Datum) * (hs->size + 1));
|
||||
while (ptr - ARRPTR(hs) < hs->size)
|
||||
{
|
||||
int vallen = (ptr->valisnull) ? 0 : ptr->vallen;
|
||||
text *item = (text *) palloc(VARHDRSZ + vallen);
|
||||
|
||||
VARATT_SIZEP(item) = VARHDRSZ + vallen;
|
||||
memcpy(VARDATA(item), base + ptr->pos + ptr->keylen, vallen);
|
||||
d[ ptr-ARRPTR(hs) ] = PointerGetDatum(item);
|
||||
d[ptr - ARRPTR(hs)] = PointerGetDatum(item);
|
||||
ptr++;
|
||||
}
|
||||
|
||||
a = construct_array(
|
||||
d,
|
||||
hs->size,
|
||||
TEXTOID,
|
||||
-1,
|
||||
false,
|
||||
'i'
|
||||
);
|
||||
|
||||
ptr=ARRPTR(hs);
|
||||
while( ptr-ARRPTR(hs) < hs->size ) {
|
||||
pfree(DatumGetPointer(d[ ptr-ARRPTR(hs) ]));
|
||||
a = construct_array(
|
||||
d,
|
||||
hs->size,
|
||||
TEXTOID,
|
||||
-1,
|
||||
false,
|
||||
'i'
|
||||
);
|
||||
|
||||
ptr = ARRPTR(hs);
|
||||
while (ptr - ARRPTR(hs) < hs->size)
|
||||
{
|
||||
pfree(DatumGetPointer(d[ptr - ARRPTR(hs)]));
|
||||
ptr++;
|
||||
}
|
||||
|
||||
pfree(d);
|
||||
PG_FREE_IF_COPY(hs,0);
|
||||
PG_FREE_IF_COPY(hs, 0);
|
||||
|
||||
PG_RETURN_POINTER(a);
|
||||
}
|
||||
|
||||
typedef struct {
|
||||
HStore *hs;
|
||||
int i;
|
||||
} AKStore;
|
||||
typedef struct
|
||||
{
|
||||
HStore *hs;
|
||||
int i;
|
||||
} AKStore;
|
||||
|
||||
static void
|
||||
setup_firstcall(FuncCallContext *funcctx, HStore *hs) {
|
||||
MemoryContext oldcontext;
|
||||
AKStore *st;
|
||||
setup_firstcall(FuncCallContext *funcctx, HStore * hs)
|
||||
{
|
||||
MemoryContext oldcontext;
|
||||
AKStore *st;
|
||||
|
||||
oldcontext = MemoryContextSwitchTo(funcctx->multi_call_memory_ctx);
|
||||
|
||||
st=(AKStore*)palloc( sizeof(AKStore) );
|
||||
st->i=0;
|
||||
st->hs = (HStore*)palloc(hs->len);
|
||||
memcpy( st->hs, hs, hs->len );
|
||||
st = (AKStore *) palloc(sizeof(AKStore));
|
||||
st->i = 0;
|
||||
st->hs = (HStore *) palloc(hs->len);
|
||||
memcpy(st->hs, hs, hs->len);
|
||||
|
||||
funcctx->user_fctx = (void*)st;
|
||||
funcctx->user_fctx = (void *) st;
|
||||
MemoryContextSwitchTo(oldcontext);
|
||||
}
|
||||
|
||||
PG_FUNCTION_INFO_V1(skeys);
|
||||
Datum skeys(PG_FUNCTION_ARGS);
|
||||
Datum skeys(PG_FUNCTION_ARGS);
|
||||
Datum
|
||||
skeys(PG_FUNCTION_ARGS) {
|
||||
FuncCallContext *funcctx;
|
||||
AKStore *st;
|
||||
skeys(PG_FUNCTION_ARGS)
|
||||
{
|
||||
FuncCallContext *funcctx;
|
||||
AKStore *st;
|
||||
|
||||
if (SRF_IS_FIRSTCALL())
|
||||
{
|
||||
HStore *hs = PG_GETARG_HS(0);
|
||||
|
||||
if (SRF_IS_FIRSTCALL()) {
|
||||
HStore *hs = PG_GETARG_HS(0);
|
||||
funcctx = SRF_FIRSTCALL_INIT();
|
||||
setup_firstcall(funcctx, hs);
|
||||
PG_FREE_IF_COPY(hs,0);
|
||||
PG_FREE_IF_COPY(hs, 0);
|
||||
}
|
||||
|
||||
funcctx = SRF_PERCALL_SETUP();
|
||||
st = (AKStore*)funcctx->user_fctx;
|
||||
|
||||
if ( st->i < st->hs->size ) {
|
||||
HEntry *ptr = &(ARRPTR(st->hs)[st->i]);
|
||||
text *item=(text*)palloc(VARHDRSZ + ptr->keylen);
|
||||
st = (AKStore *) funcctx->user_fctx;
|
||||
|
||||
VARATT_SIZEP(item) = VARHDRSZ+ptr->keylen;
|
||||
if (st->i < st->hs->size)
|
||||
{
|
||||
HEntry *ptr = &(ARRPTR(st->hs)[st->i]);
|
||||
text *item = (text *) palloc(VARHDRSZ + ptr->keylen);
|
||||
|
||||
VARATT_SIZEP(item) = VARHDRSZ + ptr->keylen;
|
||||
memcpy(VARDATA(item), STRPTR(st->hs) + ptr->pos, ptr->keylen);
|
||||
st->i++;
|
||||
|
||||
SRF_RETURN_NEXT(funcctx, PointerGetDatum(item));
|
||||
}
|
||||
|
||||
pfree( st->hs );
|
||||
pfree( st );
|
||||
|
||||
SRF_RETURN_DONE(funcctx);
|
||||
pfree(st->hs);
|
||||
pfree(st);
|
||||
|
||||
SRF_RETURN_DONE(funcctx);
|
||||
}
|
||||
|
||||
PG_FUNCTION_INFO_V1(svals);
|
||||
Datum svals(PG_FUNCTION_ARGS);
|
||||
Datum svals(PG_FUNCTION_ARGS);
|
||||
Datum
|
||||
svals(PG_FUNCTION_ARGS) {
|
||||
FuncCallContext *funcctx;
|
||||
AKStore *st;
|
||||
svals(PG_FUNCTION_ARGS)
|
||||
{
|
||||
FuncCallContext *funcctx;
|
||||
AKStore *st;
|
||||
|
||||
if (SRF_IS_FIRSTCALL())
|
||||
{
|
||||
HStore *hs = PG_GETARG_HS(0);
|
||||
|
||||
if (SRF_IS_FIRSTCALL()) {
|
||||
HStore *hs = PG_GETARG_HS(0);
|
||||
funcctx = SRF_FIRSTCALL_INIT();
|
||||
setup_firstcall(funcctx, hs);
|
||||
PG_FREE_IF_COPY(hs,0);
|
||||
PG_FREE_IF_COPY(hs, 0);
|
||||
}
|
||||
|
||||
funcctx = SRF_PERCALL_SETUP();
|
||||
st = (AKStore*)funcctx->user_fctx;
|
||||
|
||||
if ( st->i < st->hs->size ) {
|
||||
HEntry *ptr = &(ARRPTR(st->hs)[st->i]);
|
||||
st = (AKStore *) funcctx->user_fctx;
|
||||
|
||||
if ( ptr->valisnull ) {
|
||||
ReturnSetInfo *rsi;
|
||||
if (st->i < st->hs->size)
|
||||
{
|
||||
HEntry *ptr = &(ARRPTR(st->hs)[st->i]);
|
||||
|
||||
if (ptr->valisnull)
|
||||
{
|
||||
ReturnSetInfo *rsi;
|
||||
|
||||
st->i++;
|
||||
(funcctx)->call_cntr++;
|
||||
rsi = (ReturnSetInfo *) fcinfo->resultinfo;
|
||||
rsi->isDone = ExprMultipleResult;
|
||||
PG_RETURN_NULL();
|
||||
} else {
|
||||
int vallen = ptr->vallen;
|
||||
text *item=(text*)palloc(VARHDRSZ + vallen);
|
||||
}
|
||||
else
|
||||
{
|
||||
int vallen = ptr->vallen;
|
||||
text *item = (text *) palloc(VARHDRSZ + vallen);
|
||||
|
||||
VARATT_SIZEP(item) = VARHDRSZ+vallen;
|
||||
VARATT_SIZEP(item) = VARHDRSZ + vallen;
|
||||
memcpy(VARDATA(item), STRPTR(st->hs) + ptr->pos + ptr->keylen, vallen);
|
||||
st->i++;
|
||||
|
||||
SRF_RETURN_NEXT(funcctx, PointerGetDatum(item));
|
||||
}
|
||||
}
|
||||
|
||||
pfree( st->hs );
|
||||
pfree( st );
|
||||
|
||||
SRF_RETURN_DONE(funcctx);
|
||||
pfree(st->hs);
|
||||
pfree(st);
|
||||
|
||||
SRF_RETURN_DONE(funcctx);
|
||||
}
|
||||
|
||||
PG_FUNCTION_INFO_V1(hs_contains);
|
||||
Datum hs_contains(PG_FUNCTION_ARGS);
|
||||
Datum hs_contains(PG_FUNCTION_ARGS);
|
||||
Datum
|
||||
hs_contains(PG_FUNCTION_ARGS) {
|
||||
HStore *val = PG_GETARG_HS(0);
|
||||
HStore *tmpl = PG_GETARG_HS(1);
|
||||
bool res = true;
|
||||
HEntry *te = ARRPTR(tmpl);
|
||||
char *vv = STRPTR(val);
|
||||
char *tv = STRPTR(tmpl);
|
||||
hs_contains(PG_FUNCTION_ARGS)
|
||||
{
|
||||
HStore *val = PG_GETARG_HS(0);
|
||||
HStore *tmpl = PG_GETARG_HS(1);
|
||||
bool res = true;
|
||||
HEntry *te = ARRPTR(tmpl);
|
||||
char *vv = STRPTR(val);
|
||||
char *tv = STRPTR(tmpl);
|
||||
|
||||
while(res && te-ARRPTR(tmpl) < tmpl->size) {
|
||||
HEntry *entry = findkey(val, tv + te->pos, te->keylen);
|
||||
if ( entry ) {
|
||||
if ( ! te->valisnull ) {
|
||||
if ( entry->valisnull || !(
|
||||
te->vallen==entry->vallen &&
|
||||
strncmp(
|
||||
vv + entry->pos + entry->keylen,
|
||||
tv + te->pos + te->keylen,
|
||||
te->vallen ) == 0
|
||||
) )
|
||||
res=false;
|
||||
while (res && te - ARRPTR(tmpl) < tmpl->size)
|
||||
{
|
||||
HEntry *entry = findkey(val, tv + te->pos, te->keylen);
|
||||
|
||||
if (entry)
|
||||
{
|
||||
if (!te->valisnull)
|
||||
{
|
||||
if (entry->valisnull || !(
|
||||
te->vallen == entry->vallen &&
|
||||
strncmp(
|
||||
vv + entry->pos + entry->keylen,
|
||||
tv + te->pos + te->keylen,
|
||||
te->vallen) == 0
|
||||
))
|
||||
res = false;
|
||||
}
|
||||
} else
|
||||
}
|
||||
else
|
||||
res = false;
|
||||
te++;
|
||||
}
|
||||
|
||||
PG_FREE_IF_COPY(val,0);
|
||||
PG_FREE_IF_COPY(tmpl,1);
|
||||
PG_FREE_IF_COPY(val, 0);
|
||||
PG_FREE_IF_COPY(tmpl, 1);
|
||||
|
||||
PG_RETURN_BOOL(res);
|
||||
}
|
||||
|
||||
|
||||
PG_FUNCTION_INFO_V1(hs_contained);
|
||||
Datum hs_contained(PG_FUNCTION_ARGS);
|
||||
Datum hs_contained(PG_FUNCTION_ARGS);
|
||||
Datum
|
||||
hs_contained(PG_FUNCTION_ARGS) {
|
||||
PG_RETURN_DATUM( DirectFunctionCall2(
|
||||
hs_contains,
|
||||
PG_GETARG_DATUM(1),
|
||||
PG_GETARG_DATUM(0)
|
||||
));
|
||||
hs_contained(PG_FUNCTION_ARGS)
|
||||
{
|
||||
PG_RETURN_DATUM(DirectFunctionCall2(
|
||||
hs_contains,
|
||||
PG_GETARG_DATUM(1),
|
||||
PG_GETARG_DATUM(0)
|
||||
));
|
||||
}
|
||||
|
||||
PG_FUNCTION_INFO_V1(each);
|
||||
Datum each(PG_FUNCTION_ARGS);
|
||||
Datum each(PG_FUNCTION_ARGS);
|
||||
Datum
|
||||
each(PG_FUNCTION_ARGS) {
|
||||
FuncCallContext *funcctx;
|
||||
AKStore *st;
|
||||
each(PG_FUNCTION_ARGS)
|
||||
{
|
||||
FuncCallContext *funcctx;
|
||||
AKStore *st;
|
||||
|
||||
if (SRF_IS_FIRSTCALL()) {
|
||||
TupleDesc tupdesc;
|
||||
MemoryContext oldcontext;
|
||||
HStore *hs = PG_GETARG_HS(0);
|
||||
if (SRF_IS_FIRSTCALL())
|
||||
{
|
||||
TupleDesc tupdesc;
|
||||
MemoryContext oldcontext;
|
||||
HStore *hs = PG_GETARG_HS(0);
|
||||
|
||||
funcctx = SRF_FIRSTCALL_INIT();
|
||||
oldcontext = MemoryContextSwitchTo(funcctx->multi_call_memory_ctx);
|
||||
st=(AKStore*)palloc( sizeof(AKStore) );
|
||||
st->i=0;
|
||||
st->hs = (HStore*)palloc(hs->len);
|
||||
memcpy( st->hs, hs, hs->len );
|
||||
funcctx->user_fctx = (void*)st;
|
||||
|
||||
st = (AKStore *) palloc(sizeof(AKStore));
|
||||
st->i = 0;
|
||||
st->hs = (HStore *) palloc(hs->len);
|
||||
memcpy(st->hs, hs, hs->len);
|
||||
funcctx->user_fctx = (void *) st;
|
||||
|
||||
tupdesc = RelationNameGetTupleDesc("hs_each");
|
||||
funcctx->slot = TupleDescGetSlot(tupdesc);
|
||||
funcctx->attinmeta = TupleDescGetAttInMetadata(tupdesc);
|
||||
|
||||
MemoryContextSwitchTo(oldcontext);
|
||||
PG_FREE_IF_COPY(hs,0);
|
||||
PG_FREE_IF_COPY(hs, 0);
|
||||
}
|
||||
|
||||
funcctx = SRF_PERCALL_SETUP();
|
||||
st = (AKStore*)funcctx->user_fctx;
|
||||
|
||||
if ( st->i < st->hs->size ) {
|
||||
HEntry *ptr = &(ARRPTR(st->hs)[st->i]);
|
||||
Datum res, dvalues[2];
|
||||
char nulls[] = {' ', ' '};
|
||||
text *item;
|
||||
HeapTuple tuple;
|
||||
st = (AKStore *) funcctx->user_fctx;
|
||||
|
||||
item=(text*)palloc(VARHDRSZ + ptr->keylen);
|
||||
VARATT_SIZEP(item) = VARHDRSZ+ptr->keylen;
|
||||
if (st->i < st->hs->size)
|
||||
{
|
||||
HEntry *ptr = &(ARRPTR(st->hs)[st->i]);
|
||||
Datum res,
|
||||
dvalues[2];
|
||||
char nulls[] = {' ', ' '};
|
||||
text *item;
|
||||
HeapTuple tuple;
|
||||
|
||||
item = (text *) palloc(VARHDRSZ + ptr->keylen);
|
||||
VARATT_SIZEP(item) = VARHDRSZ + ptr->keylen;
|
||||
memcpy(VARDATA(item), STRPTR(st->hs) + ptr->pos, ptr->keylen);
|
||||
dvalues[0] = PointerGetDatum(item);
|
||||
|
||||
if ( ptr->valisnull ) {
|
||||
dvalues[1]=(Datum)0;
|
||||
nulls[1]='n';
|
||||
} else {
|
||||
int vallen = ptr->vallen;
|
||||
if (ptr->valisnull)
|
||||
{
|
||||
dvalues[1] = (Datum) 0;
|
||||
nulls[1] = 'n';
|
||||
}
|
||||
else
|
||||
{
|
||||
int vallen = ptr->vallen;
|
||||
|
||||
item=(text*)palloc(VARHDRSZ + vallen);
|
||||
VARATT_SIZEP(item) = VARHDRSZ+vallen;
|
||||
item = (text *) palloc(VARHDRSZ + vallen);
|
||||
VARATT_SIZEP(item) = VARHDRSZ + vallen;
|
||||
memcpy(VARDATA(item), STRPTR(st->hs) + ptr->pos + ptr->keylen, vallen);
|
||||
dvalues[1] = PointerGetDatum(item);
|
||||
}
|
||||
@ -551,17 +616,15 @@ each(PG_FUNCTION_ARGS) {
|
||||
tuple = heap_formtuple(funcctx->attinmeta->tupdesc, dvalues, nulls);
|
||||
res = TupleGetDatum(funcctx->slot, tuple);
|
||||
|
||||
pfree( DatumGetPointer(dvalues[0]) );
|
||||
if ( nulls[1] != 'n' )
|
||||
pfree( DatumGetPointer(dvalues[1]) );
|
||||
pfree(DatumGetPointer(dvalues[0]));
|
||||
if (nulls[1] != 'n')
|
||||
pfree(DatumGetPointer(dvalues[1]));
|
||||
|
||||
SRF_RETURN_NEXT(funcctx, PointerGetDatum(res));
|
||||
}
|
||||
|
||||
pfree( st->hs );
|
||||
pfree( st );
|
||||
|
||||
SRF_RETURN_DONE(funcctx);
|
||||
pfree(st->hs);
|
||||
pfree(st);
|
||||
|
||||
SRF_RETURN_DONE(funcctx);
|
||||
}
|
||||
|
||||
|
||||
|
@ -154,17 +154,17 @@ typedef struct
|
||||
#define COMPUTESIZE(size) ( HDRSIZEQT + size * sizeof(ITEM) )
|
||||
#define GETQUERY(x) (ITEM*)( (char*)(x)+HDRSIZEQT )
|
||||
|
||||
#define END 0
|
||||
#define ERR 1
|
||||
#define VAL 2
|
||||
#define OPR 3
|
||||
#define OPEN 4
|
||||
#define CLOSE 5
|
||||
#define END 0
|
||||
#define ERR 1
|
||||
#define VAL 2
|
||||
#define OPR 3
|
||||
#define OPEN 4
|
||||
#define CLOSE 5
|
||||
|
||||
bool signconsistent(QUERYTYPE * query, BITVEC sign, bool calcnot);
|
||||
bool execconsistent(QUERYTYPE * query, ArrayType *array, bool calcnot);
|
||||
bool ginconsistent(QUERYTYPE * query, bool *check);
|
||||
int4 shorterquery(ITEM * q, int4 len);
|
||||
bool ginconsistent(QUERYTYPE * query, bool *check);
|
||||
int4 shorterquery(ITEM * q, int4 len);
|
||||
|
||||
int compASC(const void *a, const void *b);
|
||||
|
||||
|
@ -232,7 +232,7 @@ typedef struct
|
||||
* is there value 'val' in array or not ?
|
||||
*/
|
||||
static bool
|
||||
checkcondition_arr(void *checkval, ITEM *item)
|
||||
checkcondition_arr(void *checkval, ITEM * item)
|
||||
{
|
||||
int4 *StopLow = ((CHKVAL *) checkval)->arrb;
|
||||
int4 *StopHigh = ((CHKVAL *) checkval)->arre;
|
||||
@ -254,7 +254,7 @@ checkcondition_arr(void *checkval, ITEM *item)
|
||||
}
|
||||
|
||||
static bool
|
||||
checkcondition_bit(void *checkval, ITEM *item)
|
||||
checkcondition_bit(void *checkval, ITEM * item)
|
||||
{
|
||||
return GETBIT(checkval, HASHVAL(item->val));
|
||||
}
|
||||
@ -263,7 +263,7 @@ checkcondition_bit(void *checkval, ITEM *item)
|
||||
* check for boolean condition
|
||||
*/
|
||||
static bool
|
||||
execute(ITEM * curitem, void *checkval, bool calcnot, bool (*chkcond) (void *checkval, ITEM *item))
|
||||
execute(ITEM * curitem, void *checkval, bool calcnot, bool (*chkcond) (void *checkval, ITEM * item))
|
||||
{
|
||||
|
||||
if (curitem->type == VAL)
|
||||
@ -319,38 +319,42 @@ execconsistent(QUERYTYPE * query, ArrayType *array, bool calcnot)
|
||||
);
|
||||
}
|
||||
|
||||
typedef struct {
|
||||
ITEM *first;
|
||||
bool *mapped_check;
|
||||
} GinChkVal;
|
||||
typedef struct
|
||||
{
|
||||
ITEM *first;
|
||||
bool *mapped_check;
|
||||
} GinChkVal;
|
||||
|
||||
static bool
|
||||
checkcondition_gin(void *checkval, ITEM *item) {
|
||||
GinChkVal *gcv = (GinChkVal*)checkval;
|
||||
checkcondition_gin(void *checkval, ITEM * item)
|
||||
{
|
||||
GinChkVal *gcv = (GinChkVal *) checkval;
|
||||
|
||||
return gcv->mapped_check[ item - gcv->first ];
|
||||
return gcv->mapped_check[item - gcv->first];
|
||||
}
|
||||
|
||||
bool
|
||||
ginconsistent(QUERYTYPE * query, bool *check) {
|
||||
GinChkVal gcv;
|
||||
ITEM *items = GETQUERY(query);
|
||||
int i, j=0;
|
||||
ginconsistent(QUERYTYPE * query, bool *check)
|
||||
{
|
||||
GinChkVal gcv;
|
||||
ITEM *items = GETQUERY(query);
|
||||
int i,
|
||||
j = 0;
|
||||
|
||||
if ( query->size < 0 )
|
||||
if (query->size < 0)
|
||||
return FALSE;
|
||||
|
||||
gcv.first = items;
|
||||
gcv.mapped_check = (bool*)palloc( sizeof(bool)*query->size );
|
||||
for(i=0; i<query->size; i++)
|
||||
if ( items[i].type == VAL )
|
||||
gcv.mapped_check[ i ] = check[ j++ ];
|
||||
gcv.mapped_check = (bool *) palloc(sizeof(bool) * query->size);
|
||||
for (i = 0; i < query->size; i++)
|
||||
if (items[i].type == VAL)
|
||||
gcv.mapped_check[i] = check[j++];
|
||||
|
||||
return execute(
|
||||
GETQUERY(query) + query->size - 1,
|
||||
(void *) &gcv, true,
|
||||
checkcondition_gin
|
||||
);
|
||||
return execute(
|
||||
GETQUERY(query) + query->size - 1,
|
||||
(void *) &gcv, true,
|
||||
checkcondition_gin
|
||||
);
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -1,102 +1,118 @@
|
||||
#include "_int.h"
|
||||
|
||||
PG_FUNCTION_INFO_V1(ginint4_queryextract);
|
||||
Datum ginint4_queryextract(PG_FUNCTION_ARGS);
|
||||
Datum ginint4_queryextract(PG_FUNCTION_ARGS);
|
||||
|
||||
Datum
|
||||
ginint4_queryextract(PG_FUNCTION_ARGS) {
|
||||
uint32 *nentries = (uint32*)PG_GETARG_POINTER(1);
|
||||
StrategyNumber strategy = PG_GETARG_UINT16(2);
|
||||
Datum *res = NULL;
|
||||
|
||||
ginint4_queryextract(PG_FUNCTION_ARGS)
|
||||
{
|
||||
uint32 *nentries = (uint32 *) PG_GETARG_POINTER(1);
|
||||
StrategyNumber strategy = PG_GETARG_UINT16(2);
|
||||
Datum *res = NULL;
|
||||
|
||||
*nentries = 0;
|
||||
|
||||
if ( strategy == BooleanSearchStrategy ) {
|
||||
QUERYTYPE *query = (QUERYTYPE*)PG_DETOAST_DATUM_COPY(PG_GETARG_POINTER(0));
|
||||
ITEM *items = GETQUERY(query);
|
||||
int i;
|
||||
if (strategy == BooleanSearchStrategy)
|
||||
{
|
||||
QUERYTYPE *query = (QUERYTYPE *) PG_DETOAST_DATUM_COPY(PG_GETARG_POINTER(0));
|
||||
ITEM *items = GETQUERY(query);
|
||||
int i;
|
||||
|
||||
if (query->size == 0)
|
||||
PG_RETURN_POINTER(NULL);
|
||||
|
||||
if ( shorterquery(items, query->size) == 0 )
|
||||
elog(ERROR,"Query requires full scan, GIN doesn't support it");
|
||||
if (shorterquery(items, query->size) == 0)
|
||||
elog(ERROR, "Query requires full scan, GIN doesn't support it");
|
||||
|
||||
pfree( query );
|
||||
pfree(query);
|
||||
|
||||
query = (QUERYTYPE*)PG_DETOAST_DATUM(PG_GETARG_POINTER(0));
|
||||
query = (QUERYTYPE *) PG_DETOAST_DATUM(PG_GETARG_POINTER(0));
|
||||
items = GETQUERY(query);
|
||||
|
||||
res = (Datum*)palloc(sizeof(Datum) * query->size);
|
||||
res = (Datum *) palloc(sizeof(Datum) * query->size);
|
||||
*nentries = 0;
|
||||
|
||||
for(i=0;i<query->size;i++)
|
||||
if ( items[i].type == VAL ) {
|
||||
res[*nentries] = Int32GetDatum( items[i].val );
|
||||
for (i = 0; i < query->size; i++)
|
||||
if (items[i].type == VAL)
|
||||
{
|
||||
res[*nentries] = Int32GetDatum(items[i].val);
|
||||
(*nentries)++;
|
||||
}
|
||||
} else {
|
||||
ArrayType *query = PG_GETARG_ARRAYTYPE_P(0);
|
||||
int4 *arr;
|
||||
uint32 i;
|
||||
}
|
||||
else
|
||||
{
|
||||
ArrayType *query = PG_GETARG_ARRAYTYPE_P(0);
|
||||
int4 *arr;
|
||||
uint32 i;
|
||||
|
||||
CHECKARRVALID(query);
|
||||
*nentries=ARRNELEMS(query);
|
||||
if ( *nentries > 0 ) {
|
||||
res = (Datum*)palloc(sizeof(Datum) * (*nentries));
|
||||
*nentries = ARRNELEMS(query);
|
||||
if (*nentries > 0)
|
||||
{
|
||||
res = (Datum *) palloc(sizeof(Datum) * (*nentries));
|
||||
|
||||
arr=ARRPTR(query);
|
||||
for(i=0;i<*nentries;i++)
|
||||
res[i] = Int32GetDatum( arr[i] );
|
||||
arr = ARRPTR(query);
|
||||
for (i = 0; i < *nentries; i++)
|
||||
res[i] = Int32GetDatum(arr[i]);
|
||||
}
|
||||
}
|
||||
|
||||
PG_RETURN_POINTER( res );
|
||||
PG_RETURN_POINTER(res);
|
||||
}
|
||||
|
||||
PG_FUNCTION_INFO_V1(ginint4_consistent);
|
||||
Datum ginint4_consistent(PG_FUNCTION_ARGS);
|
||||
Datum ginint4_consistent(PG_FUNCTION_ARGS);
|
||||
|
||||
Datum
|
||||
ginint4_consistent(PG_FUNCTION_ARGS) {
|
||||
bool *check = (bool*)PG_GETARG_POINTER(0);
|
||||
StrategyNumber strategy = PG_GETARG_UINT16(1);
|
||||
int res=FALSE;
|
||||
ginint4_consistent(PG_FUNCTION_ARGS)
|
||||
{
|
||||
bool *check = (bool *) PG_GETARG_POINTER(0);
|
||||
StrategyNumber strategy = PG_GETARG_UINT16(1);
|
||||
int res = FALSE;
|
||||
|
||||
/* we can do not check array carefully, it's done by previous ginarrayextract call */
|
||||
/*
|
||||
* we can do not check array carefully, it's done by previous
|
||||
* ginarrayextract call
|
||||
*/
|
||||
|
||||
switch( strategy ) {
|
||||
case RTOverlapStrategyNumber:
|
||||
case RTContainedByStrategyNumber:
|
||||
case RTOldContainedByStrategyNumber:
|
||||
/* at least one element in check[] is true, so result = true */
|
||||
switch (strategy)
|
||||
{
|
||||
case RTOverlapStrategyNumber:
|
||||
case RTContainedByStrategyNumber:
|
||||
case RTOldContainedByStrategyNumber:
|
||||
/* at least one element in check[] is true, so result = true */
|
||||
|
||||
res = TRUE;
|
||||
break;
|
||||
case RTSameStrategyNumber:
|
||||
case RTContainsStrategyNumber:
|
||||
case RTOldContainsStrategyNumber:
|
||||
res = TRUE;
|
||||
do {
|
||||
ArrayType *query = PG_GETARG_ARRAYTYPE_P(2);
|
||||
int i, nentries=ARRNELEMS(query);
|
||||
|
||||
for(i=0;i<nentries;i++)
|
||||
if ( !check[i] ) {
|
||||
res = FALSE;
|
||||
break;
|
||||
}
|
||||
} while(0);
|
||||
break;
|
||||
case BooleanSearchStrategy:
|
||||
do {
|
||||
QUERYTYPE *query = (QUERYTYPE*)PG_DETOAST_DATUM(PG_GETARG_POINTER(2));
|
||||
res = ginconsistent( query, check );
|
||||
} while(0);
|
||||
res = TRUE;
|
||||
break;
|
||||
default:
|
||||
elog(ERROR, "ginint4_consistent: unknown strategy number: %d", strategy);
|
||||
}
|
||||
case RTSameStrategyNumber:
|
||||
case RTContainsStrategyNumber:
|
||||
case RTOldContainsStrategyNumber:
|
||||
res = TRUE;
|
||||
do
|
||||
{
|
||||
ArrayType *query = PG_GETARG_ARRAYTYPE_P(2);
|
||||
int i,
|
||||
nentries = ARRNELEMS(query);
|
||||
|
||||
PG_RETURN_BOOL(res);
|
||||
for (i = 0; i < nentries; i++)
|
||||
if (!check[i])
|
||||
{
|
||||
res = FALSE;
|
||||
break;
|
||||
}
|
||||
} while (0);
|
||||
break;
|
||||
case BooleanSearchStrategy:
|
||||
do
|
||||
{
|
||||
QUERYTYPE *query = (QUERYTYPE *) PG_DETOAST_DATUM(PG_GETARG_POINTER(2));
|
||||
|
||||
res = ginconsistent(query, check);
|
||||
} while (0);
|
||||
break;
|
||||
default:
|
||||
elog(ERROR, "ginint4_consistent: unknown strategy number: %d", strategy);
|
||||
}
|
||||
|
||||
PG_RETURN_BOOL(res);
|
||||
}
|
||||
|
@ -36,19 +36,21 @@ g_int_consistent(PG_FUNCTION_ARGS)
|
||||
StrategyNumber strategy = (StrategyNumber) PG_GETARG_UINT16(2);
|
||||
bool retval;
|
||||
|
||||
if (strategy == BooleanSearchStrategy) {
|
||||
if (strategy == BooleanSearchStrategy)
|
||||
{
|
||||
retval = execconsistent((QUERYTYPE *) query,
|
||||
(ArrayType *) DatumGetPointer(entry->key),
|
||||
GIST_LEAF(entry));
|
||||
(ArrayType *) DatumGetPointer(entry->key),
|
||||
GIST_LEAF(entry));
|
||||
|
||||
pfree( query );
|
||||
pfree(query);
|
||||
PG_RETURN_BOOL(retval);
|
||||
}
|
||||
|
||||
/* sort query for fast search, key is already sorted */
|
||||
CHECKARRVALID(query);
|
||||
if (ARRISVOID(query)) {
|
||||
pfree( query );
|
||||
if (ARRISVOID(query))
|
||||
{
|
||||
pfree(query);
|
||||
PG_RETURN_BOOL(false);
|
||||
}
|
||||
PREPAREARR(query);
|
||||
@ -88,7 +90,7 @@ g_int_consistent(PG_FUNCTION_ARGS)
|
||||
default:
|
||||
retval = FALSE;
|
||||
}
|
||||
pfree( query );
|
||||
pfree(query);
|
||||
PG_RETURN_BOOL(retval);
|
||||
}
|
||||
|
||||
@ -156,7 +158,7 @@ g_int_compress(PG_FUNCTION_ARGS)
|
||||
|
||||
retval = palloc(sizeof(GISTENTRY));
|
||||
gistentryinit(*retval, PointerGetDatum(r),
|
||||
entry->rel, entry->page, entry->offset, FALSE);
|
||||
entry->rel, entry->page, entry->offset, FALSE);
|
||||
|
||||
PG_RETURN_POINTER(retval);
|
||||
}
|
||||
@ -203,7 +205,7 @@ g_int_compress(PG_FUNCTION_ARGS)
|
||||
r = resize_intArrayType(r, len);
|
||||
retval = palloc(sizeof(GISTENTRY));
|
||||
gistentryinit(*retval, PointerGetDatum(r),
|
||||
entry->rel, entry->page, entry->offset, FALSE);
|
||||
entry->rel, entry->page, entry->offset, FALSE);
|
||||
PG_RETURN_POINTER(retval);
|
||||
}
|
||||
else
|
||||
@ -240,7 +242,7 @@ g_int_decompress(PG_FUNCTION_ARGS)
|
||||
{
|
||||
retval = palloc(sizeof(GISTENTRY));
|
||||
gistentryinit(*retval, PointerGetDatum(in),
|
||||
entry->rel, entry->page, entry->offset, FALSE);
|
||||
entry->rel, entry->page, entry->offset, FALSE);
|
||||
|
||||
PG_RETURN_POINTER(retval);
|
||||
}
|
||||
@ -331,7 +333,7 @@ typedef struct
|
||||
{
|
||||
OffsetNumber pos;
|
||||
float cost;
|
||||
} SPLITCOST;
|
||||
} SPLITCOST;
|
||||
|
||||
static int
|
||||
comparecost(const void *a, const void *b)
|
||||
|
@ -89,22 +89,27 @@ inner_int_union(ArrayType *a, ArrayType *b)
|
||||
|
||||
if (!r)
|
||||
{
|
||||
int na = ARRNELEMS(a),
|
||||
nb = ARRNELEMS(b);
|
||||
int *da = ARRPTR(a),
|
||||
*db = ARRPTR(b);
|
||||
int i,j, *dr;
|
||||
int na = ARRNELEMS(a),
|
||||
nb = ARRNELEMS(b);
|
||||
int *da = ARRPTR(a),
|
||||
*db = ARRPTR(b);
|
||||
int i,
|
||||
j,
|
||||
*dr;
|
||||
|
||||
r = new_intArrayType(na + nb);
|
||||
dr = ARRPTR(r);
|
||||
|
||||
/* union */
|
||||
i = j = 0;
|
||||
while (i < na && j < nb) {
|
||||
if (da[i] == db[j]) {
|
||||
while (i < na && j < nb)
|
||||
{
|
||||
if (da[i] == db[j])
|
||||
{
|
||||
*dr++ = da[i++];
|
||||
j++;
|
||||
} else if (da[i] < db[j])
|
||||
}
|
||||
else if (da[i] < db[j])
|
||||
*dr++ = da[i++];
|
||||
else
|
||||
*dr++ = db[j++];
|
||||
@ -115,7 +120,7 @@ inner_int_union(ArrayType *a, ArrayType *b)
|
||||
while (j < nb)
|
||||
*dr++ = db[j++];
|
||||
|
||||
r = resize_intArrayType(r, dr-ARRPTR(r));
|
||||
r = resize_intArrayType(r, dr - ARRPTR(r));
|
||||
}
|
||||
|
||||
if (ARRNELEMS(r) > 1)
|
||||
|
@ -214,7 +214,7 @@ sizebitvec(BITVECP sign)
|
||||
i;
|
||||
|
||||
LOOPBYTE(
|
||||
size += number_of_ones[(unsigned char) sign[i]];
|
||||
size += number_of_ones[(unsigned char) sign[i]];
|
||||
);
|
||||
return size;
|
||||
}
|
||||
@ -227,8 +227,8 @@ hemdistsign(BITVECP a, BITVECP b)
|
||||
dist = 0;
|
||||
|
||||
LOOPBYTE(
|
||||
diff = (unsigned char) (a[i] ^ b[i]);
|
||||
dist += number_of_ones[diff];
|
||||
diff = (unsigned char) (a[i] ^ b[i]);
|
||||
dist += number_of_ones[diff];
|
||||
);
|
||||
return dist;
|
||||
}
|
||||
@ -318,7 +318,7 @@ typedef struct
|
||||
{
|
||||
OffsetNumber pos;
|
||||
int4 cost;
|
||||
} SPLITCOST;
|
||||
} SPLITCOST;
|
||||
|
||||
static int
|
||||
comparecost(const void *a, const void *b)
|
||||
@ -506,16 +506,17 @@ g_intbig_consistent(PG_FUNCTION_ARGS)
|
||||
|
||||
if (strategy == BooleanSearchStrategy)
|
||||
{
|
||||
retval =signconsistent((QUERYTYPE *) query,
|
||||
GETSIGN(DatumGetPointer(entry->key)),
|
||||
false);
|
||||
PG_FREE_IF_COPY( query, 1 );
|
||||
retval = signconsistent((QUERYTYPE *) query,
|
||||
GETSIGN(DatumGetPointer(entry->key)),
|
||||
false);
|
||||
PG_FREE_IF_COPY(query, 1);
|
||||
PG_RETURN_BOOL(retval);
|
||||
}
|
||||
|
||||
CHECKARRVALID(query);
|
||||
if (ARRISVOID(query)) {
|
||||
PG_FREE_IF_COPY( query, 1 );
|
||||
if (ARRISVOID(query))
|
||||
{
|
||||
PG_FREE_IF_COPY(query, 1);
|
||||
PG_RETURN_BOOL(FALSE);
|
||||
}
|
||||
|
||||
@ -602,6 +603,6 @@ g_intbig_consistent(PG_FUNCTION_ARGS)
|
||||
default:
|
||||
retval = FALSE;
|
||||
}
|
||||
PG_FREE_IF_COPY( query, 1 );
|
||||
PG_FREE_IF_COPY(query, 1);
|
||||
PG_RETURN_BOOL(retval);
|
||||
}
|
||||
|
@ -1,4 +1,4 @@
|
||||
/*
|
||||
/*
|
||||
* EAN13.h
|
||||
* PostgreSQL type definitions for ISNs (ISBN, ISMN, ISSN, EAN13, UPC)
|
||||
*
|
||||
@ -6,142 +6,143 @@
|
||||
* http://www.gs1.org/productssolutions/idkeys/support/prefix_list.html
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $PostgreSQL: pgsql/contrib/isn/EAN13.h,v 1.1 2006/09/09 04:07:52 tgl Exp $
|
||||
* $PostgreSQL: pgsql/contrib/isn/EAN13.h,v 1.2 2006/10/04 00:29:45 momjian Exp $
|
||||
*
|
||||
*/
|
||||
|
||||
/* where the digit set begins, and how many of them are in the table */
|
||||
const unsigned EAN13_index[10][2] = {
|
||||
{0, 6},
|
||||
{6, 1},
|
||||
{7, 1},
|
||||
{8, 5},
|
||||
{13, 20},
|
||||
{33, 15},
|
||||
{48, 19},
|
||||
{67, 23},
|
||||
{90, 17},
|
||||
{107, 12},
|
||||
{0, 6},
|
||||
{6, 1},
|
||||
{7, 1},
|
||||
{8, 5},
|
||||
{13, 20},
|
||||
{33, 15},
|
||||
{48, 19},
|
||||
{67, 23},
|
||||
{90, 17},
|
||||
{107, 12},
|
||||
};
|
||||
const char *EAN13_range[][2] = {
|
||||
{"000", "019"}, /* GS1 US */
|
||||
{"020", "029"}, /* Restricted distribution (MO defined) */
|
||||
{"030", "039"}, /* GS1 US */
|
||||
{"040", "049"}, /* Restricted distribution (MO defined) */
|
||||
{"050", "059"}, /* Coupons */
|
||||
{"060", "099"}, /* GS1 US */
|
||||
{"100", "139"}, /* GS1 US */
|
||||
{"200", "299"}, /* Restricted distribution (MO defined) */
|
||||
{"300", "379"}, /* GS1 France */
|
||||
{"380", "380"}, /* GS1 Bulgaria */
|
||||
{"383", "383"}, /* GS1 Slovenija */
|
||||
{"385", "385"}, /* GS1 Croatia */
|
||||
{"387", "387"}, /* GS1 BIH (Bosnia-Herzegovina) */
|
||||
{"400", "440"}, /* GS1 Germany */
|
||||
{"450", "459"}, /* GS1 Japan */
|
||||
{"460", "469"}, /* GS1 Russia */
|
||||
{"470", "470"}, /* GS1 Kyrgyzstan */
|
||||
{"471", "471"}, /* GS1 Taiwan */
|
||||
{"474", "474"}, /* GS1 Estonia */
|
||||
{"475", "475"}, /* GS1 Latvia */
|
||||
{"476", "476"}, /* GS1 Azerbaijan */
|
||||
{"477", "477"}, /* GS1 Lithuania */
|
||||
{"478", "478"}, /* GS1 Uzbekistan */
|
||||
{"479", "479"}, /* GS1 Sri Lanka */
|
||||
{"480", "480"}, /* GS1 Philippines */
|
||||
{"481", "481"}, /* GS1 Belarus */
|
||||
{"482", "482"}, /* GS1 Ukraine */
|
||||
{"484", "484"}, /* GS1 Moldova */
|
||||
{"485", "485"}, /* GS1 Armenia */
|
||||
{"486", "486"}, /* GS1 Georgia */
|
||||
{"487", "487"}, /* GS1 Kazakstan */
|
||||
{"489", "489"}, /* GS1 Hong Kong */
|
||||
{"490", "499"}, /* GS1 Japan */
|
||||
{"500", "509"}, /* GS1 UK */
|
||||
{"520", "520"}, /* GS1 Greece */
|
||||
{"528", "528"}, /* GS1 Lebanon */
|
||||
{"529", "529"}, /* GS1 Cyprus */
|
||||
{"530", "530"}, /* GS1 Albania */
|
||||
{"531", "531"}, /* GS1 MAC (FYR Macedonia) */
|
||||
{"535", "535"}, /* GS1 Malta */
|
||||
{"539", "539"}, /* GS1 Ireland */
|
||||
{"540", "549"}, /* GS1 Belgium & Luxembourg */
|
||||
{"560", "560"}, /* GS1 Portugal */
|
||||
{"569", "569"}, /* GS1 Iceland */
|
||||
{"570", "579"}, /* GS1 Denmark */
|
||||
{"590", "590"}, /* GS1 Poland */
|
||||
{"594", "594"}, /* GS1 Romania */
|
||||
{"599", "599"}, /* GS1 Hungary */
|
||||
{"600", "601"}, /* GS1 South Africa */
|
||||
{"603", "603"}, /* GS1 Ghana */
|
||||
{"608", "608"}, /* GS1 Bahrain */
|
||||
{"609", "609"}, /* GS1 Mauritius */
|
||||
{"611", "611"}, /* GS1 Morocco */
|
||||
{"613", "613"}, /* GS1 Algeria */
|
||||
{"616", "616"}, /* GS1 Kenya */
|
||||
{"618", "618"}, /* GS1 Ivory Coast */
|
||||
{"619", "619"}, /* GS1 Tunisia */
|
||||
{"621", "621"}, /* GS1 Syria */
|
||||
{"622", "622"}, /* GS1 Egypt */
|
||||
{"624", "624"}, /* GS1 Libya */
|
||||
{"625", "625"}, /* GS1 Jordan */
|
||||
{"626", "626"}, /* GS1 Iran */
|
||||
{"627", "627"}, /* GS1 Kuwait */
|
||||
{"628", "628"}, /* GS1 Saudi Arabia */
|
||||
{"629", "629"}, /* GS1 Emirates */
|
||||
{"640", "649"}, /* GS1 Finland */
|
||||
{"690", "695"}, /* GS1 China */
|
||||
{"700", "709"}, /* GS1 Norway */
|
||||
{"729", "729"}, /* GS1 Israel */
|
||||
{"730", "739"}, /* GS1 Sweden */
|
||||
{"740", "740"}, /* GS1 Guatemala */
|
||||
{"741", "741"}, /* GS1 El Salvador */
|
||||
{"742", "742"}, /* GS1 Honduras */
|
||||
{"743", "743"}, /* GS1 Nicaragua */
|
||||
{"744", "744"}, /* GS1 Costa Rica */
|
||||
{"745", "745"}, /* GS1 Panama */
|
||||
{"746", "746"}, /* GS1 Republica Dominicana */
|
||||
{"750", "750"}, /* GS1 Mexico */
|
||||
{"754", "755"}, /* GS1 Canada */
|
||||
{"759", "759"}, /* GS1 Venezuela */
|
||||
{"760", "769"}, /* GS1 Schweiz, Suisse, Svizzera */
|
||||
{"770", "770"}, /* GS1 Colombia */
|
||||
{"773", "773"}, /* GS1 Uruguay */
|
||||
{"775", "775"}, /* GS1 Peru */
|
||||
{"777", "777"}, /* GS1 Bolivia */
|
||||
{"779", "779"}, /* GS1 Argentina */
|
||||
{"780", "780"}, /* GS1 Chile */
|
||||
{"784", "784"}, /* GS1 Paraguay */
|
||||
{"786", "786"}, /* GS1 Ecuador */
|
||||
{"789", "790"}, /* GS1 Brasil */
|
||||
{"800", "839"}, /* GS1 Italy */
|
||||
{"840", "849"}, /* GS1 Spain */
|
||||
{"850", "850"}, /* GS1 Cuba */
|
||||
{"858", "858"}, /* GS1 Slovakia */
|
||||
{"859", "859"}, /* GS1 Czech */
|
||||
{"860", "860"}, /* GS1 YU (Serbia & Montenegro) */
|
||||
{"865", "865"}, /* GS1 Mongolia */
|
||||
{"867", "867"}, /* GS1 North Korea */
|
||||
{"869", "869"}, /* GS1 Turkey */
|
||||
{"870", "879"}, /* GS1 Netherlands */
|
||||
{"880", "880"}, /* GS1 South Korea */
|
||||
{"884", "884"}, /* GS1 Cambodia */
|
||||
{"885", "885"}, /* GS1 Thailand */
|
||||
{"888", "888"}, /* GS1 Singapore */
|
||||
{"890", "890"}, /* GS1 India */
|
||||
{"893", "893"}, /* GS1 Vietnam */
|
||||
{"899", "899"}, /* GS1 Indonesia */
|
||||
{"900", "919"}, /* GS1 Austria */
|
||||
{"930", "939"}, /* GS1 Australia */
|
||||
{"940", "949"}, /* GS1 New Zealand */
|
||||
{"950", "950"}, /* GS1 Head Office */
|
||||
{"955", "955"}, /* GS1 Malaysia */
|
||||
{"958", "958"}, /* GS1 Macau */
|
||||
{"977", "977"}, /* Serial publications (ISSN) */
|
||||
{"978", "978"}, /* Bookland (ISBN) */
|
||||
{"979", "979"}, /* International Standard Music Number (ISMN) and ISBN contingent */
|
||||
{"980", "980"}, /* Refund receipts */
|
||||
{"981", "982"}, /* Common Currency Coupons */
|
||||
{"990", "999"}, /* Coupons */
|
||||
{"000", "019"}, /* GS1 US */
|
||||
{"020", "029"}, /* Restricted distribution (MO defined) */
|
||||
{"030", "039"}, /* GS1 US */
|
||||
{"040", "049"}, /* Restricted distribution (MO defined) */
|
||||
{"050", "059"}, /* Coupons */
|
||||
{"060", "099"}, /* GS1 US */
|
||||
{"100", "139"}, /* GS1 US */
|
||||
{"200", "299"}, /* Restricted distribution (MO defined) */
|
||||
{"300", "379"}, /* GS1 France */
|
||||
{"380", "380"}, /* GS1 Bulgaria */
|
||||
{"383", "383"}, /* GS1 Slovenija */
|
||||
{"385", "385"}, /* GS1 Croatia */
|
||||
{"387", "387"}, /* GS1 BIH (Bosnia-Herzegovina) */
|
||||
{"400", "440"}, /* GS1 Germany */
|
||||
{"450", "459"}, /* GS1 Japan */
|
||||
{"460", "469"}, /* GS1 Russia */
|
||||
{"470", "470"}, /* GS1 Kyrgyzstan */
|
||||
{"471", "471"}, /* GS1 Taiwan */
|
||||
{"474", "474"}, /* GS1 Estonia */
|
||||
{"475", "475"}, /* GS1 Latvia */
|
||||
{"476", "476"}, /* GS1 Azerbaijan */
|
||||
{"477", "477"}, /* GS1 Lithuania */
|
||||
{"478", "478"}, /* GS1 Uzbekistan */
|
||||
{"479", "479"}, /* GS1 Sri Lanka */
|
||||
{"480", "480"}, /* GS1 Philippines */
|
||||
{"481", "481"}, /* GS1 Belarus */
|
||||
{"482", "482"}, /* GS1 Ukraine */
|
||||
{"484", "484"}, /* GS1 Moldova */
|
||||
{"485", "485"}, /* GS1 Armenia */
|
||||
{"486", "486"}, /* GS1 Georgia */
|
||||
{"487", "487"}, /* GS1 Kazakstan */
|
||||
{"489", "489"}, /* GS1 Hong Kong */
|
||||
{"490", "499"}, /* GS1 Japan */
|
||||
{"500", "509"}, /* GS1 UK */
|
||||
{"520", "520"}, /* GS1 Greece */
|
||||
{"528", "528"}, /* GS1 Lebanon */
|
||||
{"529", "529"}, /* GS1 Cyprus */
|
||||
{"530", "530"}, /* GS1 Albania */
|
||||
{"531", "531"}, /* GS1 MAC (FYR Macedonia) */
|
||||
{"535", "535"}, /* GS1 Malta */
|
||||
{"539", "539"}, /* GS1 Ireland */
|
||||
{"540", "549"}, /* GS1 Belgium & Luxembourg */
|
||||
{"560", "560"}, /* GS1 Portugal */
|
||||
{"569", "569"}, /* GS1 Iceland */
|
||||
{"570", "579"}, /* GS1 Denmark */
|
||||
{"590", "590"}, /* GS1 Poland */
|
||||
{"594", "594"}, /* GS1 Romania */
|
||||
{"599", "599"}, /* GS1 Hungary */
|
||||
{"600", "601"}, /* GS1 South Africa */
|
||||
{"603", "603"}, /* GS1 Ghana */
|
||||
{"608", "608"}, /* GS1 Bahrain */
|
||||
{"609", "609"}, /* GS1 Mauritius */
|
||||
{"611", "611"}, /* GS1 Morocco */
|
||||
{"613", "613"}, /* GS1 Algeria */
|
||||
{"616", "616"}, /* GS1 Kenya */
|
||||
{"618", "618"}, /* GS1 Ivory Coast */
|
||||
{"619", "619"}, /* GS1 Tunisia */
|
||||
{"621", "621"}, /* GS1 Syria */
|
||||
{"622", "622"}, /* GS1 Egypt */
|
||||
{"624", "624"}, /* GS1 Libya */
|
||||
{"625", "625"}, /* GS1 Jordan */
|
||||
{"626", "626"}, /* GS1 Iran */
|
||||
{"627", "627"}, /* GS1 Kuwait */
|
||||
{"628", "628"}, /* GS1 Saudi Arabia */
|
||||
{"629", "629"}, /* GS1 Emirates */
|
||||
{"640", "649"}, /* GS1 Finland */
|
||||
{"690", "695"}, /* GS1 China */
|
||||
{"700", "709"}, /* GS1 Norway */
|
||||
{"729", "729"}, /* GS1 Israel */
|
||||
{"730", "739"}, /* GS1 Sweden */
|
||||
{"740", "740"}, /* GS1 Guatemala */
|
||||
{"741", "741"}, /* GS1 El Salvador */
|
||||
{"742", "742"}, /* GS1 Honduras */
|
||||
{"743", "743"}, /* GS1 Nicaragua */
|
||||
{"744", "744"}, /* GS1 Costa Rica */
|
||||
{"745", "745"}, /* GS1 Panama */
|
||||
{"746", "746"}, /* GS1 Republica Dominicana */
|
||||
{"750", "750"}, /* GS1 Mexico */
|
||||
{"754", "755"}, /* GS1 Canada */
|
||||
{"759", "759"}, /* GS1 Venezuela */
|
||||
{"760", "769"}, /* GS1 Schweiz, Suisse, Svizzera */
|
||||
{"770", "770"}, /* GS1 Colombia */
|
||||
{"773", "773"}, /* GS1 Uruguay */
|
||||
{"775", "775"}, /* GS1 Peru */
|
||||
{"777", "777"}, /* GS1 Bolivia */
|
||||
{"779", "779"}, /* GS1 Argentina */
|
||||
{"780", "780"}, /* GS1 Chile */
|
||||
{"784", "784"}, /* GS1 Paraguay */
|
||||
{"786", "786"}, /* GS1 Ecuador */
|
||||
{"789", "790"}, /* GS1 Brasil */
|
||||
{"800", "839"}, /* GS1 Italy */
|
||||
{"840", "849"}, /* GS1 Spain */
|
||||
{"850", "850"}, /* GS1 Cuba */
|
||||
{"858", "858"}, /* GS1 Slovakia */
|
||||
{"859", "859"}, /* GS1 Czech */
|
||||
{"860", "860"}, /* GS1 YU (Serbia & Montenegro) */
|
||||
{"865", "865"}, /* GS1 Mongolia */
|
||||
{"867", "867"}, /* GS1 North Korea */
|
||||
{"869", "869"}, /* GS1 Turkey */
|
||||
{"870", "879"}, /* GS1 Netherlands */
|
||||
{"880", "880"}, /* GS1 South Korea */
|
||||
{"884", "884"}, /* GS1 Cambodia */
|
||||
{"885", "885"}, /* GS1 Thailand */
|
||||
{"888", "888"}, /* GS1 Singapore */
|
||||
{"890", "890"}, /* GS1 India */
|
||||
{"893", "893"}, /* GS1 Vietnam */
|
||||
{"899", "899"}, /* GS1 Indonesia */
|
||||
{"900", "919"}, /* GS1 Austria */
|
||||
{"930", "939"}, /* GS1 Australia */
|
||||
{"940", "949"}, /* GS1 New Zealand */
|
||||
{"950", "950"}, /* GS1 Head Office */
|
||||
{"955", "955"}, /* GS1 Malaysia */
|
||||
{"958", "958"}, /* GS1 Macau */
|
||||
{"977", "977"}, /* Serial publications (ISSN) */
|
||||
{"978", "978"}, /* Bookland (ISBN) */
|
||||
{"979", "979"}, /* International Standard Music Number (ISMN)
|
||||
* and ISBN contingent */
|
||||
{"980", "980"}, /* Refund receipts */
|
||||
{"981", "982"}, /* Common Currency Coupons */
|
||||
{"990", "999"}, /* Coupons */
|
||||
{NULL, NULL}
|
||||
};
|
||||
|
@ -1,4 +1,4 @@
|
||||
/*
|
||||
/*
|
||||
* ISBN.h
|
||||
* PostgreSQL type definitions for ISNs (ISBN, ISMN, ISSN, EAN13, UPC)
|
||||
*
|
||||
@ -7,39 +7,39 @@
|
||||
* http://www.isbn.org/
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $PostgreSQL: pgsql/contrib/isn/ISBN.h,v 1.1 2006/09/09 04:07:52 tgl Exp $
|
||||
* $PostgreSQL: pgsql/contrib/isn/ISBN.h,v 1.2 2006/10/04 00:29:45 momjian Exp $
|
||||
*
|
||||
* 0-393-04002-X => 039304002(X) <=> 039304002 <=> (978)039304002 <=> 978039304002(9) <=> 978-0-393-04002-9
|
||||
*
|
||||
*
|
||||
* ISBN 0 3 9 3 0 4 0 0 2
|
||||
* Weight 10 9 8 7 6 5 4 3 2
|
||||
* Product 0 + 27 + 72 + 21 + 0 + 20 + 0 + 0 + 4 = 144
|
||||
* 144 / 11 = 13 remainder 1
|
||||
* Check digit 11 - 1 = 10 = X
|
||||
* ISBN 0 3 9 3 0 4 0 0 2
|
||||
* Weight 10 9 8 7 6 5 4 3 2
|
||||
* Product 0 + 27 + 72 + 21 + 0 + 20 + 0 + 0 + 4 = 144
|
||||
* 144 / 11 = 13 remainder 1
|
||||
* Check digit 11 - 1 = 10 = X
|
||||
* => 0-393-04002-X
|
||||
*
|
||||
* ISBN 9 7 8 0 3 9 3 0 4 0 0 2
|
||||
* Weight 1 3 1 3 1 3 1 3 1 3 1 3
|
||||
* Product 9 + 21 + 8 + 0 + 3 + 27 + 3 + 0 + 4 + 0 + 0 + 6 = 81
|
||||
* 81 / 10 = 8 remainder 1
|
||||
* Check digit 10 - 1 = 9
|
||||
* ISBN 9 7 8 0 3 9 3 0 4 0 0 2
|
||||
* Weight 1 3 1 3 1 3 1 3 1 3 1 3
|
||||
* Product 9 + 21 + 8 + 0 + 3 + 27 + 3 + 0 + 4 + 0 + 0 + 6 = 81
|
||||
* 81 / 10 = 8 remainder 1
|
||||
* Check digit 10 - 1 = 9
|
||||
* => 978-0-393-04002-9
|
||||
*
|
||||
*/
|
||||
|
||||
/* where the digit set begins, and how many of them are in the table */
|
||||
const unsigned ISBN_index[10][2] = {
|
||||
{0, 6},
|
||||
{6, 6},
|
||||
{12, 8},
|
||||
{20, 10},
|
||||
{30, 6},
|
||||
{36, 12},
|
||||
{48, 0},
|
||||
{48, 5},
|
||||
{53, 59},
|
||||
{112, 573},
|
||||
{0, 6},
|
||||
{6, 6},
|
||||
{12, 8},
|
||||
{20, 10},
|
||||
{30, 6},
|
||||
{36, 12},
|
||||
{48, 0},
|
||||
{48, 5},
|
||||
{53, 59},
|
||||
{112, 573},
|
||||
};
|
||||
|
||||
const char *ISBN_range[][2] = {
|
||||
|
@ -1,4 +1,4 @@
|
||||
/*
|
||||
/*
|
||||
* ISMN.h
|
||||
* PostgreSQL type definitions for ISNs (ISBN, ISMN, ISSN, EAN13, UPC)
|
||||
*
|
||||
@ -6,23 +6,23 @@
|
||||
* http://www.ismn-international.org
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $PostgreSQL: pgsql/contrib/isn/ISMN.h,v 1.1 2006/09/09 04:07:52 tgl Exp $
|
||||
* $PostgreSQL: pgsql/contrib/isn/ISMN.h,v 1.2 2006/10/04 00:29:45 momjian Exp $
|
||||
*
|
||||
* M-3452-4680-5 <=> (0)-3452-4680-5 <=> 0345246805 <=> 9790345246805 <=> 979-0-3452-4680-5
|
||||
*
|
||||
* (M counts as 3)
|
||||
* ISMN M 3 4 5 2 4 6 8 0
|
||||
* Weight 3 1 3 1 3 1 3 1 3
|
||||
* Product 9 + 3 + 12 + 5 + 6 + 4 + 18 + 8 + 0 = 65
|
||||
* 65 / 10 = 6 remainder 5
|
||||
* Check digit 10 - 5 = 5
|
||||
* (M counts as 3)
|
||||
* ISMN M 3 4 5 2 4 6 8 0
|
||||
* Weight 3 1 3 1 3 1 3 1 3
|
||||
* Product 9 + 3 + 12 + 5 + 6 + 4 + 18 + 8 + 0 = 65
|
||||
* 65 / 10 = 6 remainder 5
|
||||
* Check digit 10 - 5 = 5
|
||||
* => M-3452-4680-5
|
||||
*
|
||||
* ISMN 9 7 9 0 3 4 5 2 4 6 8 0
|
||||
* Weight 1 3 1 3 1 3 1 3 1 3 1 3
|
||||
* Product 9 + 21 + 9 + 0 + 3 + 12 + 5 + 6 + 4 + 18 + 8 + 0 = 95
|
||||
* 95 / 10 = 9 remainder 5
|
||||
* Check digit 10 - 5 = 5
|
||||
* ISMN 9 7 9 0 3 4 5 2 4 6 8 0
|
||||
* Weight 1 3 1 3 1 3 1 3 1 3 1 3
|
||||
* Product 9 + 21 + 9 + 0 + 3 + 12 + 5 + 6 + 4 + 18 + 8 + 0 = 95
|
||||
* 95 / 10 = 9 remainder 5
|
||||
* Check digit 10 - 5 = 5
|
||||
* => 979-0-3452-4680-5
|
||||
*
|
||||
* Since mod10(9*1 + 7*3 + 9*1 + 0*3) = mod10(M*3) = mod10(3*3) = 9; the check digit remains the same.
|
||||
@ -31,16 +31,16 @@
|
||||
|
||||
/* where the digit set begins, and how many of them are in the table */
|
||||
const unsigned ISMN_index[10][2] = {
|
||||
{0, 5},
|
||||
{5, 0},
|
||||
{5, 0},
|
||||
{5, 0},
|
||||
{5, 0},
|
||||
{5, 0},
|
||||
{5, 0},
|
||||
{5, 0},
|
||||
{5, 0},
|
||||
{5, 0},
|
||||
{0, 5},
|
||||
{5, 0},
|
||||
{5, 0},
|
||||
{5, 0},
|
||||
{5, 0},
|
||||
{5, 0},
|
||||
{5, 0},
|
||||
{5, 0},
|
||||
{5, 0},
|
||||
{5, 0},
|
||||
};
|
||||
const char *ISMN_range[][2] = {
|
||||
{"0-000", "0-099"},
|
||||
|
@ -1,4 +1,4 @@
|
||||
/*
|
||||
/*
|
||||
* ISSN.h
|
||||
* PostgreSQL type definitions for ISNs (ISBN, ISMN, ISSN, EAN13, UPC)
|
||||
*
|
||||
@ -6,25 +6,25 @@
|
||||
* http://www.issn.org/
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $PostgreSQL: pgsql/contrib/isn/ISSN.h,v 1.1 2006/09/09 04:07:52 tgl Exp $
|
||||
* $PostgreSQL: pgsql/contrib/isn/ISSN.h,v 1.2 2006/10/04 00:29:45 momjian Exp $
|
||||
*
|
||||
* 1144-875X <=> 1144875(X) <=> 1144875 <=> (977)1144875 <=> 9771144875(00) <=> 977114487500(7) <=> 977-1144-875-00-7
|
||||
*
|
||||
*
|
||||
* ISSN 1 1 4 4 8 7 5
|
||||
* Weight 8 7 6 5 4 3 2
|
||||
* Product 8 + 7 + 24 + 20 + 32 + 21 + 10 = 122
|
||||
* 122 / 11 = 11 remainder 1
|
||||
* Check digit 11 - 1 = 10 = X
|
||||
*
|
||||
* ISSN 1 1 4 4 8 7 5
|
||||
* Weight 8 7 6 5 4 3 2
|
||||
* Product 8 + 7 + 24 + 20 + 32 + 21 + 10 = 122
|
||||
* 122 / 11 = 11 remainder 1
|
||||
* Check digit 11 - 1 = 10 = X
|
||||
* => 1144-875X
|
||||
*
|
||||
* ISSN 9 7 7 1 1 4 4 8 7 5 0 0
|
||||
* Weight 1 3 1 3 1 3 1 3 1 3 1 3
|
||||
* Product 9 + 21 + 7 + 3 + 1 + 12 + 4 + 24 + 7 + 15 + 0 + 0 = 103
|
||||
* 103 / 10 = 10 remainder 3
|
||||
* Check digit 10 - 3 = 7
|
||||
*
|
||||
* ISSN 9 7 7 1 1 4 4 8 7 5 0 0
|
||||
* Weight 1 3 1 3 1 3 1 3 1 3 1 3
|
||||
* Product 9 + 21 + 7 + 3 + 1 + 12 + 4 + 24 + 7 + 15 + 0 + 0 = 103
|
||||
* 103 / 10 = 10 remainder 3
|
||||
* Check digit 10 - 3 = 7
|
||||
* => 977-1144875-00-7 ?? <- suplemental number (number of the week, month, etc.)
|
||||
* ^^ 00 for non-daily publications (01=Monday, 02=Tuesday, ...)
|
||||
* ^^ 00 for non-daily publications (01=Monday, 02=Tuesday, ...)
|
||||
*
|
||||
* The hyphenation is always in after the four digits of the ISSN code.
|
||||
*
|
||||
@ -32,16 +32,16 @@
|
||||
|
||||
/* where the digit set begins, and how many of them are in the table */
|
||||
const unsigned ISSN_index[10][2] = {
|
||||
{0, 1},
|
||||
{0, 1},
|
||||
{0, 1},
|
||||
{0, 1},
|
||||
{0, 1},
|
||||
{0, 1},
|
||||
{0, 1},
|
||||
{0, 1},
|
||||
{0, 1},
|
||||
{0, 1},
|
||||
{0, 1},
|
||||
{0, 1},
|
||||
{0, 1},
|
||||
{0, 1},
|
||||
{0, 1},
|
||||
{0, 1},
|
||||
{0, 1},
|
||||
{0, 1},
|
||||
{0, 1},
|
||||
{0, 1},
|
||||
};
|
||||
const char *ISSN_range[][2] = {
|
||||
{"0000-000", "9999-999"},
|
||||
|
@ -1,27 +1,27 @@
|
||||
/*
|
||||
/*
|
||||
* ISSN.h
|
||||
* PostgreSQL type definitions for ISNs (ISBN, ISMN, ISSN, EAN13, UPC)
|
||||
*
|
||||
* No information available for UPC prefixes
|
||||
*
|
||||
*
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $PostgreSQL: pgsql/contrib/isn/UPC.h,v 1.1 2006/09/09 04:07:52 tgl Exp $
|
||||
* $PostgreSQL: pgsql/contrib/isn/UPC.h,v 1.2 2006/10/04 00:29:45 momjian Exp $
|
||||
*
|
||||
*/
|
||||
|
||||
/* where the digit set begins, and how many of them are in the table */
|
||||
const unsigned UPC_index[10][2] = {
|
||||
{0, 0},
|
||||
{0, 0},
|
||||
{0, 0},
|
||||
{0, 0},
|
||||
{0, 0},
|
||||
{0, 0},
|
||||
{0, 0},
|
||||
{0, 0},
|
||||
{0, 0},
|
||||
{0, 0},
|
||||
{0, 0},
|
||||
{0, 0},
|
||||
{0, 0},
|
||||
{0, 0},
|
||||
{0, 0},
|
||||
{0, 0},
|
||||
{0, 0},
|
||||
{0, 0},
|
||||
{0, 0},
|
||||
{0, 0},
|
||||
};
|
||||
const char *UPC_range[][2] = {
|
||||
{NULL, NULL}
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -219,7 +219,7 @@ sizebitvec(BITVECP sign)
|
||||
i;
|
||||
|
||||
ALOOPBYTE(
|
||||
size += number_of_ones[(unsigned char) sign[i]];
|
||||
size += number_of_ones[(unsigned char) sign[i]];
|
||||
);
|
||||
return size;
|
||||
}
|
||||
@ -232,8 +232,8 @@ hemdistsign(BITVECP a, BITVECP b)
|
||||
dist = 0;
|
||||
|
||||
ALOOPBYTE(
|
||||
diff = (unsigned char) (a[i] ^ b[i]);
|
||||
dist += number_of_ones[diff];
|
||||
diff = (unsigned char) (a[i] ^ b[i]);
|
||||
dist += number_of_ones[diff];
|
||||
);
|
||||
return dist;
|
||||
}
|
||||
@ -270,7 +270,7 @@ typedef struct
|
||||
{
|
||||
OffsetNumber pos;
|
||||
int4 cost;
|
||||
} SPLITCOST;
|
||||
} SPLITCOST;
|
||||
|
||||
static int
|
||||
comparecost(const void *a, const void *b)
|
||||
@ -580,6 +580,6 @@ _ltree_consistent(PG_FUNCTION_ARGS)
|
||||
/* internal error */
|
||||
elog(ERROR, "unrecognized StrategyNumber: %d", strategy);
|
||||
}
|
||||
PG_FREE_IF_COPY(query,1);
|
||||
PG_FREE_IF_COPY(query, 1);
|
||||
PG_RETURN_BOOL(res);
|
||||
}
|
||||
|
@ -1,7 +1,7 @@
|
||||
/*
|
||||
* op function for ltree and lquery
|
||||
* Teodor Sigaev <teodor@stack.net>
|
||||
* $PostgreSQL: pgsql/contrib/ltree/lquery_op.c,v 1.10 2006/03/11 04:38:29 momjian Exp $
|
||||
* $PostgreSQL: pgsql/contrib/ltree/lquery_op.c,v 1.11 2006/10/04 00:29:45 momjian Exp $
|
||||
*/
|
||||
|
||||
#include "ltree.h"
|
||||
@ -46,7 +46,7 @@ getlexeme(char *start, char *end, int *len)
|
||||
}
|
||||
|
||||
bool
|
||||
compare_subnode(ltree_level * t, char *qn, int len, int (*cmpptr) (const char *, const char *, size_t), bool anyend)
|
||||
compare_subnode(ltree_level * t, char *qn, int len, int (*cmpptr) (const char *, const char *, size_t), bool anyend)
|
||||
{
|
||||
char *endt = t->name + t->len;
|
||||
char *endq = qn + len;
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $PostgreSQL: pgsql/contrib/ltree/ltree.h,v 1.16 2006/07/11 16:00:44 teodor Exp $ */
|
||||
/* $PostgreSQL: pgsql/contrib/ltree/ltree.h,v 1.17 2006/10/04 00:29:45 momjian Exp $ */
|
||||
|
||||
#ifndef __LTREE_H__
|
||||
#define __LTREE_H__
|
||||
@ -163,7 +163,7 @@ bool compare_subnode(ltree_level * t, char *q, int len,
|
||||
ltree *lca_inner(ltree ** a, int len);
|
||||
|
||||
#define PG_GETARG_LTREE(x) ((ltree*)DatumGetPointer(PG_DETOAST_DATUM(PG_GETARG_DATUM(x))))
|
||||
#define PG_GETARG_LTREE_COPY(x) ((ltree*)DatumGetPointer(PG_DETOAST_DATUM_COPY(PG_GETARG_DATUM(x))))
|
||||
#define PG_GETARG_LTREE_COPY(x) ((ltree*)DatumGetPointer(PG_DETOAST_DATUM_COPY(PG_GETARG_DATUM(x))))
|
||||
#define PG_GETARG_LQUERY(x) ((lquery*)DatumGetPointer(PG_DETOAST_DATUM(PG_GETARG_DATUM(x))))
|
||||
#define PG_GETARG_LQUERY_COPY(x) ((lquery*)DatumGetPointer(PG_DETOAST_DATUM_COPY(PG_GETARG_DATUM(x))))
|
||||
#define PG_GETARG_LTXTQUERY(x) ((ltxtquery*)DatumGetPointer(PG_DETOAST_DATUM(PG_GETARG_DATUM(x))))
|
||||
|
@ -1,7 +1,7 @@
|
||||
/*
|
||||
* GiST support for ltree
|
||||
* Teodor Sigaev <teodor@stack.net>
|
||||
* $PostgreSQL: pgsql/contrib/ltree/ltree_gist.c,v 1.18 2006/08/08 15:45:18 teodor Exp $
|
||||
* $PostgreSQL: pgsql/contrib/ltree/ltree_gist.c,v 1.19 2006/10/04 00:29:45 momjian Exp $
|
||||
*/
|
||||
|
||||
#include "ltree.h"
|
||||
@ -457,8 +457,10 @@ gist_isparent(ltree_gist * key, ltree * query)
|
||||
}
|
||||
|
||||
static ltree *
|
||||
copy_ltree( ltree *src ) {
|
||||
ltree *dst = (ltree*)palloc(src->len);
|
||||
copy_ltree(ltree * src)
|
||||
{
|
||||
ltree *dst = (ltree *) palloc(src->len);
|
||||
|
||||
memcpy(dst, src, src->len);
|
||||
return dst;
|
||||
}
|
||||
@ -466,9 +468,9 @@ copy_ltree( ltree *src ) {
|
||||
static bool
|
||||
gist_ischild(ltree_gist * key, ltree * query)
|
||||
{
|
||||
ltree *left = copy_ltree(LTG_GETLNODE(key));
|
||||
ltree *right = copy_ltree(LTG_GETRNODE(key));
|
||||
bool res = true;
|
||||
ltree *left = copy_ltree(LTG_GETLNODE(key));
|
||||
ltree *right = copy_ltree(LTG_GETRNODE(key));
|
||||
bool res = true;
|
||||
|
||||
if (left->numlevel > query->numlevel)
|
||||
left->numlevel = query->numlevel;
|
||||
@ -711,6 +713,6 @@ ltree_consistent(PG_FUNCTION_ARGS)
|
||||
elog(ERROR, "unrecognized StrategyNumber: %d", strategy);
|
||||
}
|
||||
|
||||
PG_FREE_IF_COPY(query,1);
|
||||
PG_FREE_IF_COPY(query, 1);
|
||||
PG_RETURN_BOOL(res);
|
||||
}
|
||||
|
@ -1,7 +1,7 @@
|
||||
/*
|
||||
* op function for ltree
|
||||
* Teodor Sigaev <teodor@stack.net>
|
||||
* $PostgreSQL: pgsql/contrib/ltree/ltree_op.c,v 1.13 2006/09/20 19:50:21 tgl Exp $
|
||||
* $PostgreSQL: pgsql/contrib/ltree/ltree_op.c,v 1.14 2006/10/04 00:29:45 momjian Exp $
|
||||
*/
|
||||
|
||||
#include "ltree.h"
|
||||
@ -620,8 +620,8 @@ ltreeparentsel(PG_FUNCTION_ARGS)
|
||||
/*
|
||||
* If the histogram is large enough, see what fraction of it the
|
||||
* constant is "<@" to, and assume that's representative of the
|
||||
* non-MCV population. Otherwise use the default selectivity for
|
||||
* the non-MCV population.
|
||||
* non-MCV population. Otherwise use the default selectivity for the
|
||||
* non-MCV population.
|
||||
*/
|
||||
selec = histogram_selectivity(&vardata, &contproc,
|
||||
constval, varonleft,
|
||||
|
@ -3,7 +3,7 @@
|
||||
* pg_buffercache_pages.c
|
||||
* display some contents of the buffer cache
|
||||
*
|
||||
* $PostgreSQL: pgsql/contrib/pg_buffercache/pg_buffercache_pages.c,v 1.8 2006/07/23 03:07:57 tgl Exp $
|
||||
* $PostgreSQL: pgsql/contrib/pg_buffercache/pg_buffercache_pages.c,v 1.9 2006/10/04 00:29:45 momjian Exp $
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
#include "postgres.h"
|
||||
@ -74,7 +74,7 @@ pg_buffercache_pages(PG_FUNCTION_ARGS)
|
||||
|
||||
if (SRF_IS_FIRSTCALL())
|
||||
{
|
||||
int i;
|
||||
int i;
|
||||
volatile BufferDesc *bufHdr;
|
||||
|
||||
funcctx = SRF_FIRSTCALL_INIT();
|
||||
@ -123,9 +123,9 @@ pg_buffercache_pages(PG_FUNCTION_ARGS)
|
||||
MemoryContextSwitchTo(oldcontext);
|
||||
|
||||
/*
|
||||
* To get a consistent picture of the buffer state, we must lock
|
||||
* all partitions of the buffer map. Needless to say, this is
|
||||
* horrible for concurrency...
|
||||
* To get a consistent picture of the buffer state, we must lock all
|
||||
* partitions of the buffer map. Needless to say, this is horrible
|
||||
* for concurrency...
|
||||
*/
|
||||
for (i = 0; i < NUM_BUFFER_PARTITIONS; i++)
|
||||
LWLockAcquire(FirstBufMappingLock + i, LW_SHARED);
|
||||
|
@ -3,7 +3,7 @@
|
||||
* pg_freespacemap.c
|
||||
* display some contents of the free space relation and page maps.
|
||||
*
|
||||
* $PostgreSQL: pgsql/contrib/pg_freespacemap/pg_freespacemap.c,v 1.7 2006/09/21 20:31:21 tgl Exp $
|
||||
* $PostgreSQL: pgsql/contrib/pg_freespacemap/pg_freespacemap.c,v 1.8 2006/10/04 00:29:45 momjian Exp $
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
#include "postgres.h"
|
||||
@ -14,13 +14,13 @@
|
||||
#include "storage/freespace.h"
|
||||
|
||||
|
||||
#define NUM_FREESPACE_PAGES_ELEM 5
|
||||
#define NUM_FREESPACE_RELATIONS_ELEM 7
|
||||
#define NUM_FREESPACE_PAGES_ELEM 5
|
||||
#define NUM_FREESPACE_RELATIONS_ELEM 7
|
||||
|
||||
#if defined(WIN32) || defined(__CYGWIN__)
|
||||
/* Need DLLIMPORT for some things that are not so marked in main headers */
|
||||
extern DLLIMPORT int MaxFSMPages;
|
||||
extern DLLIMPORT int MaxFSMRelations;
|
||||
extern DLLIMPORT int MaxFSMPages;
|
||||
extern DLLIMPORT int MaxFSMRelations;
|
||||
extern DLLIMPORT volatile uint32 InterruptHoldoffCount;
|
||||
#endif
|
||||
|
||||
@ -35,12 +35,12 @@ Datum pg_freespacemap_relations(PG_FUNCTION_ARGS);
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
Oid reltablespace;
|
||||
Oid reldatabase;
|
||||
Oid relfilenode;
|
||||
BlockNumber relblocknumber;
|
||||
Size bytes;
|
||||
bool isindex;
|
||||
Oid reltablespace;
|
||||
Oid reldatabase;
|
||||
Oid relfilenode;
|
||||
BlockNumber relblocknumber;
|
||||
Size bytes;
|
||||
bool isindex;
|
||||
} FreeSpacePagesRec;
|
||||
|
||||
|
||||
@ -49,14 +49,14 @@ typedef struct
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
Oid reltablespace;
|
||||
Oid reldatabase;
|
||||
Oid relfilenode;
|
||||
Size avgrequest;
|
||||
BlockNumber interestingpages;
|
||||
int storedpages;
|
||||
int nextpage;
|
||||
bool isindex;
|
||||
Oid reltablespace;
|
||||
Oid reldatabase;
|
||||
Oid relfilenode;
|
||||
Size avgrequest;
|
||||
BlockNumber interestingpages;
|
||||
int storedpages;
|
||||
int nextpage;
|
||||
bool isindex;
|
||||
} FreeSpaceRelationsRec;
|
||||
|
||||
|
||||
@ -66,8 +66,8 @@ typedef struct
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
TupleDesc tupdesc;
|
||||
FreeSpacePagesRec *record;
|
||||
TupleDesc tupdesc;
|
||||
FreeSpacePagesRec *record;
|
||||
} FreeSpacePagesContext;
|
||||
|
||||
|
||||
@ -76,8 +76,8 @@ typedef struct
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
TupleDesc tupdesc;
|
||||
FreeSpaceRelationsRec *record;
|
||||
TupleDesc tupdesc;
|
||||
FreeSpaceRelationsRec *record;
|
||||
} FreeSpaceRelationsContext;
|
||||
|
||||
|
||||
@ -89,21 +89,21 @@ PG_FUNCTION_INFO_V1(pg_freespacemap_pages);
|
||||
Datum
|
||||
pg_freespacemap_pages(PG_FUNCTION_ARGS)
|
||||
{
|
||||
FuncCallContext *funcctx;
|
||||
Datum result;
|
||||
MemoryContext oldcontext;
|
||||
FreeSpacePagesContext *fctx; /* User function context. */
|
||||
TupleDesc tupledesc;
|
||||
HeapTuple tuple;
|
||||
FSMHeader *FreeSpaceMap; /* FSM main structure. */
|
||||
FSMRelation *fsmrel; /* Individual relation. */
|
||||
FuncCallContext *funcctx;
|
||||
Datum result;
|
||||
MemoryContext oldcontext;
|
||||
FreeSpacePagesContext *fctx; /* User function context. */
|
||||
TupleDesc tupledesc;
|
||||
HeapTuple tuple;
|
||||
FSMHeader *FreeSpaceMap; /* FSM main structure. */
|
||||
FSMRelation *fsmrel; /* Individual relation. */
|
||||
|
||||
if (SRF_IS_FIRSTCALL())
|
||||
{
|
||||
int i;
|
||||
int numPages; /* Max possible no. of pages in map. */
|
||||
int nPages; /* Mapped pages for a relation. */
|
||||
|
||||
int i;
|
||||
int numPages; /* Max possible no. of pages in map. */
|
||||
int nPages; /* Mapped pages for a relation. */
|
||||
|
||||
/*
|
||||
* Get the free space map data structure.
|
||||
*/
|
||||
@ -138,8 +138,8 @@ pg_freespacemap_pages(PG_FUNCTION_ARGS)
|
||||
fctx->tupdesc = BlessTupleDesc(tupledesc);
|
||||
|
||||
/*
|
||||
* Allocate numPages worth of FreeSpacePagesRec records, this is
|
||||
* an upper bound.
|
||||
* Allocate numPages worth of FreeSpacePagesRec records, this is an
|
||||
* upper bound.
|
||||
*/
|
||||
fctx->record = (FreeSpacePagesRec *) palloc(sizeof(FreeSpacePagesRec) * numPages);
|
||||
|
||||
@ -147,16 +147,16 @@ pg_freespacemap_pages(PG_FUNCTION_ARGS)
|
||||
MemoryContextSwitchTo(oldcontext);
|
||||
|
||||
/*
|
||||
* Lock free space map and scan though all the relations.
|
||||
* For each relation, gets all its mapped pages.
|
||||
* Lock free space map and scan though all the relations. For each
|
||||
* relation, gets all its mapped pages.
|
||||
*/
|
||||
LWLockAcquire(FreeSpaceLock, LW_EXCLUSIVE);
|
||||
|
||||
i = 0;
|
||||
|
||||
for (fsmrel = FreeSpaceMap->usageList; fsmrel; fsmrel = fsmrel->nextUsage)
|
||||
for (fsmrel = FreeSpaceMap->usageList; fsmrel; fsmrel = fsmrel->nextUsage)
|
||||
{
|
||||
if (fsmrel->isIndex)
|
||||
if (fsmrel->isIndex)
|
||||
{
|
||||
/* Index relation. */
|
||||
IndexFSMPageData *page;
|
||||
@ -169,9 +169,9 @@ pg_freespacemap_pages(PG_FUNCTION_ARGS)
|
||||
fctx->record[i].reltablespace = fsmrel->key.spcNode;
|
||||
fctx->record[i].reldatabase = fsmrel->key.dbNode;
|
||||
fctx->record[i].relfilenode = fsmrel->key.relNode;
|
||||
fctx->record[i].relblocknumber = IndexFSMPageGetPageNum(page);
|
||||
fctx->record[i].bytes = 0;
|
||||
fctx->record[i].isindex = true;
|
||||
fctx->record[i].relblocknumber = IndexFSMPageGetPageNum(page);
|
||||
fctx->record[i].bytes = 0;
|
||||
fctx->record[i].isindex = true;
|
||||
|
||||
page++;
|
||||
i++;
|
||||
@ -191,9 +191,9 @@ pg_freespacemap_pages(PG_FUNCTION_ARGS)
|
||||
fctx->record[i].reldatabase = fsmrel->key.dbNode;
|
||||
fctx->record[i].relfilenode = fsmrel->key.relNode;
|
||||
fctx->record[i].relblocknumber = FSMPageGetPageNum(page);
|
||||
fctx->record[i].bytes = FSMPageGetSpace(page);
|
||||
fctx->record[i].isindex = false;
|
||||
|
||||
fctx->record[i].bytes = FSMPageGetSpace(page);
|
||||
fctx->record[i].isindex = false;
|
||||
|
||||
page++;
|
||||
i++;
|
||||
}
|
||||
@ -216,7 +216,7 @@ pg_freespacemap_pages(PG_FUNCTION_ARGS)
|
||||
if (funcctx->call_cntr < funcctx->max_calls)
|
||||
{
|
||||
int i = funcctx->call_cntr;
|
||||
FreeSpacePagesRec *record = &fctx->record[i];
|
||||
FreeSpacePagesRec *record = &fctx->record[i];
|
||||
Datum values[NUM_FREESPACE_PAGES_ELEM];
|
||||
bool nulls[NUM_FREESPACE_PAGES_ELEM];
|
||||
|
||||
@ -261,20 +261,20 @@ PG_FUNCTION_INFO_V1(pg_freespacemap_relations);
|
||||
Datum
|
||||
pg_freespacemap_relations(PG_FUNCTION_ARGS)
|
||||
{
|
||||
FuncCallContext *funcctx;
|
||||
Datum result;
|
||||
MemoryContext oldcontext;
|
||||
FreeSpaceRelationsContext *fctx; /* User function context. */
|
||||
TupleDesc tupledesc;
|
||||
HeapTuple tuple;
|
||||
FSMHeader *FreeSpaceMap; /* FSM main structure. */
|
||||
FSMRelation *fsmrel; /* Individual relation. */
|
||||
FuncCallContext *funcctx;
|
||||
Datum result;
|
||||
MemoryContext oldcontext;
|
||||
FreeSpaceRelationsContext *fctx; /* User function context. */
|
||||
TupleDesc tupledesc;
|
||||
HeapTuple tuple;
|
||||
FSMHeader *FreeSpaceMap; /* FSM main structure. */
|
||||
FSMRelation *fsmrel; /* Individual relation. */
|
||||
|
||||
if (SRF_IS_FIRSTCALL())
|
||||
{
|
||||
int i;
|
||||
int numRelations; /* Max no. of Relations in map. */
|
||||
|
||||
int i;
|
||||
int numRelations; /* Max no. of Relations in map. */
|
||||
|
||||
/*
|
||||
* Get the free space map data structure.
|
||||
*/
|
||||
@ -313,8 +313,8 @@ pg_freespacemap_relations(PG_FUNCTION_ARGS)
|
||||
fctx->tupdesc = BlessTupleDesc(tupledesc);
|
||||
|
||||
/*
|
||||
* Allocate numRelations worth of FreeSpaceRelationsRec records,
|
||||
* this is also an upper bound.
|
||||
* Allocate numRelations worth of FreeSpaceRelationsRec records, this
|
||||
* is also an upper bound.
|
||||
*/
|
||||
fctx->record = (FreeSpaceRelationsRec *) palloc(sizeof(FreeSpaceRelationsRec) * numRelations);
|
||||
|
||||
@ -328,12 +328,12 @@ pg_freespacemap_relations(PG_FUNCTION_ARGS)
|
||||
|
||||
i = 0;
|
||||
|
||||
for (fsmrel = FreeSpaceMap->usageList; fsmrel; fsmrel = fsmrel->nextUsage)
|
||||
for (fsmrel = FreeSpaceMap->usageList; fsmrel; fsmrel = fsmrel->nextUsage)
|
||||
{
|
||||
fctx->record[i].reltablespace = fsmrel->key.spcNode;
|
||||
fctx->record[i].reldatabase = fsmrel->key.dbNode;
|
||||
fctx->record[i].relfilenode = fsmrel->key.relNode;
|
||||
fctx->record[i].avgrequest = (int64)fsmrel->avgRequest;
|
||||
fctx->record[i].avgrequest = (int64) fsmrel->avgRequest;
|
||||
fctx->record[i].interestingpages = fsmrel->interestingPages;
|
||||
fctx->record[i].storedpages = fsmrel->storedPages;
|
||||
fctx->record[i].nextpage = fsmrel->nextPage;
|
||||
@ -358,7 +358,7 @@ pg_freespacemap_relations(PG_FUNCTION_ARGS)
|
||||
if (funcctx->call_cntr < funcctx->max_calls)
|
||||
{
|
||||
int i = funcctx->call_cntr;
|
||||
FreeSpaceRelationsRec *record = &fctx->record[i];
|
||||
FreeSpaceRelationsRec *record = &fctx->record[i];
|
||||
Datum values[NUM_FREESPACE_RELATIONS_ELEM];
|
||||
bool nulls[NUM_FREESPACE_RELATIONS_ELEM];
|
||||
|
||||
@ -368,6 +368,7 @@ pg_freespacemap_relations(PG_FUNCTION_ARGS)
|
||||
nulls[1] = false;
|
||||
values[2] = ObjectIdGetDatum(record->relfilenode);
|
||||
nulls[2] = false;
|
||||
|
||||
/*
|
||||
* avgrequest isn't meaningful for an index
|
||||
*/
|
||||
|
@ -307,7 +307,7 @@ sizebitvec(BITVECP sign)
|
||||
i;
|
||||
|
||||
LOOPBYTE(
|
||||
size += number_of_ones[(unsigned char) sign[i]];
|
||||
size += number_of_ones[(unsigned char) sign[i]];
|
||||
);
|
||||
return size;
|
||||
}
|
||||
@ -320,8 +320,8 @@ hemdistsign(BITVECP a, BITVECP b)
|
||||
dist = 0;
|
||||
|
||||
LOOPBYTE(
|
||||
diff = (unsigned char) (a[i] ^ b[i]);
|
||||
dist += number_of_ones[diff];
|
||||
diff = (unsigned char) (a[i] ^ b[i]);
|
||||
dist += number_of_ones[diff];
|
||||
);
|
||||
return dist;
|
||||
}
|
||||
@ -393,7 +393,7 @@ typedef struct
|
||||
{
|
||||
OffsetNumber pos;
|
||||
int4 cost;
|
||||
} SPLITCOST;
|
||||
} SPLITCOST;
|
||||
|
||||
static int
|
||||
comparecost(const void *a, const void *b)
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* $PostgreSQL: pgsql/contrib/pgbench/pgbench.c,v 1.55 2006/09/16 13:31:40 tgl Exp $
|
||||
* $PostgreSQL: pgsql/contrib/pgbench/pgbench.c,v 1.56 2006/10/04 00:29:45 momjian Exp $
|
||||
*
|
||||
* pgbench: a simple benchmark program for PostgreSQL
|
||||
* written by Tatsuo Ishii
|
||||
@ -136,7 +136,7 @@ int num_files; /* its number */
|
||||
static char *tpc_b = {
|
||||
"\\set nbranches :scale\n"
|
||||
"\\set ntellers 10 * :scale\n"
|
||||
"\\set naccounts 100000 * :scale\n"
|
||||
"\\set naccounts 100000 * :scale\n"
|
||||
"\\setrandom aid 1 :naccounts\n"
|
||||
"\\setrandom bid 1 :nbranches\n"
|
||||
"\\setrandom tid 1 :ntellers\n"
|
||||
@ -154,7 +154,7 @@ static char *tpc_b = {
|
||||
static char *simple_update = {
|
||||
"\\set nbranches :scale\n"
|
||||
"\\set ntellers 10 * :scale\n"
|
||||
"\\set naccounts 100000 * :scale\n"
|
||||
"\\set naccounts 100000 * :scale\n"
|
||||
"\\setrandom aid 1 :naccounts\n"
|
||||
"\\setrandom bid 1 :nbranches\n"
|
||||
"\\setrandom tid 1 :ntellers\n"
|
||||
@ -168,7 +168,7 @@ static char *simple_update = {
|
||||
|
||||
/* -S case */
|
||||
static char *select_only = {
|
||||
"\\set naccounts 100000 * :scale\n"
|
||||
"\\set naccounts 100000 * :scale\n"
|
||||
"\\setrandom aid 1 :naccounts\n"
|
||||
"SELECT abalance FROM accounts WHERE aid = :aid;\n"
|
||||
};
|
||||
@ -338,7 +338,7 @@ putVariable(CState * st, char *name, char *value)
|
||||
}
|
||||
else
|
||||
{
|
||||
char *val;
|
||||
char *val;
|
||||
|
||||
if ((val = strdup(value)) == NULL)
|
||||
return false;
|
||||
@ -1009,14 +1009,16 @@ process_file(char *filename)
|
||||
while (isspace((unsigned char) buf[i]))
|
||||
i++;
|
||||
|
||||
if (buf[i] != '\0' && strncmp(&buf[i], "--", 2) != 0) {
|
||||
if (buf[i] != '\0' && strncmp(&buf[i], "--", 2) != 0)
|
||||
{
|
||||
commands = process_commands(&buf[i]);
|
||||
if (commands == NULL)
|
||||
{
|
||||
fclose(fd);
|
||||
return false;
|
||||
}
|
||||
} else
|
||||
}
|
||||
else
|
||||
continue;
|
||||
|
||||
my_commands[lineno] = commands;
|
||||
@ -1530,7 +1532,7 @@ main(int argc, char **argv)
|
||||
if (state[i].ecnt > prev_ecnt && commands[state[i].state]->type == META_COMMAND)
|
||||
{
|
||||
fprintf(stderr, "Client %d aborted in state %d. Execution meta-command failed.\n", i, state[i].state);
|
||||
remains--; /* I've aborted */
|
||||
remains--; /* I've aborted */
|
||||
PQfinish(state[i].con);
|
||||
state[i].con = NULL;
|
||||
}
|
||||
@ -1610,7 +1612,7 @@ main(int argc, char **argv)
|
||||
if (state[i].ecnt > prev_ecnt && commands[state[i].state]->type == META_COMMAND)
|
||||
{
|
||||
fprintf(stderr, "Client %d aborted in state %d. Execution meta-command failed.\n", i, state[i].state);
|
||||
remains--; /* I've aborted */
|
||||
remains--; /* I've aborted */
|
||||
PQfinish(state[i].con);
|
||||
state[i].con = NULL;
|
||||
}
|
||||
|
@ -2,7 +2,7 @@
|
||||
* Written by Solar Designer and placed in the public domain.
|
||||
* See crypt_blowfish.c for more information.
|
||||
*
|
||||
* $PostgreSQL: pgsql/contrib/pgcrypto/crypt-gensalt.c,v 1.9 2006/07/13 04:15:24 neilc Exp $
|
||||
* $PostgreSQL: pgsql/contrib/pgcrypto/crypt-gensalt.c,v 1.10 2006/10/04 00:29:46 momjian Exp $
|
||||
*
|
||||
* This file contains salt generation functions for the traditional and
|
||||
* other common crypt(3) algorithms, except for bcrypt which is defined
|
||||
@ -64,9 +64,9 @@ _crypt_gensalt_extended_rn(unsigned long count,
|
||||
output[2] = _crypt_itoa64[(count >> 6) & 0x3f];
|
||||
output[3] = _crypt_itoa64[(count >> 12) & 0x3f];
|
||||
output[4] = _crypt_itoa64[(count >> 18) & 0x3f];
|
||||
value = (unsigned long)(unsigned char) input[0] |
|
||||
((unsigned long)(unsigned char) input[1] << 8) |
|
||||
((unsigned long)(unsigned char) input[2] << 16);
|
||||
value = (unsigned long) (unsigned char) input[0] |
|
||||
((unsigned long) (unsigned char) input[1] << 8) |
|
||||
((unsigned long) (unsigned char) input[2] << 16);
|
||||
output[5] = _crypt_itoa64[value & 0x3f];
|
||||
output[6] = _crypt_itoa64[(value >> 6) & 0x3f];
|
||||
output[7] = _crypt_itoa64[(value >> 12) & 0x3f];
|
||||
@ -92,9 +92,9 @@ _crypt_gensalt_md5_rn(unsigned long count,
|
||||
output[0] = '$';
|
||||
output[1] = '1';
|
||||
output[2] = '$';
|
||||
value = (unsigned long)(unsigned char) input[0] |
|
||||
((unsigned long)(unsigned char) input[1] << 8) |
|
||||
((unsigned long)(unsigned char) input[2] << 16);
|
||||
value = (unsigned long) (unsigned char) input[0] |
|
||||
((unsigned long) (unsigned char) input[1] << 8) |
|
||||
((unsigned long) (unsigned char) input[2] << 16);
|
||||
output[3] = _crypt_itoa64[value & 0x3f];
|
||||
output[4] = _crypt_itoa64[(value >> 6) & 0x3f];
|
||||
output[5] = _crypt_itoa64[(value >> 12) & 0x3f];
|
||||
@ -103,9 +103,9 @@ _crypt_gensalt_md5_rn(unsigned long count,
|
||||
|
||||
if (size >= 6 && output_size >= 3 + 4 + 4 + 1)
|
||||
{
|
||||
value = (unsigned long)(unsigned char) input[3] |
|
||||
((unsigned long)(unsigned char) input[4] << 8) |
|
||||
((unsigned long)(unsigned char) input[5] << 16);
|
||||
value = (unsigned long) (unsigned char) input[3] |
|
||||
((unsigned long) (unsigned char) input[4] << 8) |
|
||||
((unsigned long) (unsigned char) input[5] << 16);
|
||||
output[7] = _crypt_itoa64[value & 0x3f];
|
||||
output[8] = _crypt_itoa64[(value >> 6) & 0x3f];
|
||||
output[9] = _crypt_itoa64[(value >> 12) & 0x3f];
|
||||
|
@ -8,7 +8,7 @@
|
||||
*
|
||||
* $FreeBSD: src/lib/libcrypt/crypt-md5.c,v 1.5 1999/12/17 20:21:45 peter Exp $
|
||||
*
|
||||
* $PostgreSQL: pgsql/contrib/pgcrypto/crypt-md5.c,v 1.7 2006/07/13 04:15:24 neilc Exp $
|
||||
* $PostgreSQL: pgsql/contrib/pgcrypto/crypt-md5.c,v 1.8 2006/10/04 00:29:46 momjian Exp $
|
||||
*/
|
||||
|
||||
#include "postgres.h"
|
||||
@ -24,7 +24,7 @@ static const char _crypt_a64[] =
|
||||
static void
|
||||
_crypt_to64(char *s, unsigned long v, int n)
|
||||
{
|
||||
while (--n >= 0)
|
||||
while (--n >= 0)
|
||||
{
|
||||
*s++ = _crypt_a64[v & 0x3f];
|
||||
v >>= 6;
|
||||
|
@ -26,7 +26,7 @@
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* $PostgreSQL: pgsql/contrib/pgcrypto/fortuna.c,v 1.7 2006/07/13 04:15:24 neilc Exp $
|
||||
* $PostgreSQL: pgsql/contrib/pgcrypto/fortuna.c,v 1.8 2006/10/04 00:29:46 momjian Exp $
|
||||
*/
|
||||
|
||||
#include "postgres.h"
|
||||
@ -365,8 +365,8 @@ rekey(FState * st)
|
||||
static void
|
||||
startup_tricks(FState * st)
|
||||
{
|
||||
int i;
|
||||
uint8 buf[BLOCK];
|
||||
int i;
|
||||
uint8 buf[BLOCK];
|
||||
|
||||
/* Use next block as counter. */
|
||||
encrypt_counter(st, st->counter);
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -1,8 +1,8 @@
|
||||
/*
|
||||
Name: imath.h
|
||||
Purpose: Arbitrary precision integer arithmetic routines.
|
||||
Author: M. J. Fromberger <http://www.dartmouth.edu/~sting/>
|
||||
Info: Id: imath.h 21 2006-04-02 18:58:36Z sting
|
||||
Name: imath.h
|
||||
Purpose: Arbitrary precision integer arithmetic routines.
|
||||
Author: M. J. Fromberger <http://www.dartmouth.edu/~sting/>
|
||||
Info: Id: imath.h 21 2006-04-02 18:58:36Z sting
|
||||
|
||||
Copyright (C) 2002 Michael J. Fromberger, All Rights Reserved.
|
||||
|
||||
@ -20,13 +20,13 @@
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
|
||||
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
|
||||
BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
|
||||
ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
*/
|
||||
/* $PostgreSQL: pgsql/contrib/pgcrypto/imath.h,v 1.4 2006/07/19 17:05:50 neilc Exp $ */
|
||||
/* $PostgreSQL: pgsql/contrib/pgcrypto/imath.h,v 1.5 2006/10/04 00:29:46 momjian Exp $ */
|
||||
|
||||
#ifndef IMATH_H_
|
||||
#define IMATH_H_
|
||||
@ -36,32 +36,36 @@
|
||||
|
||||
#include <limits.h>
|
||||
|
||||
typedef unsigned char mp_sign;
|
||||
typedef unsigned int mp_size;
|
||||
typedef int mp_result;
|
||||
typedef unsigned char mp_sign;
|
||||
typedef unsigned int mp_size;
|
||||
typedef int mp_result;
|
||||
|
||||
#ifdef USE_LONG_LONG
|
||||
typedef uint32 mp_digit;
|
||||
typedef uint64 mp_word;
|
||||
#define MP_DIGIT_MAX 0xFFFFFFFFULL
|
||||
#define MP_WORD_MAX 0xFFFFFFFFFFFFFFFFULL
|
||||
typedef uint32 mp_digit;
|
||||
typedef uint64 mp_word;
|
||||
|
||||
#define MP_DIGIT_MAX 0xFFFFFFFFULL
|
||||
#define MP_WORD_MAX 0xFFFFFFFFFFFFFFFFULL
|
||||
#else
|
||||
typedef uint16 mp_digit;
|
||||
typedef uint32 mp_word;
|
||||
#define MP_DIGIT_MAX 0xFFFFUL
|
||||
#define MP_WORD_MAX 0xFFFFFFFFUL
|
||||
typedef uint16 mp_digit;
|
||||
typedef uint32 mp_word;
|
||||
|
||||
#define MP_DIGIT_MAX 0xFFFFUL
|
||||
#define MP_WORD_MAX 0xFFFFFFFFUL
|
||||
#endif
|
||||
|
||||
typedef struct mpz {
|
||||
mp_digit *digits;
|
||||
mp_size alloc;
|
||||
mp_size used;
|
||||
mp_sign sign;
|
||||
} mpz_t, *mp_int;
|
||||
typedef struct mpz
|
||||
{
|
||||
mp_digit *digits;
|
||||
mp_size alloc;
|
||||
mp_size used;
|
||||
mp_sign sign;
|
||||
} mpz_t, *mp_int;
|
||||
|
||||
#define MP_DIGITS(Z) ((Z)->digits)
|
||||
#define MP_ALLOC(Z) ((Z)->alloc)
|
||||
#define MP_USED(Z) ((Z)->used)
|
||||
#define MP_SIGN(Z) ((Z)->sign)
|
||||
#define MP_USED(Z) ((Z)->used)
|
||||
#define MP_SIGN(Z) ((Z)->sign)
|
||||
|
||||
extern const mp_result MP_OK;
|
||||
extern const mp_result MP_FALSE;
|
||||
@ -72,131 +76,140 @@ extern const mp_result MP_UNDEF;
|
||||
extern const mp_result MP_TRUNC;
|
||||
extern const mp_result MP_BADARG;
|
||||
|
||||
#define MP_DIGIT_BIT (sizeof(mp_digit) * CHAR_BIT)
|
||||
#define MP_WORD_BIT (sizeof(mp_word) * CHAR_BIT)
|
||||
#define MP_DIGIT_BIT (sizeof(mp_digit) * CHAR_BIT)
|
||||
#define MP_WORD_BIT (sizeof(mp_word) * CHAR_BIT)
|
||||
|
||||
#define MP_MIN_RADIX 2
|
||||
#define MP_MAX_RADIX 36
|
||||
#define MP_MIN_RADIX 2
|
||||
#define MP_MAX_RADIX 36
|
||||
|
||||
extern const mp_sign MP_NEG;
|
||||
extern const mp_sign MP_ZPOS;
|
||||
extern const mp_sign MP_NEG;
|
||||
extern const mp_sign MP_ZPOS;
|
||||
|
||||
#define mp_int_is_odd(Z) ((Z)->digits[0] & 1)
|
||||
#define mp_int_is_even(Z) !((Z)->digits[0] & 1)
|
||||
|
||||
mp_size mp_get_default_precision(void);
|
||||
void mp_set_default_precision(mp_size s);
|
||||
mp_size mp_get_multiply_threshold(void);
|
||||
void mp_set_multiply_threshold(mp_size s);
|
||||
mp_size mp_get_default_precision(void);
|
||||
void mp_set_default_precision(mp_size s);
|
||||
mp_size mp_get_multiply_threshold(void);
|
||||
void mp_set_multiply_threshold(mp_size s);
|
||||
|
||||
mp_result mp_int_init(mp_int z);
|
||||
mp_int mp_int_alloc(void);
|
||||
mp_result mp_int_init_size(mp_int z, mp_size prec);
|
||||
mp_result mp_int_init_copy(mp_int z, mp_int old);
|
||||
mp_result mp_int_init_value(mp_int z, int value);
|
||||
mp_result mp_int_set_value(mp_int z, int value);
|
||||
void mp_int_clear(mp_int z);
|
||||
void mp_int_free(mp_int z);
|
||||
mp_result mp_int_init(mp_int z);
|
||||
mp_int mp_int_alloc(void);
|
||||
mp_result mp_int_init_size(mp_int z, mp_size prec);
|
||||
mp_result mp_int_init_copy(mp_int z, mp_int old);
|
||||
mp_result mp_int_init_value(mp_int z, int value);
|
||||
mp_result mp_int_set_value(mp_int z, int value);
|
||||
void mp_int_clear(mp_int z);
|
||||
void mp_int_free(mp_int z);
|
||||
|
||||
mp_result mp_int_copy(mp_int a, mp_int c); /* c = a */
|
||||
void mp_int_swap(mp_int a, mp_int c); /* swap a, c */
|
||||
void mp_int_zero(mp_int z); /* z = 0 */
|
||||
mp_result mp_int_abs(mp_int a, mp_int c); /* c = |a| */
|
||||
mp_result mp_int_neg(mp_int a, mp_int c); /* c = -a */
|
||||
mp_result mp_int_add(mp_int a, mp_int b, mp_int c); /* c = a + b */
|
||||
mp_result mp_int_add_value(mp_int a, int value, mp_int c);
|
||||
mp_result mp_int_sub(mp_int a, mp_int b, mp_int c); /* c = a - b */
|
||||
mp_result mp_int_sub_value(mp_int a, int value, mp_int c);
|
||||
mp_result mp_int_mul(mp_int a, mp_int b, mp_int c); /* c = a * b */
|
||||
mp_result mp_int_mul_value(mp_int a, int value, mp_int c);
|
||||
mp_result mp_int_mul_pow2(mp_int a, int p2, mp_int c);
|
||||
mp_result mp_int_sqr(mp_int a, mp_int c); /* c = a * a */
|
||||
mp_result
|
||||
mp_int_div(mp_int a, mp_int b, /* q = a / b */
|
||||
mp_int q, mp_int r); /* r = a % b */
|
||||
mp_result
|
||||
mp_int_div_value(mp_int a, int value, /* q = a / value */
|
||||
mp_int q, int *r); /* r = a % value */
|
||||
mp_result
|
||||
mp_int_div_pow2(mp_int a, int p2, /* q = a / 2^p2 */
|
||||
mp_int q, mp_int r); /* r = q % 2^p2 */
|
||||
mp_result mp_int_mod(mp_int a, mp_int m, mp_int c); /* c = a % m */
|
||||
|
||||
mp_result mp_int_copy(mp_int a, mp_int c); /* c = a */
|
||||
void mp_int_swap(mp_int a, mp_int c); /* swap a, c */
|
||||
void mp_int_zero(mp_int z); /* z = 0 */
|
||||
mp_result mp_int_abs(mp_int a, mp_int c); /* c = |a| */
|
||||
mp_result mp_int_neg(mp_int a, mp_int c); /* c = -a */
|
||||
mp_result mp_int_add(mp_int a, mp_int b, mp_int c); /* c = a + b */
|
||||
mp_result mp_int_add_value(mp_int a, int value, mp_int c);
|
||||
mp_result mp_int_sub(mp_int a, mp_int b, mp_int c); /* c = a - b */
|
||||
mp_result mp_int_sub_value(mp_int a, int value, mp_int c);
|
||||
mp_result mp_int_mul(mp_int a, mp_int b, mp_int c); /* c = a * b */
|
||||
mp_result mp_int_mul_value(mp_int a, int value, mp_int c);
|
||||
mp_result mp_int_mul_pow2(mp_int a, int p2, mp_int c);
|
||||
mp_result mp_int_sqr(mp_int a, mp_int c); /* c = a * a */
|
||||
mp_result mp_int_div(mp_int a, mp_int b, /* q = a / b */
|
||||
mp_int q, mp_int r); /* r = a % b */
|
||||
mp_result mp_int_div_value(mp_int a, int value, /* q = a / value */
|
||||
mp_int q, int *r); /* r = a % value */
|
||||
mp_result mp_int_div_pow2(mp_int a, int p2, /* q = a / 2^p2 */
|
||||
mp_int q, mp_int r); /* r = q % 2^p2 */
|
||||
mp_result mp_int_mod(mp_int a, mp_int m, mp_int c); /* c = a % m */
|
||||
#define mp_int_mod_value(A, V, R) mp_int_div_value((A), (V), 0, (R))
|
||||
mp_result mp_int_expt(mp_int a, int b, mp_int c); /* c = a^b */
|
||||
mp_result mp_int_expt_value(int a, int b, mp_int c); /* c = a^b */
|
||||
mp_result mp_int_expt(mp_int a, int b, mp_int c); /* c = a^b */
|
||||
mp_result mp_int_expt_value(int a, int b, mp_int c); /* c = a^b */
|
||||
|
||||
int mp_int_compare(mp_int a, mp_int b); /* a <=> b */
|
||||
int mp_int_compare_unsigned(mp_int a, mp_int b); /* |a| <=> |b| */
|
||||
int mp_int_compare_zero(mp_int z); /* a <=> 0 */
|
||||
int mp_int_compare_value(mp_int z, int value); /* a <=> v */
|
||||
int mp_int_compare(mp_int a, mp_int b); /* a <=> b */
|
||||
int mp_int_compare_unsigned(mp_int a, mp_int b); /* |a| <=> |b| */
|
||||
int mp_int_compare_zero(mp_int z); /* a <=> 0 */
|
||||
int mp_int_compare_value(mp_int z, int value); /* a <=> v */
|
||||
|
||||
/* Returns true if v|a, false otherwise (including errors) */
|
||||
int mp_int_divisible_value(mp_int a, int v);
|
||||
int mp_int_divisible_value(mp_int a, int v);
|
||||
|
||||
/* Returns k >= 0 such that z = 2^k, if one exists; otherwise < 0 */
|
||||
int mp_int_is_pow2(mp_int z);
|
||||
int mp_int_is_pow2(mp_int z);
|
||||
|
||||
mp_result mp_int_exptmod(mp_int a, mp_int b, mp_int m,
|
||||
mp_int c); /* c = a^b (mod m) */
|
||||
mp_result mp_int_exptmod_evalue(mp_int a, int value,
|
||||
mp_int m, mp_int c); /* c = a^v (mod m) */
|
||||
mp_result mp_int_exptmod_bvalue(int value, mp_int b,
|
||||
mp_int m, mp_int c); /* c = v^b (mod m) */
|
||||
mp_result mp_int_exptmod_known(mp_int a, mp_int b,
|
||||
mp_int m, mp_int mu,
|
||||
mp_int c); /* c = a^b (mod m) */
|
||||
mp_result mp_int_redux_const(mp_int m, mp_int c);
|
||||
mp_result
|
||||
mp_int_exptmod(mp_int a, mp_int b, mp_int m,
|
||||
mp_int c); /* c = a^b (mod m) */
|
||||
mp_result
|
||||
mp_int_exptmod_evalue(mp_int a, int value,
|
||||
mp_int m, mp_int c); /* c = a^v (mod m) */
|
||||
mp_result
|
||||
mp_int_exptmod_bvalue(int value, mp_int b,
|
||||
mp_int m, mp_int c); /* c = v^b (mod m) */
|
||||
mp_result
|
||||
mp_int_exptmod_known(mp_int a, mp_int b,
|
||||
mp_int m, mp_int mu,
|
||||
mp_int c); /* c = a^b (mod m) */
|
||||
mp_result mp_int_redux_const(mp_int m, mp_int c);
|
||||
|
||||
mp_result mp_int_invmod(mp_int a, mp_int m, mp_int c); /* c = 1/a (mod m) */
|
||||
mp_result mp_int_invmod(mp_int a, mp_int m, mp_int c); /* c = 1/a (mod m) */
|
||||
|
||||
mp_result mp_int_gcd(mp_int a, mp_int b, mp_int c); /* c = gcd(a, b) */
|
||||
mp_result mp_int_gcd(mp_int a, mp_int b, mp_int c); /* c = gcd(a, b) */
|
||||
|
||||
mp_result mp_int_egcd(mp_int a, mp_int b, mp_int c, /* c = gcd(a, b) */
|
||||
mp_int x, mp_int y); /* c = ax + by */
|
||||
mp_result
|
||||
mp_int_egcd(mp_int a, mp_int b, mp_int c, /* c = gcd(a, b) */
|
||||
mp_int x, mp_int y); /* c = ax + by */
|
||||
|
||||
mp_result mp_int_sqrt(mp_int a, mp_int c); /* c = floor(sqrt(q)) */
|
||||
mp_result mp_int_sqrt(mp_int a, mp_int c); /* c = floor(sqrt(q)) */
|
||||
|
||||
/* Convert to an int, if representable (returns MP_RANGE if not). */
|
||||
mp_result mp_int_to_int(mp_int z, int *out);
|
||||
mp_result mp_int_to_int(mp_int z, int *out);
|
||||
|
||||
/* Convert to nul-terminated string with the specified radix, writing at
|
||||
most limit characters including the nul terminator */
|
||||
mp_result mp_int_to_string(mp_int z, mp_size radix,
|
||||
char *str, int limit);
|
||||
mp_result mp_int_to_string(mp_int z, mp_size radix,
|
||||
char *str, int limit);
|
||||
|
||||
/* Return the number of characters required to represent
|
||||
/* Return the number of characters required to represent
|
||||
z in the given radix. May over-estimate. */
|
||||
mp_result mp_int_string_len(mp_int z, mp_size radix);
|
||||
mp_result mp_int_string_len(mp_int z, mp_size radix);
|
||||
|
||||
/* Read zero-terminated string into z */
|
||||
mp_result mp_int_read_string(mp_int z, mp_size radix, const char *str);
|
||||
mp_result mp_int_read_cstring(mp_int z, mp_size radix, const char *str,
|
||||
char **end);
|
||||
mp_result mp_int_read_string(mp_int z, mp_size radix, const char *str);
|
||||
mp_result mp_int_read_cstring(mp_int z, mp_size radix, const char *str,
|
||||
char **end);
|
||||
|
||||
/* Return the number of significant bits in z */
|
||||
mp_result mp_int_count_bits(mp_int z);
|
||||
mp_result mp_int_count_bits(mp_int z);
|
||||
|
||||
/* Convert z to two's complement binary, writing at most limit bytes */
|
||||
mp_result mp_int_to_binary(mp_int z, unsigned char *buf, int limit);
|
||||
mp_result mp_int_to_binary(mp_int z, unsigned char *buf, int limit);
|
||||
|
||||
/* Read a two's complement binary value into z from the given buffer */
|
||||
mp_result mp_int_read_binary(mp_int z, unsigned char *buf, int len);
|
||||
mp_result mp_int_read_binary(mp_int z, unsigned char *buf, int len);
|
||||
|
||||
/* Return the number of bytes required to represent z in binary. */
|
||||
mp_result mp_int_binary_len(mp_int z);
|
||||
mp_result mp_int_binary_len(mp_int z);
|
||||
|
||||
/* Convert z to unsigned binary, writing at most limit bytes */
|
||||
mp_result mp_int_to_unsigned(mp_int z, unsigned char *buf, int limit);
|
||||
mp_result mp_int_to_unsigned(mp_int z, unsigned char *buf, int limit);
|
||||
|
||||
/* Read an unsigned binary value into z from the given buffer */
|
||||
mp_result mp_int_read_unsigned(mp_int z, unsigned char *buf, int len);
|
||||
mp_result mp_int_read_unsigned(mp_int z, unsigned char *buf, int len);
|
||||
|
||||
/* Return the number of bytes required to represent z as unsigned output */
|
||||
mp_result mp_int_unsigned_len(mp_int z);
|
||||
mp_result mp_int_unsigned_len(mp_int z);
|
||||
|
||||
/* Return a statically allocated string describing error code res */
|
||||
const char *mp_error_string(mp_result res);
|
||||
|
||||
#if 0
|
||||
void s_print(char *tag, mp_int z);
|
||||
void s_print_buf(char *tag, mp_digit *buf, mp_size num);
|
||||
void s_print(char *tag, mp_int z);
|
||||
void s_print_buf(char *tag, mp_digit * buf, mp_size num);
|
||||
#endif
|
||||
|
||||
#endif /* end IMATH_H_ */
|
||||
#endif /* end IMATH_H_ */
|
||||
|
@ -26,7 +26,7 @@
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* $PostgreSQL: pgsql/contrib/pgcrypto/internal-sha2.c,v 1.1 2006/07/13 04:15:24 neilc Exp $
|
||||
* $PostgreSQL: pgsql/contrib/pgcrypto/internal-sha2.c,v 1.2 2006/10/04 00:29:46 momjian Exp $
|
||||
*/
|
||||
|
||||
#include "postgres.h"
|
||||
@ -36,10 +36,10 @@
|
||||
#include "px.h"
|
||||
#include "sha2.h"
|
||||
|
||||
void init_sha224(PX_MD * h);
|
||||
void init_sha256(PX_MD * h);
|
||||
void init_sha384(PX_MD * h);
|
||||
void init_sha512(PX_MD * h);
|
||||
void init_sha224(PX_MD * h);
|
||||
void init_sha256(PX_MD * h);
|
||||
void init_sha384(PX_MD * h);
|
||||
void init_sha512(PX_MD * h);
|
||||
|
||||
/* SHA224 */
|
||||
|
||||
@ -314,4 +314,3 @@ init_sha512(PX_MD * md)
|
||||
|
||||
md->reset(md);
|
||||
}
|
||||
|
||||
|
@ -26,7 +26,7 @@
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* $PostgreSQL: pgsql/contrib/pgcrypto/internal.c,v 1.24 2006/07/13 04:15:24 neilc Exp $
|
||||
* $PostgreSQL: pgsql/contrib/pgcrypto/internal.c,v 1.25 2006/10/04 00:29:46 momjian Exp $
|
||||
*/
|
||||
|
||||
#include "postgres.h"
|
||||
@ -78,10 +78,10 @@
|
||||
static void init_md5(PX_MD * h);
|
||||
static void init_sha1(PX_MD * h);
|
||||
|
||||
void init_sha224(PX_MD * h);
|
||||
void init_sha256(PX_MD * h);
|
||||
void init_sha384(PX_MD * h);
|
||||
void init_sha512(PX_MD * h);
|
||||
void init_sha224(PX_MD * h);
|
||||
void init_sha256(PX_MD * h);
|
||||
void init_sha384(PX_MD * h);
|
||||
void init_sha512(PX_MD * h);
|
||||
|
||||
struct int_digest
|
||||
{
|
||||
|
@ -26,7 +26,7 @@
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* $PostgreSQL: pgsql/contrib/pgcrypto/openssl.c,v 1.29 2006/09/05 23:02:28 tgl Exp $
|
||||
* $PostgreSQL: pgsql/contrib/pgcrypto/openssl.c,v 1.30 2006/10/04 00:29:46 momjian Exp $
|
||||
*/
|
||||
|
||||
#include "postgres.h"
|
||||
@ -58,7 +58,6 @@
|
||||
*/
|
||||
|
||||
#include <openssl/aes.h>
|
||||
|
||||
#else /* old OPENSSL */
|
||||
|
||||
/*
|
||||
@ -121,29 +120,32 @@
|
||||
* Emulate newer digest API.
|
||||
*/
|
||||
|
||||
static void EVP_MD_CTX_init(EVP_MD_CTX *ctx)
|
||||
static void
|
||||
EVP_MD_CTX_init(EVP_MD_CTX *ctx)
|
||||
{
|
||||
memset(ctx, 0, sizeof(*ctx));
|
||||
}
|
||||
|
||||
static int EVP_MD_CTX_cleanup(EVP_MD_CTX *ctx)
|
||||
static int
|
||||
EVP_MD_CTX_cleanup(EVP_MD_CTX *ctx)
|
||||
{
|
||||
memset(ctx, 0, sizeof(*ctx));
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int EVP_DigestInit_ex(EVP_MD_CTX *ctx, const EVP_MD *md, void *engine)
|
||||
static int
|
||||
EVP_DigestInit_ex(EVP_MD_CTX *ctx, const EVP_MD *md, void *engine)
|
||||
{
|
||||
EVP_DigestInit(ctx, md);
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int EVP_DigestFinal_ex(EVP_MD_CTX *ctx, unsigned char *res, unsigned int *len)
|
||||
static int
|
||||
EVP_DigestFinal_ex(EVP_MD_CTX *ctx, unsigned char *res, unsigned int *len)
|
||||
{
|
||||
EVP_DigestFinal(ctx, res, len);
|
||||
return 1;
|
||||
}
|
||||
|
||||
#endif /* old OpenSSL */
|
||||
|
||||
/*
|
||||
@ -154,11 +156,12 @@ static int EVP_DigestFinal_ex(EVP_MD_CTX *ctx, unsigned char *res, unsigned int
|
||||
#include "sha2.c"
|
||||
#include "internal-sha2.c"
|
||||
|
||||
typedef void (*init_f)(PX_MD *md);
|
||||
typedef void (*init_f) (PX_MD * md);
|
||||
|
||||
static int compat_find_digest(const char *name, PX_MD **res)
|
||||
static int
|
||||
compat_find_digest(const char *name, PX_MD ** res)
|
||||
{
|
||||
init_f init = NULL;
|
||||
init_f init = NULL;
|
||||
|
||||
if (pg_strcasecmp(name, "sha224") == 0)
|
||||
init = init_sha224;
|
||||
@ -175,7 +178,6 @@ static int compat_find_digest(const char *name, PX_MD **res)
|
||||
init(*res);
|
||||
return 0;
|
||||
}
|
||||
|
||||
#else
|
||||
#define compat_find_digest(name, res) (PXE_NO_HASH)
|
||||
#endif
|
||||
@ -184,29 +186,32 @@ static int compat_find_digest(const char *name, PX_MD **res)
|
||||
* Hashes
|
||||
*/
|
||||
|
||||
typedef struct OSSLDigest {
|
||||
typedef struct OSSLDigest
|
||||
{
|
||||
const EVP_MD *algo;
|
||||
EVP_MD_CTX ctx;
|
||||
} OSSLDigest;
|
||||
EVP_MD_CTX ctx;
|
||||
} OSSLDigest;
|
||||
|
||||
static unsigned
|
||||
digest_result_size(PX_MD * h)
|
||||
{
|
||||
OSSLDigest *digest = (OSSLDigest *)h->p.ptr;
|
||||
OSSLDigest *digest = (OSSLDigest *) h->p.ptr;
|
||||
|
||||
return EVP_MD_CTX_size(&digest->ctx);
|
||||
}
|
||||
|
||||
static unsigned
|
||||
digest_block_size(PX_MD * h)
|
||||
{
|
||||
OSSLDigest *digest = (OSSLDigest *)h->p.ptr;
|
||||
OSSLDigest *digest = (OSSLDigest *) h->p.ptr;
|
||||
|
||||
return EVP_MD_CTX_block_size(&digest->ctx);
|
||||
}
|
||||
|
||||
static void
|
||||
digest_reset(PX_MD * h)
|
||||
{
|
||||
OSSLDigest *digest = (OSSLDigest *)h->p.ptr;
|
||||
OSSLDigest *digest = (OSSLDigest *) h->p.ptr;
|
||||
|
||||
EVP_DigestInit_ex(&digest->ctx, digest->algo, NULL);
|
||||
}
|
||||
@ -214,7 +219,7 @@ digest_reset(PX_MD * h)
|
||||
static void
|
||||
digest_update(PX_MD * h, const uint8 *data, unsigned dlen)
|
||||
{
|
||||
OSSLDigest *digest = (OSSLDigest *)h->p.ptr;
|
||||
OSSLDigest *digest = (OSSLDigest *) h->p.ptr;
|
||||
|
||||
EVP_DigestUpdate(&digest->ctx, data, dlen);
|
||||
}
|
||||
@ -222,7 +227,7 @@ digest_update(PX_MD * h, const uint8 *data, unsigned dlen)
|
||||
static void
|
||||
digest_finish(PX_MD * h, uint8 *dst)
|
||||
{
|
||||
OSSLDigest *digest = (OSSLDigest *)h->p.ptr;
|
||||
OSSLDigest *digest = (OSSLDigest *) h->p.ptr;
|
||||
|
||||
EVP_DigestFinal_ex(&digest->ctx, dst, NULL);
|
||||
}
|
||||
@ -230,7 +235,7 @@ digest_finish(PX_MD * h, uint8 *dst)
|
||||
static void
|
||||
digest_free(PX_MD * h)
|
||||
{
|
||||
OSSLDigest *digest = (OSSLDigest *)h->p.ptr;
|
||||
OSSLDigest *digest = (OSSLDigest *) h->p.ptr;
|
||||
|
||||
EVP_MD_CTX_cleanup(&digest->ctx);
|
||||
|
||||
@ -560,7 +565,7 @@ ossl_des3_ecb_encrypt(PX_Cipher * c, const uint8 *data, unsigned dlen,
|
||||
ossldata *od = c->ptr;
|
||||
|
||||
for (i = 0; i < dlen / bs; i++)
|
||||
DES_ecb3_encrypt((void *)(data + i * bs), (void *)(res + i * bs),
|
||||
DES_ecb3_encrypt((void *) (data + i * bs), (void *) (res + i * bs),
|
||||
&od->u.des3.k1, &od->u.des3.k2, &od->u.des3.k3, 1);
|
||||
return 0;
|
||||
}
|
||||
@ -574,7 +579,7 @@ ossl_des3_ecb_decrypt(PX_Cipher * c, const uint8 *data, unsigned dlen,
|
||||
ossldata *od = c->ptr;
|
||||
|
||||
for (i = 0; i < dlen / bs; i++)
|
||||
DES_ecb3_encrypt((void *)(data + i * bs), (void *)(res + i * bs),
|
||||
DES_ecb3_encrypt((void *) (data + i * bs), (void *) (res + i * bs),
|
||||
&od->u.des3.k1, &od->u.des3.k2, &od->u.des3.k3, 0);
|
||||
return 0;
|
||||
}
|
||||
|
@ -26,7 +26,7 @@
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* $PostgreSQL: pgsql/contrib/pgcrypto/pgcrypto.c,v 1.23 2006/09/05 21:26:48 tgl Exp $
|
||||
* $PostgreSQL: pgsql/contrib/pgcrypto/pgcrypto.c,v 1.24 2006/10/04 00:29:46 momjian Exp $
|
||||
*/
|
||||
|
||||
#include "postgres.h"
|
||||
@ -491,9 +491,9 @@ PG_FUNCTION_INFO_V1(pg_random_bytes);
|
||||
Datum
|
||||
pg_random_bytes(PG_FUNCTION_ARGS)
|
||||
{
|
||||
int err;
|
||||
int len = PG_GETARG_INT32(0);
|
||||
bytea *res;
|
||||
int err;
|
||||
int len = PG_GETARG_INT32(0);
|
||||
bytea *res;
|
||||
|
||||
if (len < 1 || len > 1024)
|
||||
ereport(ERROR,
|
||||
@ -504,7 +504,7 @@ pg_random_bytes(PG_FUNCTION_ARGS)
|
||||
VARATT_SIZEP(res) = VARHDRSZ + len;
|
||||
|
||||
/* generate result */
|
||||
err = px_get_random_bytes((uint8*)VARDATA(res), len);
|
||||
err = px_get_random_bytes((uint8 *) VARDATA(res), len);
|
||||
if (err < 0)
|
||||
ereport(ERROR,
|
||||
(errcode(ERRCODE_EXTERNAL_ROUTINE_INVOCATION_EXCEPTION),
|
||||
|
@ -26,7 +26,7 @@
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* $PostgreSQL: pgsql/contrib/pgcrypto/pgp-mpi-internal.c,v 1.6 2006/07/13 04:52:51 neilc Exp $
|
||||
* $PostgreSQL: pgsql/contrib/pgcrypto/pgp-mpi-internal.c,v 1.7 2006/10/04 00:29:46 momjian Exp $
|
||||
*/
|
||||
#include "postgres.h"
|
||||
|
||||
@ -36,14 +36,17 @@
|
||||
#include "mbuf.h"
|
||||
#include "pgp.h"
|
||||
|
||||
static mpz_t *mp_new()
|
||||
static mpz_t *
|
||||
mp_new()
|
||||
{
|
||||
mpz_t *mp = mp_int_alloc();
|
||||
mpz_t *mp = mp_int_alloc();
|
||||
|
||||
mp_int_init_size(mp, 256);
|
||||
return mp;
|
||||
}
|
||||
|
||||
static void mp_clear_free(mpz_t *a)
|
||||
static void
|
||||
mp_clear_free(mpz_t * a)
|
||||
{
|
||||
if (!a)
|
||||
return;
|
||||
@ -52,25 +55,29 @@ static void mp_clear_free(mpz_t *a)
|
||||
}
|
||||
|
||||
|
||||
static int mp_px_rand(uint32 bits, mpz_t *res)
|
||||
static int
|
||||
mp_px_rand(uint32 bits, mpz_t * res)
|
||||
{
|
||||
int err;
|
||||
unsigned bytes = (bits + 7) / 8;
|
||||
int last_bits = bits & 7;
|
||||
uint8 *buf;
|
||||
int err;
|
||||
unsigned bytes = (bits + 7) / 8;
|
||||
int last_bits = bits & 7;
|
||||
uint8 *buf;
|
||||
|
||||
buf = px_alloc(bytes);
|
||||
err = px_get_random_bytes(buf, bytes);
|
||||
if (err < 0) {
|
||||
if (err < 0)
|
||||
{
|
||||
px_free(buf);
|
||||
return err;
|
||||
}
|
||||
|
||||
/* clear unnecessary bits and set last bit to one */
|
||||
if (last_bits) {
|
||||
if (last_bits)
|
||||
{
|
||||
buf[0] >>= 8 - last_bits;
|
||||
buf[0] |= 1 << (last_bits - 1);
|
||||
} else
|
||||
}
|
||||
else
|
||||
buf[0] |= 1 << 7;
|
||||
|
||||
mp_int_read_unsigned(res, buf, bytes);
|
||||
@ -80,9 +87,11 @@ static int mp_px_rand(uint32 bits, mpz_t *res)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void mp_modmul(mpz_t *a, mpz_t *b, mpz_t *p, mpz_t *res)
|
||||
static void
|
||||
mp_modmul(mpz_t * a, mpz_t * b, mpz_t * p, mpz_t * res)
|
||||
{
|
||||
mpz_t *tmp = mp_new();
|
||||
mpz_t *tmp = mp_new();
|
||||
|
||||
mp_int_mul(a, b, tmp);
|
||||
mp_int_mod(tmp, p, res);
|
||||
mp_clear_free(tmp);
|
||||
@ -92,6 +101,7 @@ static mpz_t *
|
||||
mpi_to_bn(PGP_MPI * n)
|
||||
{
|
||||
mpz_t *bn = mp_new();
|
||||
|
||||
mp_int_read_unsigned(bn, n->data, n->bytes);
|
||||
|
||||
if (!bn)
|
||||
@ -107,11 +117,11 @@ mpi_to_bn(PGP_MPI * n)
|
||||
}
|
||||
|
||||
static PGP_MPI *
|
||||
bn_to_mpi(mpz_t *bn)
|
||||
bn_to_mpi(mpz_t * bn)
|
||||
{
|
||||
int res;
|
||||
PGP_MPI *n;
|
||||
int bytes;
|
||||
int bytes;
|
||||
|
||||
res = pgp_mpi_alloc(mp_int_count_bits(bn), &n);
|
||||
if (res < 0)
|
||||
|
@ -33,7 +33,7 @@
|
||||
*
|
||||
* $From: sha2.c,v 1.1 2001/11/08 00:01:51 adg Exp adg $
|
||||
*
|
||||
* $PostgreSQL: pgsql/contrib/pgcrypto/sha2.c,v 1.7 2006/07/13 04:15:25 neilc Exp $
|
||||
* $PostgreSQL: pgsql/contrib/pgcrypto/sha2.c,v 1.8 2006/10/04 00:29:46 momjian Exp $
|
||||
*/
|
||||
|
||||
#include "postgres.h"
|
||||
@ -534,7 +534,7 @@ SHA256_Update(SHA256_CTX * context, const uint8 *data, size_t len)
|
||||
}
|
||||
|
||||
static void
|
||||
SHA256_Last(SHA256_CTX *context)
|
||||
SHA256_Last(SHA256_CTX * context)
|
||||
{
|
||||
unsigned int usedspace;
|
||||
|
||||
@ -1023,4 +1023,3 @@ SHA224_Final(uint8 digest[], SHA224_CTX * context)
|
||||
/* Clean up state data: */
|
||||
memset(context, 0, sizeof(*context));
|
||||
}
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* $PostgreSQL: pgsql/contrib/pgrowlocks/pgrowlocks.c,v 1.4 2006/07/13 16:57:31 momjian Exp $
|
||||
* $PostgreSQL: pgsql/contrib/pgrowlocks/pgrowlocks.c,v 1.5 2006/10/04 00:29:46 momjian Exp $
|
||||
*
|
||||
* Copyright (c) 2005-2006 Tatsuo Ishii
|
||||
*
|
||||
@ -63,11 +63,12 @@ extern Datum pgrowlocks(PG_FUNCTION_ARGS);
|
||||
*/
|
||||
#undef MAKERANGEVARFROMNAMELIST_HAS_TWO_ARGS
|
||||
|
||||
typedef struct {
|
||||
typedef struct
|
||||
{
|
||||
Relation rel;
|
||||
HeapScanDesc scan;
|
||||
int ncolumns;
|
||||
} MyData;
|
||||
int ncolumns;
|
||||
} MyData;
|
||||
|
||||
Datum
|
||||
pgrowlocks(PG_FUNCTION_ARGS)
|
||||
@ -78,7 +79,7 @@ pgrowlocks(PG_FUNCTION_ARGS)
|
||||
TupleDesc tupdesc;
|
||||
AttInMetadata *attinmeta;
|
||||
Datum result;
|
||||
MyData *mydata;
|
||||
MyData *mydata;
|
||||
Relation rel;
|
||||
|
||||
if (SRF_IS_FIRSTCALL())
|
||||
@ -96,8 +97,7 @@ pgrowlocks(PG_FUNCTION_ARGS)
|
||||
|
||||
relname = PG_GETARG_TEXT_P(0);
|
||||
#ifdef MAKERANGEVARFROMNAMELIST_HAS_TWO_ARGS
|
||||
relrv = makeRangeVarFromNameList(textToQualifiedNameList(relname, "pgrowlocks"));
|
||||
|
||||
relrv = makeRangeVarFromNameList(textToQualifiedNameList(relname, "pgrowlocks"));
|
||||
#else
|
||||
relrv = makeRangeVarFromNameList(textToQualifiedNameList(relname));
|
||||
#endif
|
||||
@ -114,7 +114,7 @@ pgrowlocks(PG_FUNCTION_ARGS)
|
||||
|
||||
funcctx = SRF_PERCALL_SETUP();
|
||||
attinmeta = funcctx->attinmeta;
|
||||
mydata = (MyData *)funcctx->user_fctx;
|
||||
mydata = (MyData *) funcctx->user_fctx;
|
||||
scan = mydata->scan;
|
||||
|
||||
/* scan the relation */
|
||||
@ -124,16 +124,16 @@ pgrowlocks(PG_FUNCTION_ARGS)
|
||||
LockBuffer(scan->rs_cbuf, BUFFER_LOCK_SHARE);
|
||||
|
||||
if (HeapTupleSatisfiesUpdate(tuple->t_data, GetCurrentCommandId(), scan->rs_cbuf)
|
||||
== HeapTupleBeingUpdated)
|
||||
== HeapTupleBeingUpdated)
|
||||
{
|
||||
|
||||
char **values;
|
||||
int i;
|
||||
char **values;
|
||||
int i;
|
||||
|
||||
values = (char **) palloc(mydata->ncolumns * sizeof(char *));
|
||||
|
||||
i = 0;
|
||||
values[i++] = (char *)DirectFunctionCall1(tidout, PointerGetDatum(&tuple->t_self));
|
||||
values[i++] = (char *) DirectFunctionCall1(tidout, PointerGetDatum(&tuple->t_self));
|
||||
|
||||
#ifdef HEAP_XMAX_SHARED_LOCK
|
||||
if (tuple->t_data->t_infomask & HEAP_XMAX_SHARED_LOCK)
|
||||
@ -143,15 +143,15 @@ pgrowlocks(PG_FUNCTION_ARGS)
|
||||
#else
|
||||
values[i++] = pstrdup("Exclusive");
|
||||
#endif
|
||||
values[i] = palloc(NCHARS*sizeof(char));
|
||||
values[i] = palloc(NCHARS * sizeof(char));
|
||||
snprintf(values[i++], NCHARS, "%d", HeapTupleHeaderGetXmax(tuple->t_data));
|
||||
#ifdef HEAP_XMAX_SHARED_LOCK
|
||||
if (tuple->t_data->t_infomask & HEAP_XMAX_IS_MULTI)
|
||||
{
|
||||
TransactionId *xids;
|
||||
int nxids;
|
||||
int j;
|
||||
int isValidXid = 0; /* any valid xid ever exists? */
|
||||
int nxids;
|
||||
int j;
|
||||
int isValidXid = 0; /* any valid xid ever exists? */
|
||||
|
||||
values[i++] = pstrdup("true");
|
||||
nxids = GetMultiXactIdMembers(HeapTupleHeaderGetXmax(tuple->t_data), &xids);
|
||||
@ -160,45 +160,44 @@ pgrowlocks(PG_FUNCTION_ARGS)
|
||||
elog(ERROR, "GetMultiXactIdMembers returns error");
|
||||
}
|
||||
|
||||
values[i] = palloc(NCHARS*nxids);
|
||||
values[i+1] = palloc(NCHARS*nxids);
|
||||
values[i] = palloc(NCHARS * nxids);
|
||||
values[i + 1] = palloc(NCHARS * nxids);
|
||||
strcpy(values[i], "{");
|
||||
strcpy(values[i+1], "{");
|
||||
strcpy(values[i + 1], "{");
|
||||
|
||||
for (j=0;j<nxids;j++)
|
||||
for (j = 0; j < nxids; j++)
|
||||
{
|
||||
char buf[NCHARS];
|
||||
char buf[NCHARS];
|
||||
|
||||
if (TransactionIdIsInProgress(xids[j]))
|
||||
{
|
||||
if (isValidXid)
|
||||
{
|
||||
strcat(values[i], ",");
|
||||
strcat(values[i+1], ",");
|
||||
strcat(values[i + 1], ",");
|
||||
}
|
||||
snprintf(buf, NCHARS, "%d", xids[j]);
|
||||
strcat(values[i], buf);
|
||||
snprintf(buf, NCHARS, "%d", BackendXidGetPid(xids[j]));
|
||||
strcat(values[i+1], buf);
|
||||
strcat(values[i + 1], buf);
|
||||
|
||||
isValidXid = 1;
|
||||
}
|
||||
}
|
||||
|
||||
strcat(values[i], "}");
|
||||
strcat(values[i+1], "}");
|
||||
strcat(values[i + 1], "}");
|
||||
i++;
|
||||
}
|
||||
else
|
||||
{
|
||||
values[i++] = pstrdup("false");
|
||||
values[i] = palloc(NCHARS*sizeof(char));
|
||||
values[i] = palloc(NCHARS * sizeof(char));
|
||||
snprintf(values[i++], NCHARS, "{%d}", HeapTupleHeaderGetXmax(tuple->t_data));
|
||||
|
||||
values[i] = palloc(NCHARS*sizeof(char));
|
||||
values[i] = palloc(NCHARS * sizeof(char));
|
||||
snprintf(values[i++], NCHARS, "{%d}", BackendXidGetPid(HeapTupleHeaderGetXmax(tuple->t_data)));
|
||||
}
|
||||
|
||||
#else
|
||||
values[i++] = pstrdup("false");
|
||||
values[i++] = pstrdup("{}");
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* $PostgreSQL: pgsql/contrib/pgstattuple/pgstattuple.c,v 1.24 2006/09/04 02:03:04 tgl Exp $
|
||||
* $PostgreSQL: pgsql/contrib/pgstattuple/pgstattuple.c,v 1.25 2006/10/04 00:29:46 momjian Exp $
|
||||
*
|
||||
* Copyright (c) 2001,2002 Tatsuo Ishii
|
||||
*
|
||||
@ -51,36 +51,36 @@ extern Datum pgstattuplebyid(PG_FUNCTION_ARGS);
|
||||
*/
|
||||
typedef struct pgstattuple_type
|
||||
{
|
||||
uint64 table_len;
|
||||
uint64 tuple_count;
|
||||
uint64 tuple_len;
|
||||
uint64 dead_tuple_count;
|
||||
uint64 dead_tuple_len;
|
||||
uint64 free_space; /* free/reusable space in bytes */
|
||||
} pgstattuple_type;
|
||||
uint64 table_len;
|
||||
uint64 tuple_count;
|
||||
uint64 tuple_len;
|
||||
uint64 dead_tuple_count;
|
||||
uint64 dead_tuple_len;
|
||||
uint64 free_space; /* free/reusable space in bytes */
|
||||
} pgstattuple_type;
|
||||
|
||||
typedef void (*pgstat_page)(pgstattuple_type *, Relation, BlockNumber);
|
||||
typedef void (*pgstat_page) (pgstattuple_type *, Relation, BlockNumber);
|
||||
|
||||
static Datum build_pgstattuple_type(pgstattuple_type *stat,
|
||||
FunctionCallInfo fcinfo);
|
||||
static Datum build_pgstattuple_type(pgstattuple_type * stat,
|
||||
FunctionCallInfo fcinfo);
|
||||
static Datum pgstat_relation(Relation rel, FunctionCallInfo fcinfo);
|
||||
static Datum pgstat_heap(Relation rel, FunctionCallInfo fcinfo);
|
||||
static void pgstat_btree_page(pgstattuple_type *stat,
|
||||
Relation rel, BlockNumber blkno);
|
||||
static void pgstat_hash_page(pgstattuple_type *stat,
|
||||
Relation rel, BlockNumber blkno);
|
||||
static void pgstat_gist_page(pgstattuple_type *stat,
|
||||
Relation rel, BlockNumber blkno);
|
||||
static void pgstat_btree_page(pgstattuple_type * stat,
|
||||
Relation rel, BlockNumber blkno);
|
||||
static void pgstat_hash_page(pgstattuple_type * stat,
|
||||
Relation rel, BlockNumber blkno);
|
||||
static void pgstat_gist_page(pgstattuple_type * stat,
|
||||
Relation rel, BlockNumber blkno);
|
||||
static Datum pgstat_index(Relation rel, BlockNumber start,
|
||||
pgstat_page pagefn, FunctionCallInfo fcinfo);
|
||||
static void pgstat_index_page(pgstattuple_type *stat, Page page,
|
||||
OffsetNumber minoff, OffsetNumber maxoff);
|
||||
pgstat_page pagefn, FunctionCallInfo fcinfo);
|
||||
static void pgstat_index_page(pgstattuple_type * stat, Page page,
|
||||
OffsetNumber minoff, OffsetNumber maxoff);
|
||||
|
||||
/*
|
||||
* build_pgstattuple_type -- build a pgstattuple_type tuple
|
||||
*/
|
||||
static Datum
|
||||
build_pgstattuple_type(pgstattuple_type *stat, FunctionCallInfo fcinfo)
|
||||
build_pgstattuple_type(pgstattuple_type * stat, FunctionCallInfo fcinfo)
|
||||
{
|
||||
#define NCOLUMNS 9
|
||||
#define NCHARS 32
|
||||
@ -91,7 +91,7 @@ build_pgstattuple_type(pgstattuple_type *stat, FunctionCallInfo fcinfo)
|
||||
int i;
|
||||
double tuple_percent;
|
||||
double dead_tuple_percent;
|
||||
double free_percent; /* free/reusable space in % */
|
||||
double free_percent; /* free/reusable space in % */
|
||||
TupleDesc tupdesc;
|
||||
AttInMetadata *attinmeta;
|
||||
|
||||
@ -190,49 +190,49 @@ pgstat_relation(Relation rel, FunctionCallInfo fcinfo)
|
||||
{
|
||||
const char *err;
|
||||
|
||||
switch(rel->rd_rel->relkind)
|
||||
switch (rel->rd_rel->relkind)
|
||||
{
|
||||
case RELKIND_RELATION:
|
||||
case RELKIND_TOASTVALUE:
|
||||
case RELKIND_UNCATALOGED:
|
||||
case RELKIND_SEQUENCE:
|
||||
return pgstat_heap(rel, fcinfo);
|
||||
case RELKIND_INDEX:
|
||||
switch(rel->rd_rel->relam)
|
||||
{
|
||||
case BTREE_AM_OID:
|
||||
return pgstat_index(rel, BTREE_METAPAGE + 1,
|
||||
pgstat_btree_page, fcinfo);
|
||||
case HASH_AM_OID:
|
||||
return pgstat_index(rel, HASH_METAPAGE + 1,
|
||||
pgstat_hash_page, fcinfo);
|
||||
case GIST_AM_OID:
|
||||
return pgstat_index(rel, GIST_ROOT_BLKNO + 1,
|
||||
pgstat_gist_page, fcinfo);
|
||||
case GIN_AM_OID:
|
||||
err = "gin index";
|
||||
case RELKIND_RELATION:
|
||||
case RELKIND_TOASTVALUE:
|
||||
case RELKIND_UNCATALOGED:
|
||||
case RELKIND_SEQUENCE:
|
||||
return pgstat_heap(rel, fcinfo);
|
||||
case RELKIND_INDEX:
|
||||
switch (rel->rd_rel->relam)
|
||||
{
|
||||
case BTREE_AM_OID:
|
||||
return pgstat_index(rel, BTREE_METAPAGE + 1,
|
||||
pgstat_btree_page, fcinfo);
|
||||
case HASH_AM_OID:
|
||||
return pgstat_index(rel, HASH_METAPAGE + 1,
|
||||
pgstat_hash_page, fcinfo);
|
||||
case GIST_AM_OID:
|
||||
return pgstat_index(rel, GIST_ROOT_BLKNO + 1,
|
||||
pgstat_gist_page, fcinfo);
|
||||
case GIN_AM_OID:
|
||||
err = "gin index";
|
||||
break;
|
||||
default:
|
||||
err = "unknown index";
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case RELKIND_VIEW:
|
||||
err = "view";
|
||||
break;
|
||||
case RELKIND_COMPOSITE_TYPE:
|
||||
err = "composite type";
|
||||
break;
|
||||
default:
|
||||
err = "unknown index";
|
||||
err = "unknown";
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case RELKIND_VIEW:
|
||||
err = "view";
|
||||
break;
|
||||
case RELKIND_COMPOSITE_TYPE:
|
||||
err = "composite type";
|
||||
break;
|
||||
default:
|
||||
err = "unknown";
|
||||
break;
|
||||
}
|
||||
|
||||
ereport(ERROR,
|
||||
(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
|
||||
errmsg("\"%s\" (%s) is not supported",
|
||||
RelationGetRelationName(rel), err)));
|
||||
return 0; /* should not happen */
|
||||
RelationGetRelationName(rel), err)));
|
||||
return 0; /* should not happen */
|
||||
}
|
||||
|
||||
/*
|
||||
@ -241,13 +241,13 @@ pgstat_relation(Relation rel, FunctionCallInfo fcinfo)
|
||||
static Datum
|
||||
pgstat_heap(Relation rel, FunctionCallInfo fcinfo)
|
||||
{
|
||||
HeapScanDesc scan;
|
||||
HeapTuple tuple;
|
||||
BlockNumber nblocks;
|
||||
BlockNumber block = 0; /* next block to count free space in */
|
||||
BlockNumber tupblock;
|
||||
Buffer buffer;
|
||||
pgstattuple_type stat = { 0 };
|
||||
HeapScanDesc scan;
|
||||
HeapTuple tuple;
|
||||
BlockNumber nblocks;
|
||||
BlockNumber block = 0; /* next block to count free space in */
|
||||
BlockNumber tupblock;
|
||||
Buffer buffer;
|
||||
pgstattuple_type stat = {0};
|
||||
|
||||
scan = heap_beginscan(rel, SnapshotAny, 0, NULL);
|
||||
|
||||
@ -302,7 +302,7 @@ pgstat_heap(Relation rel, FunctionCallInfo fcinfo)
|
||||
|
||||
relation_close(rel, AccessShareLock);
|
||||
|
||||
stat.table_len = (uint64) nblocks * BLCKSZ;
|
||||
stat.table_len = (uint64) nblocks *BLCKSZ;
|
||||
|
||||
return build_pgstattuple_type(&stat, fcinfo);
|
||||
}
|
||||
@ -311,10 +311,10 @@ pgstat_heap(Relation rel, FunctionCallInfo fcinfo)
|
||||
* pgstat_btree_page -- check tuples in a btree page
|
||||
*/
|
||||
static void
|
||||
pgstat_btree_page(pgstattuple_type *stat, Relation rel, BlockNumber blkno)
|
||||
pgstat_btree_page(pgstattuple_type * stat, Relation rel, BlockNumber blkno)
|
||||
{
|
||||
Buffer buf;
|
||||
Page page;
|
||||
Buffer buf;
|
||||
Page page;
|
||||
|
||||
buf = ReadBuffer(rel, blkno);
|
||||
LockBuffer(buf, BT_READ);
|
||||
@ -328,7 +328,8 @@ pgstat_btree_page(pgstattuple_type *stat, Relation rel, BlockNumber blkno)
|
||||
}
|
||||
else
|
||||
{
|
||||
BTPageOpaque opaque;
|
||||
BTPageOpaque opaque;
|
||||
|
||||
opaque = (BTPageOpaque) PageGetSpecialPointer(page);
|
||||
if (opaque->btpo_flags & (BTP_DELETED | BTP_HALF_DEAD))
|
||||
{
|
||||
@ -338,7 +339,7 @@ pgstat_btree_page(pgstattuple_type *stat, Relation rel, BlockNumber blkno)
|
||||
else if (P_ISLEAF(opaque))
|
||||
{
|
||||
pgstat_index_page(stat, page, P_FIRSTDATAKEY(opaque),
|
||||
PageGetMaxOffsetNumber(page));
|
||||
PageGetMaxOffsetNumber(page));
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -353,10 +354,10 @@ pgstat_btree_page(pgstattuple_type *stat, Relation rel, BlockNumber blkno)
|
||||
* pgstat_hash_page -- check tuples in a hash page
|
||||
*/
|
||||
static void
|
||||
pgstat_hash_page(pgstattuple_type *stat, Relation rel, BlockNumber blkno)
|
||||
pgstat_hash_page(pgstattuple_type * stat, Relation rel, BlockNumber blkno)
|
||||
{
|
||||
Buffer buf;
|
||||
Page page;
|
||||
Buffer buf;
|
||||
Page page;
|
||||
|
||||
_hash_getlock(rel, blkno, HASH_SHARE);
|
||||
buf = _hash_getbuf(rel, blkno, HASH_READ);
|
||||
@ -364,22 +365,23 @@ pgstat_hash_page(pgstattuple_type *stat, Relation rel, BlockNumber blkno)
|
||||
|
||||
if (PageGetSpecialSize(page) == MAXALIGN(sizeof(HashPageOpaqueData)))
|
||||
{
|
||||
HashPageOpaque opaque;
|
||||
HashPageOpaque opaque;
|
||||
|
||||
opaque = (HashPageOpaque) PageGetSpecialPointer(page);
|
||||
switch (opaque->hasho_flag)
|
||||
{
|
||||
case LH_UNUSED_PAGE:
|
||||
stat->free_space += BLCKSZ;
|
||||
break;
|
||||
case LH_BUCKET_PAGE:
|
||||
case LH_OVERFLOW_PAGE:
|
||||
pgstat_index_page(stat, page, FirstOffsetNumber,
|
||||
PageGetMaxOffsetNumber(page));
|
||||
break;
|
||||
case LH_BITMAP_PAGE:
|
||||
case LH_META_PAGE:
|
||||
default:
|
||||
break;
|
||||
case LH_UNUSED_PAGE:
|
||||
stat->free_space += BLCKSZ;
|
||||
break;
|
||||
case LH_BUCKET_PAGE:
|
||||
case LH_OVERFLOW_PAGE:
|
||||
pgstat_index_page(stat, page, FirstOffsetNumber,
|
||||
PageGetMaxOffsetNumber(page));
|
||||
break;
|
||||
case LH_BITMAP_PAGE:
|
||||
case LH_META_PAGE:
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
@ -395,10 +397,10 @@ pgstat_hash_page(pgstattuple_type *stat, Relation rel, BlockNumber blkno)
|
||||
* pgstat_gist_page -- check tuples in a gist page
|
||||
*/
|
||||
static void
|
||||
pgstat_gist_page(pgstattuple_type *stat, Relation rel, BlockNumber blkno)
|
||||
pgstat_gist_page(pgstattuple_type * stat, Relation rel, BlockNumber blkno)
|
||||
{
|
||||
Buffer buf;
|
||||
Page page;
|
||||
Buffer buf;
|
||||
Page page;
|
||||
|
||||
buf = ReadBuffer(rel, blkno);
|
||||
LockBuffer(buf, GIST_SHARE);
|
||||
@ -408,7 +410,7 @@ pgstat_gist_page(pgstattuple_type *stat, Relation rel, BlockNumber blkno)
|
||||
if (GistPageIsLeaf(page))
|
||||
{
|
||||
pgstat_index_page(stat, page, FirstOffsetNumber,
|
||||
PageGetMaxOffsetNumber(page));
|
||||
PageGetMaxOffsetNumber(page));
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -427,7 +429,7 @@ pgstat_index(Relation rel, BlockNumber start, pgstat_page pagefn,
|
||||
{
|
||||
BlockNumber nblocks;
|
||||
BlockNumber blkno;
|
||||
pgstattuple_type stat = { 0 };
|
||||
pgstattuple_type stat = {0};
|
||||
|
||||
blkno = start;
|
||||
for (;;)
|
||||
@ -440,7 +442,8 @@ pgstat_index(Relation rel, BlockNumber start, pgstat_page pagefn,
|
||||
/* Quit if we've scanned the whole relation */
|
||||
if (blkno >= nblocks)
|
||||
{
|
||||
stat.table_len = (uint64) nblocks * BLCKSZ;
|
||||
stat.table_len = (uint64) nblocks *BLCKSZ;
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
@ -457,16 +460,16 @@ pgstat_index(Relation rel, BlockNumber start, pgstat_page pagefn,
|
||||
* pgstat_index_page -- for generic index page
|
||||
*/
|
||||
static void
|
||||
pgstat_index_page(pgstattuple_type *stat, Page page,
|
||||
OffsetNumber minoff, OffsetNumber maxoff)
|
||||
pgstat_index_page(pgstattuple_type * stat, Page page,
|
||||
OffsetNumber minoff, OffsetNumber maxoff)
|
||||
{
|
||||
OffsetNumber i;
|
||||
OffsetNumber i;
|
||||
|
||||
stat->free_space += PageGetFreeSpace(page);
|
||||
|
||||
for (i = minoff; i <= maxoff; i = OffsetNumberNext(i))
|
||||
{
|
||||
ItemId itemid = PageGetItemId(page, i);
|
||||
ItemId itemid = PageGetItemId(page, i);
|
||||
|
||||
if (ItemIdDeleted(itemid))
|
||||
{
|
||||
|
@ -4,7 +4,7 @@
|
||||
* Written by Victor B. Wagner <vitus@cryptocom.ru>, Cryptocom LTD
|
||||
* This file is distributed under BSD-style license.
|
||||
*
|
||||
* $PostgreSQL: pgsql/contrib/sslinfo/sslinfo.c,v 1.4 2006/09/30 18:44:37 tgl Exp $
|
||||
* $PostgreSQL: pgsql/contrib/sslinfo/sslinfo.c,v 1.5 2006/10/04 00:29:46 momjian Exp $
|
||||
*/
|
||||
|
||||
#include "postgres.h"
|
||||
@ -22,28 +22,29 @@
|
||||
PG_MODULE_MAGIC;
|
||||
|
||||
|
||||
Datum ssl_is_used(PG_FUNCTION_ARGS);
|
||||
Datum ssl_client_cert_present(PG_FUNCTION_ARGS);
|
||||
Datum ssl_client_serial(PG_FUNCTION_ARGS);
|
||||
Datum ssl_client_dn_field(PG_FUNCTION_ARGS);
|
||||
Datum ssl_issuer_field(PG_FUNCTION_ARGS);
|
||||
Datum ssl_client_dn(PG_FUNCTION_ARGS);
|
||||
Datum ssl_issuer_dn(PG_FUNCTION_ARGS);
|
||||
Datum X509_NAME_field_to_text(X509_NAME *name, text *fieldName);
|
||||
Datum X509_NAME_to_text(X509_NAME *name);
|
||||
Datum ASN1_STRING_to_text(ASN1_STRING *str);
|
||||
Datum ssl_is_used(PG_FUNCTION_ARGS);
|
||||
Datum ssl_client_cert_present(PG_FUNCTION_ARGS);
|
||||
Datum ssl_client_serial(PG_FUNCTION_ARGS);
|
||||
Datum ssl_client_dn_field(PG_FUNCTION_ARGS);
|
||||
Datum ssl_issuer_field(PG_FUNCTION_ARGS);
|
||||
Datum ssl_client_dn(PG_FUNCTION_ARGS);
|
||||
Datum ssl_issuer_dn(PG_FUNCTION_ARGS);
|
||||
Datum X509_NAME_field_to_text(X509_NAME *name, text *fieldName);
|
||||
Datum X509_NAME_to_text(X509_NAME *name);
|
||||
Datum ASN1_STRING_to_text(ASN1_STRING *str);
|
||||
|
||||
|
||||
/*
|
||||
/*
|
||||
* Indicates whether current session uses SSL
|
||||
*
|
||||
* Function has no arguments. Returns bool. True if current session
|
||||
* is SSL session and false if it is local or non-ssl session.
|
||||
*/
|
||||
PG_FUNCTION_INFO_V1(ssl_is_used);
|
||||
Datum ssl_is_used(PG_FUNCTION_ARGS)
|
||||
Datum
|
||||
ssl_is_used(PG_FUNCTION_ARGS)
|
||||
{
|
||||
PG_RETURN_BOOL(MyProcPort->ssl !=NULL);
|
||||
PG_RETURN_BOOL(MyProcPort->ssl != NULL);
|
||||
}
|
||||
|
||||
|
||||
@ -54,7 +55,8 @@ Datum ssl_is_used(PG_FUNCTION_ARGS)
|
||||
* is SSL session and client certificate is verified, otherwise false.
|
||||
*/
|
||||
PG_FUNCTION_INFO_V1(ssl_client_cert_present);
|
||||
Datum ssl_client_cert_present(PG_FUNCTION_ARGS)
|
||||
Datum
|
||||
ssl_client_cert_present(PG_FUNCTION_ARGS)
|
||||
{
|
||||
PG_RETURN_BOOL(MyProcPort->peer != NULL);
|
||||
}
|
||||
@ -69,20 +71,22 @@ Datum ssl_client_cert_present(PG_FUNCTION_ARGS)
|
||||
* SSL connection is established without sending client certificate.
|
||||
*/
|
||||
PG_FUNCTION_INFO_V1(ssl_client_serial);
|
||||
Datum ssl_client_serial(PG_FUNCTION_ARGS)
|
||||
Datum
|
||||
ssl_client_serial(PG_FUNCTION_ARGS)
|
||||
{
|
||||
Datum result;
|
||||
Port *port = MyProcPort;
|
||||
X509 *peer = port->peer;
|
||||
Datum result;
|
||||
Port *port = MyProcPort;
|
||||
X509 *peer = port->peer;
|
||||
ASN1_INTEGER *serial = NULL;
|
||||
BIGNUM *b;
|
||||
char *decimal;
|
||||
BIGNUM *b;
|
||||
char *decimal;
|
||||
|
||||
if (!peer)
|
||||
PG_RETURN_NULL();
|
||||
serial = X509_get_serialNumber(peer);
|
||||
b = ASN1_INTEGER_to_BN(serial, NULL);
|
||||
decimal = BN_bn2dec(b);
|
||||
|
||||
BN_free(b);
|
||||
result = DirectFunctionCall3(numeric_in,
|
||||
CStringGetDatum(decimal),
|
||||
@ -100,23 +104,25 @@ Datum ssl_client_serial(PG_FUNCTION_ARGS)
|
||||
* current database encoding if possible. Any invalid characters are
|
||||
* replaced by question marks.
|
||||
*
|
||||
* Parameter: str - OpenSSL ASN1_STRING structure. Memory managment
|
||||
* Parameter: str - OpenSSL ASN1_STRING structure. Memory managment
|
||||
* of this structure is responsibility of caller.
|
||||
*
|
||||
* Returns Datum, which can be directly returned from a C language SQL
|
||||
* function.
|
||||
*/
|
||||
Datum ASN1_STRING_to_text(ASN1_STRING *str)
|
||||
Datum
|
||||
ASN1_STRING_to_text(ASN1_STRING *str)
|
||||
{
|
||||
BIO *membuf = NULL;
|
||||
size_t size, outlen;
|
||||
char *sp;
|
||||
char *dp;
|
||||
text *result;
|
||||
BIO *membuf = NULL;
|
||||
size_t size,
|
||||
outlen;
|
||||
char *sp;
|
||||
char *dp;
|
||||
text *result;
|
||||
|
||||
membuf = BIO_new(BIO_s_mem());
|
||||
(void) BIO_set_close(membuf, BIO_CLOSE);
|
||||
ASN1_STRING_print_ex(membuf,str,
|
||||
ASN1_STRING_print_ex(membuf, str,
|
||||
((ASN1_STRFLGS_RFC2253 & ~ASN1_STRFLGS_ESC_MSB)
|
||||
| ASN1_STRFLGS_UTF8_CONVERT));
|
||||
|
||||
@ -124,7 +130,7 @@ Datum ASN1_STRING_to_text(ASN1_STRING *str)
|
||||
BIO_write(membuf, &outlen, 1);
|
||||
size = BIO_get_mem_data(membuf, &sp);
|
||||
dp = (char *) pg_do_encoding_conversion((unsigned char *) sp,
|
||||
size-1,
|
||||
size - 1,
|
||||
PG_UTF8,
|
||||
GetDatabaseEncoding());
|
||||
outlen = strlen(dp);
|
||||
@ -146,18 +152,21 @@ Datum ASN1_STRING_to_text(ASN1_STRING *str)
|
||||
*
|
||||
* Parameter: X509_NAME *name - either subject or issuer of certificate
|
||||
* Parameter: text fieldName - field name string like 'CN' or commonName
|
||||
* to be looked up in the OpenSSL ASN1 OID database
|
||||
* to be looked up in the OpenSSL ASN1 OID database
|
||||
*
|
||||
* Returns result of ASN1_STRING_to_text applied to appropriate
|
||||
* part of name
|
||||
*/
|
||||
Datum X509_NAME_field_to_text(X509_NAME *name, text *fieldName)
|
||||
Datum
|
||||
X509_NAME_field_to_text(X509_NAME *name, text *fieldName)
|
||||
{
|
||||
char *sp;
|
||||
char *string_fieldname;
|
||||
char *dp;
|
||||
size_t name_len = VARSIZE(fieldName) - VARHDRSZ;
|
||||
int nid, index, i;
|
||||
char *sp;
|
||||
char *string_fieldname;
|
||||
char *dp;
|
||||
size_t name_len = VARSIZE(fieldName) - VARHDRSZ;
|
||||
int nid,
|
||||
index,
|
||||
i;
|
||||
ASN1_STRING *data;
|
||||
|
||||
string_fieldname = palloc(name_len + 1);
|
||||
@ -175,7 +184,7 @@ Datum X509_NAME_field_to_text(X509_NAME *name, text *fieldName)
|
||||
pfree(string_fieldname);
|
||||
index = X509_NAME_get_index_by_NID(name, nid, -1);
|
||||
if (index < 0)
|
||||
return (Datum)0;
|
||||
return (Datum) 0;
|
||||
data = X509_NAME_ENTRY_get_data(X509_NAME_get_entry(name, index));
|
||||
return ASN1_STRING_to_text(data);
|
||||
}
|
||||
@ -198,10 +207,11 @@ Datum X509_NAME_field_to_text(X509_NAME *name, text *fieldName)
|
||||
* there is no field with such name in the certificate.
|
||||
*/
|
||||
PG_FUNCTION_INFO_V1(ssl_client_dn_field);
|
||||
Datum ssl_client_dn_field(PG_FUNCTION_ARGS)
|
||||
Datum
|
||||
ssl_client_dn_field(PG_FUNCTION_ARGS)
|
||||
{
|
||||
text *fieldname = PG_GETARG_TEXT_P(0);
|
||||
Datum result;
|
||||
text *fieldname = PG_GETARG_TEXT_P(0);
|
||||
Datum result;
|
||||
|
||||
if (!(MyProcPort->peer))
|
||||
PG_RETURN_NULL();
|
||||
@ -232,10 +242,11 @@ Datum ssl_client_dn_field(PG_FUNCTION_ARGS)
|
||||
* there is no field with such name in the certificate.
|
||||
*/
|
||||
PG_FUNCTION_INFO_V1(ssl_issuer_field);
|
||||
Datum ssl_issuer_field(PG_FUNCTION_ARGS)
|
||||
Datum
|
||||
ssl_issuer_field(PG_FUNCTION_ARGS)
|
||||
{
|
||||
text *fieldname = PG_GETARG_TEXT_P(0);
|
||||
Datum result;
|
||||
text *fieldname = PG_GETARG_TEXT_P(0);
|
||||
Datum result;
|
||||
|
||||
if (!(MyProcPort->peer))
|
||||
PG_RETURN_NULL();
|
||||
@ -260,21 +271,25 @@ Datum ssl_issuer_field(PG_FUNCTION_ARGS)
|
||||
* Returns: text datum which contains string representation of
|
||||
* X509_NAME
|
||||
*/
|
||||
Datum X509_NAME_to_text(X509_NAME *name)
|
||||
Datum
|
||||
X509_NAME_to_text(X509_NAME *name)
|
||||
{
|
||||
BIO *membuf = BIO_new(BIO_s_mem());
|
||||
int i,nid,count = X509_NAME_entry_count(name);
|
||||
BIO *membuf = BIO_new(BIO_s_mem());
|
||||
int i,
|
||||
nid,
|
||||
count = X509_NAME_entry_count(name);
|
||||
X509_NAME_ENTRY *e;
|
||||
ASN1_STRING *v;
|
||||
|
||||
const char *field_name;
|
||||
size_t size,outlen;
|
||||
char *sp;
|
||||
char *dp;
|
||||
text *result;
|
||||
size_t size,
|
||||
outlen;
|
||||
char *sp;
|
||||
char *dp;
|
||||
text *result;
|
||||
|
||||
(void) BIO_set_close(membuf, BIO_CLOSE);
|
||||
for (i=0; i<count; i++)
|
||||
for (i = 0; i < count; i++)
|
||||
{
|
||||
e = X509_NAME_get_entry(name, i);
|
||||
nid = OBJ_obj2nid(X509_NAME_ENTRY_get_object(e));
|
||||
@ -283,17 +298,17 @@ Datum X509_NAME_to_text(X509_NAME *name)
|
||||
if (!field_name)
|
||||
field_name = OBJ_nid2ln(nid);
|
||||
BIO_printf(membuf, "/%s=", field_name);
|
||||
ASN1_STRING_print_ex(membuf,v,
|
||||
ASN1_STRING_print_ex(membuf, v,
|
||||
((ASN1_STRFLGS_RFC2253 & ~ASN1_STRFLGS_ESC_MSB)
|
||||
| ASN1_STRFLGS_UTF8_CONVERT));
|
||||
}
|
||||
|
||||
i=0;
|
||||
i = 0;
|
||||
BIO_write(membuf, &i, 1);
|
||||
size = BIO_get_mem_data(membuf, &sp);
|
||||
|
||||
dp = (char *) pg_do_encoding_conversion((unsigned char *) sp,
|
||||
size-1,
|
||||
size - 1,
|
||||
PG_UTF8,
|
||||
GetDatabaseEncoding());
|
||||
BIO_free(membuf);
|
||||
@ -301,8 +316,10 @@ Datum X509_NAME_to_text(X509_NAME *name)
|
||||
result = palloc(VARHDRSZ + outlen);
|
||||
memcpy(VARDATA(result), dp, outlen);
|
||||
|
||||
/* pg_do_encoding_conversion has annoying habit of returning
|
||||
* source pointer */
|
||||
/*
|
||||
* pg_do_encoding_conversion has annoying habit of returning source
|
||||
* pointer
|
||||
*/
|
||||
if (dp != sp)
|
||||
pfree(dp);
|
||||
VARATT_SIZEP(result) = outlen + VARHDRSZ;
|
||||
@ -320,7 +337,8 @@ Datum X509_NAME_to_text(X509_NAME *name)
|
||||
* Returns text datum.
|
||||
*/
|
||||
PG_FUNCTION_INFO_V1(ssl_client_dn);
|
||||
Datum ssl_client_dn(PG_FUNCTION_ARGS)
|
||||
Datum
|
||||
ssl_client_dn(PG_FUNCTION_ARGS)
|
||||
{
|
||||
if (!(MyProcPort->peer))
|
||||
PG_RETURN_NULL();
|
||||
@ -338,7 +356,8 @@ Datum ssl_client_dn(PG_FUNCTION_ARGS)
|
||||
* Returns text datum.
|
||||
*/
|
||||
PG_FUNCTION_INFO_V1(ssl_issuer_dn);
|
||||
Datum ssl_issuer_dn(PG_FUNCTION_ARGS)
|
||||
Datum
|
||||
ssl_issuer_dn(PG_FUNCTION_ARGS)
|
||||
{
|
||||
if (!(MyProcPort->peer))
|
||||
PG_RETURN_NULL();
|
||||
|
@ -1259,7 +1259,7 @@ build_tuplestore_recursively(char *key_fld,
|
||||
int ret;
|
||||
int proc;
|
||||
int serial_column;
|
||||
StringInfoData sql;
|
||||
StringInfoData sql;
|
||||
char **values;
|
||||
char *current_key;
|
||||
char *current_key_parent;
|
||||
@ -1357,9 +1357,9 @@ build_tuplestore_recursively(char *key_fld,
|
||||
SPITupleTable *tuptable = SPI_tuptable;
|
||||
TupleDesc spi_tupdesc = tuptable->tupdesc;
|
||||
int i;
|
||||
StringInfoData branchstr;
|
||||
StringInfoData chk_branchstr;
|
||||
StringInfoData chk_current_key;
|
||||
StringInfoData branchstr;
|
||||
StringInfoData chk_branchstr;
|
||||
StringInfoData chk_current_key;
|
||||
|
||||
/* First time through, do a little more setup */
|
||||
if (level == 0)
|
||||
|
@ -164,16 +164,19 @@ get_oidnamespace(Oid funcoid)
|
||||
return nspoid;
|
||||
}
|
||||
|
||||
/* if path is relative, take it as relative to share dir */
|
||||
/* if path is relative, take it as relative to share dir */
|
||||
char *
|
||||
to_absfilename(char *filename) {
|
||||
if (!is_absolute_path(filename)) {
|
||||
char sharepath[MAXPGPATH];
|
||||
char *absfn;
|
||||
#ifdef WIN32
|
||||
char delim = '\\';
|
||||
to_absfilename(char *filename)
|
||||
{
|
||||
if (!is_absolute_path(filename))
|
||||
{
|
||||
char sharepath[MAXPGPATH];
|
||||
char *absfn;
|
||||
|
||||
#ifdef WIN32
|
||||
char delim = '\\';
|
||||
#else
|
||||
char delim = '/';
|
||||
char delim = '/';
|
||||
#endif
|
||||
get_share_path(my_exec_path, sharepath);
|
||||
absfn = palloc(strlen(sharepath) + strlen(filename) + 2);
|
||||
|
@ -14,7 +14,7 @@ text *mtextdup(text *in);
|
||||
|
||||
int text_cmp(text *a, text *b);
|
||||
|
||||
char * to_absfilename(char *filename);
|
||||
char *to_absfilename(char *filename);
|
||||
|
||||
#define NEXTVAL(x) ( (text*)( (char*)(x) + INTALIGN( VARSIZE(x) ) ) )
|
||||
#define ARRNELEMS(x) ArrayGetNItems( ARR_NDIM(x), ARR_DIMS(x))
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $PostgreSQL: pgsql/contrib/tsearch2/dict.c,v 1.12 2006/05/31 14:05:31 teodor Exp $ */
|
||||
/* $PostgreSQL: pgsql/contrib/tsearch2/dict.c,v 1.13 2006/10/04 00:29:46 momjian Exp $ */
|
||||
|
||||
/*
|
||||
* interface functions to dictionary
|
||||
@ -102,7 +102,8 @@ comparedict(const void *a, const void *b)
|
||||
}
|
||||
|
||||
static void
|
||||
insertdict(Oid id) {
|
||||
insertdict(Oid id)
|
||||
{
|
||||
DictInfo newdict;
|
||||
|
||||
if (DList.len == DList.reallen)
|
||||
@ -143,7 +144,7 @@ finddict(Oid id)
|
||||
return DList.last_dict;
|
||||
}
|
||||
|
||||
/* insert new dictionary */
|
||||
/* insert new dictionary */
|
||||
insertdict(id);
|
||||
return finddict(id); /* qsort changed order!! */ ;
|
||||
}
|
||||
@ -201,30 +202,31 @@ lexize(PG_FUNCTION_ARGS)
|
||||
*ptr;
|
||||
Datum *da;
|
||||
ArrayType *a;
|
||||
DictSubState dstate = { false, false, NULL };
|
||||
DictSubState dstate = {false, false, NULL};
|
||||
|
||||
SET_FUNCOID();
|
||||
dict = finddict(PG_GETARG_OID(0));
|
||||
|
||||
ptr = res = (TSLexeme *) DatumGetPointer(
|
||||
FunctionCall4(&(dict->lexize_info),
|
||||
PointerGetDatum(dict->dictionary),
|
||||
PointerGetDatum(VARDATA(in)),
|
||||
Int32GetDatum(VARSIZE(in) - VARHDRSZ),
|
||||
PointerGetDatum(&dstate)
|
||||
FunctionCall4(&(dict->lexize_info),
|
||||
PointerGetDatum(dict->dictionary),
|
||||
PointerGetDatum(VARDATA(in)),
|
||||
Int32GetDatum(VARSIZE(in) - VARHDRSZ),
|
||||
PointerGetDatum(&dstate)
|
||||
)
|
||||
);
|
||||
|
||||
if (dstate.getnext) {
|
||||
dstate.isend = true;
|
||||
if (dstate.getnext)
|
||||
{
|
||||
dstate.isend = true;
|
||||
ptr = res = (TSLexeme *) DatumGetPointer(
|
||||
FunctionCall4(&(dict->lexize_info),
|
||||
FunctionCall4(&(dict->lexize_info),
|
||||
PointerGetDatum(dict->dictionary),
|
||||
PointerGetDatum(VARDATA(in)),
|
||||
Int32GetDatum(VARSIZE(in) - VARHDRSZ),
|
||||
PointerGetDatum(&dstate)
|
||||
Int32GetDatum(VARSIZE(in) - VARHDRSZ),
|
||||
PointerGetDatum(&dstate)
|
||||
)
|
||||
);
|
||||
);
|
||||
}
|
||||
|
||||
PG_FREE_IF_COPY(in, 1);
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $PostgreSQL: pgsql/contrib/tsearch2/dict.h,v 1.7 2006/05/31 14:05:31 teodor Exp $ */
|
||||
/* $PostgreSQL: pgsql/contrib/tsearch2/dict.h,v 1.8 2006/10/04 00:29:46 momjian Exp $ */
|
||||
|
||||
#ifndef __DICT_H__
|
||||
#define __DICT_H__
|
||||
@ -30,11 +30,14 @@ DictInfo *finddict(Oid id);
|
||||
Oid name2id_dict(text *name);
|
||||
void reset_dict(void);
|
||||
|
||||
typedef struct {
|
||||
bool isend; /* in: marks for lexize_info about text end is reached */
|
||||
bool getnext; /* out: dict wants next lexeme */
|
||||
void *private; /* internal dict state between calls with getnext == true */
|
||||
} DictSubState;
|
||||
typedef struct
|
||||
{
|
||||
bool isend; /* in: marks for lexize_info about text end is
|
||||
* reached */
|
||||
bool getnext; /* out: dict wants next lexeme */
|
||||
void *private; /* internal dict state between calls with
|
||||
* getnext == true */
|
||||
} DictSubState;
|
||||
|
||||
/* simple parser of cfg string */
|
||||
typedef struct
|
||||
@ -51,13 +54,8 @@ typedef struct
|
||||
/*
|
||||
* number of variant of split word , for example Word 'fotballklubber'
|
||||
* (norwegian) has two varian to split: ( fotball, klubb ) and ( fot,
|
||||
* ball, klubb ). So, dictionary should return:
|
||||
* nvariant lexeme
|
||||
* 1 fotball
|
||||
* 1 klubb
|
||||
* 2 fot
|
||||
* 2 ball
|
||||
* 2 klubb
|
||||
* ball, klubb ). So, dictionary should return: nvariant lexeme 1
|
||||
* fotball 1 klubb 2 fot 2 ball 2 klubb
|
||||
*/
|
||||
uint16 nvariant;
|
||||
|
||||
@ -74,38 +72,43 @@ typedef struct
|
||||
* Lexize subsystem
|
||||
*/
|
||||
|
||||
typedef struct ParsedLex {
|
||||
int type;
|
||||
char *lemm;
|
||||
int lenlemm;
|
||||
typedef struct ParsedLex
|
||||
{
|
||||
int type;
|
||||
char *lemm;
|
||||
int lenlemm;
|
||||
bool resfollow;
|
||||
struct ParsedLex *next;
|
||||
} ParsedLex;
|
||||
struct ParsedLex *next;
|
||||
} ParsedLex;
|
||||
|
||||
typedef struct ListParsedLex {
|
||||
ParsedLex *head;
|
||||
ParsedLex *tail;
|
||||
} ListParsedLex;
|
||||
typedef struct ListParsedLex
|
||||
{
|
||||
ParsedLex *head;
|
||||
ParsedLex *tail;
|
||||
} ListParsedLex;
|
||||
|
||||
typedef struct {
|
||||
TSCfgInfo *cfg;
|
||||
Oid curDictId;
|
||||
int posDict;
|
||||
DictSubState dictState;
|
||||
ParsedLex *curSub;
|
||||
ListParsedLex towork; /* current list to work */
|
||||
ListParsedLex waste; /* list of lexemes that already lexized */
|
||||
typedef struct
|
||||
{
|
||||
TSCfgInfo *cfg;
|
||||
Oid curDictId;
|
||||
int posDict;
|
||||
DictSubState dictState;
|
||||
ParsedLex *curSub;
|
||||
ListParsedLex towork; /* current list to work */
|
||||
ListParsedLex waste; /* list of lexemes that already lexized */
|
||||
|
||||
/* fields to store last variant to lexize (basically, thesaurus
|
||||
or similar to, which wants several lexemes */
|
||||
|
||||
ParsedLex *lastRes;
|
||||
TSLexeme *tmpRes;
|
||||
} LexizeData;
|
||||
/*
|
||||
* fields to store last variant to lexize (basically, thesaurus or similar
|
||||
* to, which wants several lexemes
|
||||
*/
|
||||
|
||||
ParsedLex *lastRes;
|
||||
TSLexeme *tmpRes;
|
||||
} LexizeData;
|
||||
|
||||
|
||||
void LexizeInit(LexizeData *ld, TSCfgInfo *cfg);
|
||||
void LexizeAddLemm(LexizeData *ld, int type, char *lemm, int lenlemm);
|
||||
TSLexeme* LexizeExec(LexizeData *ld, ParsedLex **correspondLexem);
|
||||
void LexizeInit(LexizeData * ld, TSCfgInfo * cfg);
|
||||
void LexizeAddLemm(LexizeData * ld, int type, char *lemm, int lenlemm);
|
||||
TSLexeme *LexizeExec(LexizeData * ld, ParsedLex ** correspondLexem);
|
||||
|
||||
#endif
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -15,29 +15,32 @@
|
||||
#include "query_cleanup.h"
|
||||
|
||||
PG_FUNCTION_INFO_V1(gin_extract_tsvector);
|
||||
Datum gin_extract_tsvector(PG_FUNCTION_ARGS);
|
||||
Datum gin_extract_tsvector(PG_FUNCTION_ARGS);
|
||||
|
||||
Datum
|
||||
gin_extract_tsvector(PG_FUNCTION_ARGS) {
|
||||
tsvector *vector = (tsvector *) PG_DETOAST_DATUM(PG_GETARG_DATUM(0));
|
||||
uint32 *nentries = (uint32*)PG_GETARG_POINTER(1);
|
||||
Datum *entries = NULL;
|
||||
gin_extract_tsvector(PG_FUNCTION_ARGS)
|
||||
{
|
||||
tsvector *vector = (tsvector *) PG_DETOAST_DATUM(PG_GETARG_DATUM(0));
|
||||
uint32 *nentries = (uint32 *) PG_GETARG_POINTER(1);
|
||||
Datum *entries = NULL;
|
||||
|
||||
*nentries = 0;
|
||||
if ( vector->size > 0 ) {
|
||||
int i;
|
||||
WordEntry *we = ARRPTR( vector );
|
||||
if (vector->size > 0)
|
||||
{
|
||||
int i;
|
||||
WordEntry *we = ARRPTR(vector);
|
||||
|
||||
*nentries = (uint32)vector->size;
|
||||
entries = (Datum*)palloc( sizeof(Datum) * vector->size );
|
||||
*nentries = (uint32) vector->size;
|
||||
entries = (Datum *) palloc(sizeof(Datum) * vector->size);
|
||||
|
||||
for(i=0;i<vector->size;i++) {
|
||||
text *txt = (text*)palloc( VARHDRSZ + we->len );
|
||||
for (i = 0; i < vector->size; i++)
|
||||
{
|
||||
text *txt = (text *) palloc(VARHDRSZ + we->len);
|
||||
|
||||
VARATT_SIZEP(txt) = VARHDRSZ + we->len;
|
||||
memcpy( VARDATA(txt), STRPTR( vector ) + we->pos, we->len );
|
||||
VARATT_SIZEP(txt) = VARHDRSZ + we->len;
|
||||
memcpy(VARDATA(txt), STRPTR(vector) + we->pos, we->len);
|
||||
|
||||
entries[i] = PointerGetDatum( txt );
|
||||
entries[i] = PointerGetDatum(txt);
|
||||
|
||||
we++;
|
||||
}
|
||||
@ -49,45 +52,50 @@ gin_extract_tsvector(PG_FUNCTION_ARGS) {
|
||||
|
||||
|
||||
PG_FUNCTION_INFO_V1(gin_extract_tsquery);
|
||||
Datum gin_extract_tsquery(PG_FUNCTION_ARGS);
|
||||
Datum gin_extract_tsquery(PG_FUNCTION_ARGS);
|
||||
|
||||
Datum
|
||||
gin_extract_tsquery(PG_FUNCTION_ARGS) {
|
||||
QUERYTYPE *query = (QUERYTYPE*) PG_DETOAST_DATUM(PG_GETARG_DATUM(0));
|
||||
uint32 *nentries = (uint32*)PG_GETARG_POINTER(1);
|
||||
StrategyNumber strategy = DatumGetUInt16( PG_GETARG_DATUM(2) );
|
||||
Datum *entries = NULL;
|
||||
gin_extract_tsquery(PG_FUNCTION_ARGS)
|
||||
{
|
||||
QUERYTYPE *query = (QUERYTYPE *) PG_DETOAST_DATUM(PG_GETARG_DATUM(0));
|
||||
uint32 *nentries = (uint32 *) PG_GETARG_POINTER(1);
|
||||
StrategyNumber strategy = DatumGetUInt16(PG_GETARG_DATUM(2));
|
||||
Datum *entries = NULL;
|
||||
|
||||
*nentries = 0;
|
||||
if ( query->size > 0 ) {
|
||||
int4 i, j=0, len;
|
||||
ITEM *item;
|
||||
if (query->size > 0)
|
||||
{
|
||||
int4 i,
|
||||
j = 0,
|
||||
len;
|
||||
ITEM *item;
|
||||
|
||||
item = clean_NOT_v2(GETQUERY(query), &len);
|
||||
if ( !item )
|
||||
elog(ERROR,"Query requires full scan, GIN doesn't support it");
|
||||
if (!item)
|
||||
elog(ERROR, "Query requires full scan, GIN doesn't support it");
|
||||
|
||||
item = GETQUERY(query);
|
||||
|
||||
for(i=0; i<query->size; i++)
|
||||
if ( item[i].type == VAL )
|
||||
for (i = 0; i < query->size; i++)
|
||||
if (item[i].type == VAL)
|
||||
(*nentries)++;
|
||||
|
||||
entries = (Datum*)palloc( sizeof(Datum) * (*nentries) );
|
||||
entries = (Datum *) palloc(sizeof(Datum) * (*nentries));
|
||||
|
||||
for(i=0; i<query->size; i++)
|
||||
if ( item[i].type == VAL ) {
|
||||
text *txt;
|
||||
for (i = 0; i < query->size; i++)
|
||||
if (item[i].type == VAL)
|
||||
{
|
||||
text *txt;
|
||||
|
||||
txt = (text*)palloc( VARHDRSZ + item[i].length );
|
||||
txt = (text *) palloc(VARHDRSZ + item[i].length);
|
||||
|
||||
VARATT_SIZEP(txt) = VARHDRSZ + item[i].length;
|
||||
memcpy( VARDATA(txt), GETOPERAND( query ) + item[i].distance, item[i].length );
|
||||
VARATT_SIZEP(txt) = VARHDRSZ + item[i].length;
|
||||
memcpy(VARDATA(txt), GETOPERAND(query) + item[i].distance, item[i].length);
|
||||
|
||||
entries[j++] = PointerGetDatum( txt );
|
||||
entries[j++] = PointerGetDatum(txt);
|
||||
|
||||
if ( strategy == 1 && item[i].weight != 0 )
|
||||
elog(ERROR,"With class of lexeme restrictions use @@@ operation");
|
||||
if (strategy == 1 && item[i].weight != 0)
|
||||
elog(ERROR, "With class of lexeme restrictions use @@@ operation");
|
||||
}
|
||||
|
||||
}
|
||||
@ -96,51 +104,54 @@ gin_extract_tsquery(PG_FUNCTION_ARGS) {
|
||||
PG_RETURN_POINTER(entries);
|
||||
}
|
||||
|
||||
typedef struct {
|
||||
ITEM *frst;
|
||||
bool *mapped_check;
|
||||
} GinChkVal;
|
||||
typedef struct
|
||||
{
|
||||
ITEM *frst;
|
||||
bool *mapped_check;
|
||||
} GinChkVal;
|
||||
|
||||
static bool
|
||||
checkcondition_gin(void *checkval, ITEM * val) {
|
||||
GinChkVal *gcv = (GinChkVal*)checkval;
|
||||
checkcondition_gin(void *checkval, ITEM * val)
|
||||
{
|
||||
GinChkVal *gcv = (GinChkVal *) checkval;
|
||||
|
||||
return gcv->mapped_check[ val - gcv->frst ];
|
||||
return gcv->mapped_check[val - gcv->frst];
|
||||
}
|
||||
|
||||
PG_FUNCTION_INFO_V1(gin_ts_consistent);
|
||||
Datum gin_ts_consistent(PG_FUNCTION_ARGS);
|
||||
Datum gin_ts_consistent(PG_FUNCTION_ARGS);
|
||||
|
||||
Datum
|
||||
gin_ts_consistent(PG_FUNCTION_ARGS) {
|
||||
bool *check = (bool*)PG_GETARG_POINTER(0);
|
||||
QUERYTYPE *query = (QUERYTYPE*) PG_DETOAST_DATUM(PG_GETARG_DATUM(2));
|
||||
bool res = FALSE;
|
||||
gin_ts_consistent(PG_FUNCTION_ARGS)
|
||||
{
|
||||
bool *check = (bool *) PG_GETARG_POINTER(0);
|
||||
QUERYTYPE *query = (QUERYTYPE *) PG_DETOAST_DATUM(PG_GETARG_DATUM(2));
|
||||
bool res = FALSE;
|
||||
|
||||
if ( query->size > 0 ) {
|
||||
int4 i, j=0;
|
||||
ITEM *item;
|
||||
if (query->size > 0)
|
||||
{
|
||||
int4 i,
|
||||
j = 0;
|
||||
ITEM *item;
|
||||
GinChkVal gcv;
|
||||
|
||||
gcv.frst = item = GETQUERY(query);
|
||||
gcv.mapped_check= (bool*)palloc( sizeof(bool) * query->size );
|
||||
gcv.frst = item = GETQUERY(query);
|
||||
gcv.mapped_check = (bool *) palloc(sizeof(bool) * query->size);
|
||||
|
||||
for(i=0; i<query->size; i++)
|
||||
if ( item[i].type == VAL )
|
||||
gcv.mapped_check[ i ] = check[ j++ ];
|
||||
for (i = 0; i < query->size; i++)
|
||||
if (item[i].type == VAL)
|
||||
gcv.mapped_check[i] = check[j++];
|
||||
|
||||
|
||||
res = TS_execute(
|
||||
GETQUERY(query),
|
||||
&gcv,
|
||||
true,
|
||||
checkcondition_gin
|
||||
);
|
||||
GETQUERY(query),
|
||||
&gcv,
|
||||
true,
|
||||
checkcondition_gin
|
||||
);
|
||||
|
||||
}
|
||||
|
||||
PG_FREE_IF_COPY(query, 2);
|
||||
PG_RETURN_BOOL(res);
|
||||
}
|
||||
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $PostgreSQL: pgsql/contrib/tsearch2/gistidx.c,v 1.14 2006/06/28 12:00:06 teodor Exp $ */
|
||||
/* $PostgreSQL: pgsql/contrib/tsearch2/gistidx.c,v 1.15 2006/10/04 00:29:46 momjian Exp $ */
|
||||
|
||||
#include "postgres.h"
|
||||
|
||||
@ -447,7 +447,7 @@ sizebitvec(BITVECP sign)
|
||||
i;
|
||||
|
||||
LOOPBYTE(
|
||||
size += number_of_ones[(unsigned char) sign[i]];
|
||||
size += number_of_ones[(unsigned char) sign[i]];
|
||||
);
|
||||
return size;
|
||||
}
|
||||
@ -460,8 +460,8 @@ hemdistsign(BITVECP a, BITVECP b)
|
||||
dist = 0;
|
||||
|
||||
LOOPBYTE(
|
||||
diff = (unsigned char) (a[i] ^ b[i]);
|
||||
dist += number_of_ones[diff];
|
||||
diff = (unsigned char) (a[i] ^ b[i]);
|
||||
dist += number_of_ones[diff];
|
||||
);
|
||||
return dist;
|
||||
}
|
||||
@ -533,7 +533,7 @@ typedef struct
|
||||
{
|
||||
OffsetNumber pos;
|
||||
int4 cost;
|
||||
} SPLITCOST;
|
||||
} SPLITCOST;
|
||||
|
||||
static int
|
||||
comparecost(const void *a, const void *b)
|
||||
|
@ -9,7 +9,7 @@ RS_isRegis(const char *str)
|
||||
{
|
||||
if (t_isalpha(str) ||
|
||||
t_iseq(str, '[') ||
|
||||
t_iseq(str,']') ||
|
||||
t_iseq(str, ']') ||
|
||||
t_iseq(str, '^'))
|
||||
str += pg_mblen(str);
|
||||
else
|
||||
@ -42,13 +42,13 @@ RS_compile(Regis * r, bool issuffix, char *str)
|
||||
{
|
||||
int len = strlen(str);
|
||||
int state = RS_IN_WAIT;
|
||||
char *c = (char*)str;
|
||||
char *c = (char *) str;
|
||||
RegisNode *ptr = NULL;
|
||||
|
||||
memset(r, 0, sizeof(Regis));
|
||||
r->issuffix = (issuffix) ? 1 : 0;
|
||||
|
||||
while(*c)
|
||||
while (*c)
|
||||
{
|
||||
if (state == RS_IN_WAIT)
|
||||
{
|
||||
@ -62,7 +62,7 @@ RS_compile(Regis * r, bool issuffix, char *str)
|
||||
ptr->type = RSF_ONEOF;
|
||||
ptr->len = pg_mblen(c);
|
||||
}
|
||||
else if (t_iseq(c,'['))
|
||||
else if (t_iseq(c, '['))
|
||||
{
|
||||
if (ptr)
|
||||
ptr = newRegisNode(ptr, len);
|
||||
@ -72,11 +72,11 @@ RS_compile(Regis * r, bool issuffix, char *str)
|
||||
state = RS_IN_ONEOF;
|
||||
}
|
||||
else
|
||||
ts_error(ERROR, "Error in regis: %s", str );
|
||||
ts_error(ERROR, "Error in regis: %s", str);
|
||||
}
|
||||
else if (state == RS_IN_ONEOF)
|
||||
{
|
||||
if (t_iseq(c,'^'))
|
||||
if (t_iseq(c, '^'))
|
||||
{
|
||||
ptr->type = RSF_NONEOF;
|
||||
state = RS_IN_NONEOF;
|
||||
@ -94,10 +94,10 @@ RS_compile(Regis * r, bool issuffix, char *str)
|
||||
{
|
||||
if (t_isalpha(c))
|
||||
{
|
||||
COPYCHAR(ptr->data+ptr->len, c);
|
||||
ptr->len+=pg_mblen(c);
|
||||
COPYCHAR(ptr->data + ptr->len, c);
|
||||
ptr->len += pg_mblen(c);
|
||||
}
|
||||
else if (t_iseq(c,']'))
|
||||
else if (t_iseq(c, ']'))
|
||||
state = RS_IN_WAIT;
|
||||
else
|
||||
ts_error(ERROR, "Error in regis: %s", str);
|
||||
@ -133,28 +133,34 @@ RS_free(Regis * r)
|
||||
|
||||
#ifdef TS_USE_WIDE
|
||||
static bool
|
||||
mb_strchr(char *str, char *c) {
|
||||
int clen = pg_mblen(c), plen,i;
|
||||
char *ptr =str;
|
||||
bool res=false;
|
||||
mb_strchr(char *str, char *c)
|
||||
{
|
||||
int clen = pg_mblen(c),
|
||||
plen,
|
||||
i;
|
||||
char *ptr = str;
|
||||
bool res = false;
|
||||
|
||||
clen = pg_mblen(c);
|
||||
while( *ptr && !res) {
|
||||
while (*ptr && !res)
|
||||
{
|
||||
plen = pg_mblen(ptr);
|
||||
if ( plen == clen ) {
|
||||
i=plen;
|
||||
if (plen == clen)
|
||||
{
|
||||
i = plen;
|
||||
res = true;
|
||||
while(i--)
|
||||
if ( *(ptr+i) != *(c+i) ) {
|
||||
while (i--)
|
||||
if (*(ptr + i) != *(c + i))
|
||||
{
|
||||
res = false;
|
||||
break;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
ptr += plen;
|
||||
}
|
||||
|
||||
return res;
|
||||
ptr += plen;
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
#else
|
||||
#define mb_strchr(s,c) ( (strchr((s),*(c)) == NULL) ? false : true )
|
||||
@ -165,21 +171,23 @@ bool
|
||||
RS_execute(Regis * r, char *str)
|
||||
{
|
||||
RegisNode *ptr = r->node;
|
||||
char *c = str;
|
||||
int len=0;
|
||||
char *c = str;
|
||||
int len = 0;
|
||||
|
||||
while(*c) {
|
||||
while (*c)
|
||||
{
|
||||
len++;
|
||||
c += pg_mblen(c);
|
||||
}
|
||||
}
|
||||
|
||||
if (len < r->nchar)
|
||||
return 0;
|
||||
|
||||
c = str;
|
||||
if (r->issuffix) {
|
||||
if (r->issuffix)
|
||||
{
|
||||
len -= r->nchar;
|
||||
while(len-- > 0)
|
||||
while (len-- > 0)
|
||||
c += pg_mblen(c);
|
||||
}
|
||||
|
||||
@ -189,18 +197,18 @@ RS_execute(Regis * r, char *str)
|
||||
switch (ptr->type)
|
||||
{
|
||||
case RSF_ONEOF:
|
||||
if ( mb_strchr((char *) ptr->data, c) != true )
|
||||
if (mb_strchr((char *) ptr->data, c) != true)
|
||||
return false;
|
||||
break;
|
||||
case RSF_NONEOF:
|
||||
if ( mb_strchr((char *) ptr->data, c) == true )
|
||||
if (mb_strchr((char *) ptr->data, c) == true)
|
||||
return false;
|
||||
break;
|
||||
default:
|
||||
ts_error(ERROR, "RS_execute: Unknown type node: %d\n", ptr->type);
|
||||
}
|
||||
ptr = ptr->next;
|
||||
c+=pg_mblen(c);
|
||||
c += pg_mblen(c);
|
||||
}
|
||||
|
||||
return true;
|
||||
|
@ -27,12 +27,12 @@ typedef struct Regis
|
||||
unused:15;
|
||||
} Regis;
|
||||
|
||||
bool RS_isRegis(const char *str);
|
||||
bool RS_isRegis(const char *str);
|
||||
|
||||
void RS_compile(Regis * r, bool issuffix, char *str);
|
||||
void RS_compile(Regis * r, bool issuffix, char *str);
|
||||
void RS_free(Regis * r);
|
||||
|
||||
/*returns true if matches */
|
||||
bool RS_execute(Regis * r, char *str);
|
||||
bool RS_execute(Regis * r, char *str);
|
||||
|
||||
#endif
|
||||
|
@ -41,16 +41,18 @@ strnduplicate(char *s, int len)
|
||||
}
|
||||
|
||||
static char *
|
||||
findchar(char *str, int c) {
|
||||
while( *str ) {
|
||||
if ( t_iseq(str, c) )
|
||||
findchar(char *str, int c)
|
||||
{
|
||||
while (*str)
|
||||
{
|
||||
if (t_iseq(str, c))
|
||||
return str;
|
||||
str+=pg_mblen(str);
|
||||
str += pg_mblen(str);
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* backward string compare for suffix tree operations */
|
||||
static int
|
||||
@ -126,16 +128,16 @@ NIAddSpell(IspellDict * Conf, const char *word, const char *flag)
|
||||
if (Conf->mspell)
|
||||
{
|
||||
Conf->mspell += 1024 * 20;
|
||||
Conf->Spell = (SPELL **) repalloc(Conf->Spell, Conf->mspell * sizeof(SPELL*));
|
||||
Conf->Spell = (SPELL **) repalloc(Conf->Spell, Conf->mspell * sizeof(SPELL *));
|
||||
}
|
||||
else
|
||||
{
|
||||
Conf->mspell = 1024 * 20;
|
||||
Conf->Spell = (SPELL **) palloc(Conf->mspell * sizeof(SPELL*));
|
||||
Conf->Spell = (SPELL **) palloc(Conf->mspell * sizeof(SPELL *));
|
||||
}
|
||||
}
|
||||
Conf->Spell[Conf->nspell] = (SPELL*)palloc(SPELLHDRSZ + strlen(word) + 1);
|
||||
strcpy( Conf->Spell[Conf->nspell]->word ,word );
|
||||
Conf->Spell[Conf->nspell] = (SPELL *) palloc(SPELLHDRSZ + strlen(word) + 1);
|
||||
strcpy(Conf->Spell[Conf->nspell]->word, word);
|
||||
strncpy(Conf->Spell[Conf->nspell]->p.flag, flag, 16);
|
||||
Conf->nspell++;
|
||||
return (0);
|
||||
@ -155,7 +157,7 @@ NIImportDictionary(IspellDict * Conf, const char *filename)
|
||||
char *s;
|
||||
const char *flag;
|
||||
|
||||
pg_verifymbstr( str, strlen(str), false);
|
||||
pg_verifymbstr(str, strlen(str), false);
|
||||
|
||||
flag = NULL;
|
||||
if ((s = findchar(str, '/')))
|
||||
@ -181,11 +183,12 @@ NIImportDictionary(IspellDict * Conf, const char *filename)
|
||||
s = str;
|
||||
while (*s)
|
||||
{
|
||||
if (t_isspace(s)) {
|
||||
if (t_isspace(s))
|
||||
{
|
||||
*s = '\0';
|
||||
break;
|
||||
}
|
||||
s+=pg_mblen(s);
|
||||
s += pg_mblen(s);
|
||||
}
|
||||
lowerstr(str);
|
||||
|
||||
@ -268,12 +271,13 @@ NIAddAffix(IspellDict * Conf, int flag, char flagflags, const char *mask, const
|
||||
}
|
||||
else
|
||||
{
|
||||
int masklen = strlen(mask);
|
||||
int masklen = strlen(mask);
|
||||
|
||||
Conf->Affix[Conf->naffixes].issimple = 0;
|
||||
Conf->Affix[Conf->naffixes].isregis = 0;
|
||||
Conf->Affix[Conf->naffixes].mask = (char *) malloc(masklen + 2);
|
||||
if (type == FF_SUFFIX)
|
||||
sprintf(Conf->Affix[Conf->naffixes].mask, "%s$", mask);
|
||||
if (type == FF_SUFFIX)
|
||||
sprintf(Conf->Affix[Conf->naffixes].mask, "%s$", mask);
|
||||
else
|
||||
sprintf(Conf->Affix[Conf->naffixes].mask, "^%s", mask);
|
||||
}
|
||||
@ -286,83 +290,121 @@ NIAddAffix(IspellDict * Conf, int flag, char flagflags, const char *mask, const
|
||||
|
||||
Conf->Affix[Conf->naffixes].find = (find && *find) ? strdup(find) : VoidString;
|
||||
MEMOUT(Conf->Affix[Conf->naffixes].find);
|
||||
if ( (Conf->Affix[Conf->naffixes].replen = strlen(repl)) > 0 ) {
|
||||
if ((Conf->Affix[Conf->naffixes].replen = strlen(repl)) > 0)
|
||||
{
|
||||
Conf->Affix[Conf->naffixes].repl = strdup(repl);
|
||||
MEMOUT(Conf->Affix[Conf->naffixes].repl);
|
||||
} else
|
||||
Conf->Affix[Conf->naffixes].repl = VoidString;
|
||||
}
|
||||
else
|
||||
Conf->Affix[Conf->naffixes].repl = VoidString;
|
||||
Conf->naffixes++;
|
||||
return (0);
|
||||
}
|
||||
|
||||
#define PAE_WAIT_MASK 0
|
||||
#define PAE_INMASK 1
|
||||
#define PAE_WAIT_FIND 2
|
||||
#define PAE_INFIND 3
|
||||
#define PAE_WAIT_REPL 4
|
||||
#define PAE_INREPL 5
|
||||
#define PAE_INMASK 1
|
||||
#define PAE_WAIT_FIND 2
|
||||
#define PAE_INFIND 3
|
||||
#define PAE_WAIT_REPL 4
|
||||
#define PAE_INREPL 5
|
||||
|
||||
static bool
|
||||
parse_affentry( char *str, char *mask, char *find, char *repl, int line ) {
|
||||
int state = PAE_WAIT_MASK;
|
||||
char *pmask=mask, *pfind=find, *prepl=repl;
|
||||
parse_affentry(char *str, char *mask, char *find, char *repl, int line)
|
||||
{
|
||||
int state = PAE_WAIT_MASK;
|
||||
char *pmask = mask,
|
||||
*pfind = find,
|
||||
*prepl = repl;
|
||||
|
||||
*mask = *find = *repl = '\0';
|
||||
|
||||
while(*str) {
|
||||
if ( state == PAE_WAIT_MASK ) {
|
||||
if ( t_iseq(str,'#') )
|
||||
while (*str)
|
||||
{
|
||||
if (state == PAE_WAIT_MASK)
|
||||
{
|
||||
if (t_iseq(str, '#'))
|
||||
return false;
|
||||
else if (!t_isspace(str)) {
|
||||
else if (!t_isspace(str))
|
||||
{
|
||||
COPYCHAR(pmask, str);
|
||||
pmask += pg_mblen(str);
|
||||
state = PAE_INMASK;
|
||||
}
|
||||
} else if ( state == PAE_INMASK ) {
|
||||
if ( t_iseq(str,'>') ) {
|
||||
*pmask='\0';
|
||||
}
|
||||
else if (state == PAE_INMASK)
|
||||
{
|
||||
if (t_iseq(str, '>'))
|
||||
{
|
||||
*pmask = '\0';
|
||||
state = PAE_WAIT_FIND;
|
||||
} else if (!t_isspace(str)) {
|
||||
}
|
||||
else if (!t_isspace(str))
|
||||
{
|
||||
COPYCHAR(pmask, str);
|
||||
pmask += pg_mblen(str);
|
||||
}
|
||||
} else if ( state == PAE_WAIT_FIND ) {
|
||||
if ( t_iseq(str,'-') ) {
|
||||
}
|
||||
else if (state == PAE_WAIT_FIND)
|
||||
{
|
||||
if (t_iseq(str, '-'))
|
||||
{
|
||||
state = PAE_INFIND;
|
||||
} else if (t_isalpha(str) || t_iseq(str,'\'') /* english 's */) {
|
||||
COPYCHAR(prepl,str);
|
||||
}
|
||||
else if (t_isalpha(str) || t_iseq(str, '\'') /* english 's */ )
|
||||
{
|
||||
COPYCHAR(prepl, str);
|
||||
prepl += pg_mblen(str);
|
||||
state = PAE_INREPL;
|
||||
} else if (!t_isspace(str))
|
||||
}
|
||||
else if (!t_isspace(str))
|
||||
ts_error(ERROR, "Affix parse error at %d line", line);
|
||||
} else if ( state == PAE_INFIND ) {
|
||||
if ( t_iseq(str,',') ) {
|
||||
*pfind='\0';
|
||||
}
|
||||
else if (state == PAE_INFIND)
|
||||
{
|
||||
if (t_iseq(str, ','))
|
||||
{
|
||||
*pfind = '\0';
|
||||
state = PAE_WAIT_REPL;
|
||||
} else if (t_isalpha(str)) {
|
||||
COPYCHAR(pfind,str);
|
||||
}
|
||||
else if (t_isalpha(str))
|
||||
{
|
||||
COPYCHAR(pfind, str);
|
||||
pfind += pg_mblen(str);
|
||||
} else if (!t_isspace(str))
|
||||
}
|
||||
else if (!t_isspace(str))
|
||||
ts_error(ERROR, "Affix parse error at %d line", line);
|
||||
} else if ( state == PAE_WAIT_REPL ) {
|
||||
if ( t_iseq(str,'-') ) {
|
||||
break; /* void repl */
|
||||
} else if ( t_isalpha(str) ) {
|
||||
COPYCHAR(prepl,str);
|
||||
}
|
||||
else if (state == PAE_WAIT_REPL)
|
||||
{
|
||||
if (t_iseq(str, '-'))
|
||||
{
|
||||
break; /* void repl */
|
||||
}
|
||||
else if (t_isalpha(str))
|
||||
{
|
||||
COPYCHAR(prepl, str);
|
||||
prepl += pg_mblen(str);
|
||||
state = PAE_INREPL;
|
||||
} else if (!t_isspace(str))
|
||||
}
|
||||
else if (!t_isspace(str))
|
||||
ts_error(ERROR, "Affix parse error at %d line", line);
|
||||
} else if ( state == PAE_INREPL ) {
|
||||
if ( t_iseq(str,'#') ) {
|
||||
}
|
||||
else if (state == PAE_INREPL)
|
||||
{
|
||||
if (t_iseq(str, '#'))
|
||||
{
|
||||
*prepl = '\0';
|
||||
break;
|
||||
} else if ( t_isalpha(str) ) {
|
||||
COPYCHAR(prepl,str);
|
||||
}
|
||||
else if (t_isalpha(str))
|
||||
{
|
||||
COPYCHAR(prepl, str);
|
||||
prepl += pg_mblen(str);
|
||||
} else if (!t_isspace(str))
|
||||
}
|
||||
else if (!t_isspace(str))
|
||||
ts_error(ERROR, "Affix parse error at %d line", line);
|
||||
} else
|
||||
}
|
||||
else
|
||||
ts_error(ERROR, "Unknown state in parse_affentry: %d", state);
|
||||
|
||||
str += pg_mblen(str);
|
||||
@ -370,8 +412,8 @@ parse_affentry( char *str, char *mask, char *find, char *repl, int line ) {
|
||||
|
||||
*pmask = *pfind = *prepl = '\0';
|
||||
|
||||
return ( *mask && ( *find || *repl) ) ? true : false;
|
||||
}
|
||||
return (*mask && (*find || *repl)) ? true : false;
|
||||
}
|
||||
|
||||
int
|
||||
NIImportAffixes(IspellDict * Conf, const char *filename)
|
||||
@ -387,8 +429,8 @@ NIImportAffixes(IspellDict * Conf, const char *filename)
|
||||
int flag = 0;
|
||||
char flagflags = 0;
|
||||
FILE *affix;
|
||||
int line=0;
|
||||
int oldformat = 0;
|
||||
int line = 0;
|
||||
int oldformat = 0;
|
||||
|
||||
if (!(affix = fopen(filename, "r")))
|
||||
return (1);
|
||||
@ -397,18 +439,20 @@ NIImportAffixes(IspellDict * Conf, const char *filename)
|
||||
while (fgets(str, sizeof(str), affix))
|
||||
{
|
||||
line++;
|
||||
pg_verifymbstr( str, strlen(str), false);
|
||||
memcpy(tmpstr, str, 32); /* compoundwords... */
|
||||
tmpstr[32]='\0';
|
||||
pg_verifymbstr(str, strlen(str), false);
|
||||
memcpy(tmpstr, str, 32); /* compoundwords... */
|
||||
tmpstr[32] = '\0';
|
||||
lowerstr(tmpstr);
|
||||
if (STRNCMP(tmpstr, "compoundwords") == 0)
|
||||
{
|
||||
s = findchar(str, 'l');
|
||||
if (s)
|
||||
{
|
||||
while (*s && !t_isspace(s)) s++;
|
||||
while (*s && t_isspace(s)) s++;
|
||||
if ( *s && pg_mblen(s) == 1 )
|
||||
while (*s && !t_isspace(s))
|
||||
s++;
|
||||
while (*s && t_isspace(s))
|
||||
s++;
|
||||
if (*s && pg_mblen(s) == 1)
|
||||
Conf->compoundcontrol = *s;
|
||||
oldformat++;
|
||||
continue;
|
||||
@ -433,12 +477,13 @@ NIImportAffixes(IspellDict * Conf, const char *filename)
|
||||
s = str + 4;
|
||||
flagflags = 0;
|
||||
|
||||
while (*s && t_isspace(s)) s++;
|
||||
while (*s && t_isspace(s))
|
||||
s++;
|
||||
oldformat++;
|
||||
|
||||
/* allow only single-encoded flags */
|
||||
if ( pg_mblen(s) != 1 )
|
||||
elog(ERROR,"Multiencoded flag at line %d: %s", line, s);
|
||||
if (pg_mblen(s) != 1)
|
||||
elog(ERROR, "Multiencoded flag at line %d: %s", line, s);
|
||||
|
||||
if (*s == '*')
|
||||
{
|
||||
@ -455,29 +500,31 @@ NIImportAffixes(IspellDict * Conf, const char *filename)
|
||||
s++;
|
||||
|
||||
/* allow only single-encoded flags */
|
||||
if ( pg_mblen(s) != 1 ) {
|
||||
if (pg_mblen(s) != 1)
|
||||
{
|
||||
flagflags = 0;
|
||||
elog(ERROR,"Multiencoded flag at line %d: %s", line, s);
|
||||
elog(ERROR, "Multiencoded flag at line %d: %s", line, s);
|
||||
}
|
||||
|
||||
flag = (unsigned char) *s;
|
||||
continue;
|
||||
}
|
||||
if ( STRNCMP(str, "COMPOUNDFLAG") == 0 || STRNCMP(str, "COMPOUNDMIN") == 0 ||
|
||||
STRNCMP(str, "PFX")==0 || STRNCMP(str, "SFX")==0 ) {
|
||||
if (STRNCMP(str, "COMPOUNDFLAG") == 0 || STRNCMP(str, "COMPOUNDMIN") == 0 ||
|
||||
STRNCMP(str, "PFX") == 0 || STRNCMP(str, "SFX") == 0)
|
||||
{
|
||||
|
||||
if ( oldformat )
|
||||
elog(ERROR,"Wrong affix file format");
|
||||
if (oldformat)
|
||||
elog(ERROR, "Wrong affix file format");
|
||||
|
||||
fclose(affix);
|
||||
return NIImportOOAffixes(Conf, filename);
|
||||
|
||||
|
||||
}
|
||||
if ((!suffixes) && (!prefixes))
|
||||
continue;
|
||||
|
||||
lowerstr(str);
|
||||
if ( !parse_affentry(str, mask, find, repl, line) )
|
||||
if (!parse_affentry(str, mask, find, repl, line))
|
||||
continue;
|
||||
|
||||
NIAddAffix(Conf, flag, flagflags, mask, find, repl, suffixes ? FF_SUFFIX : FF_PREFIX);
|
||||
@ -488,7 +535,8 @@ NIImportAffixes(IspellDict * Conf, const char *filename)
|
||||
}
|
||||
|
||||
int
|
||||
NIImportOOAffixes(IspellDict * Conf, const char *filename) {
|
||||
NIImportOOAffixes(IspellDict * Conf, const char *filename)
|
||||
{
|
||||
char str[BUFSIZ];
|
||||
char type[BUFSIZ];
|
||||
char sflag[BUFSIZ];
|
||||
@ -499,11 +547,11 @@ NIImportOOAffixes(IspellDict * Conf, const char *filename) {
|
||||
int flag = 0;
|
||||
char flagflags = 0;
|
||||
FILE *affix;
|
||||
int line=0;
|
||||
int scanread = 0;
|
||||
int line = 0;
|
||||
int scanread = 0;
|
||||
char scanbuf[BUFSIZ];
|
||||
|
||||
sprintf(scanbuf,"%%6s %%%ds %%%ds %%%ds %%%ds", BUFSIZ/5, BUFSIZ/5, BUFSIZ/5, BUFSIZ/5);
|
||||
sprintf(scanbuf, "%%6s %%%ds %%%ds %%%ds %%%ds", BUFSIZ / 5, BUFSIZ / 5, BUFSIZ / 5, BUFSIZ / 5);
|
||||
|
||||
if (!(affix = fopen(filename, "r")))
|
||||
return (1);
|
||||
@ -512,14 +560,17 @@ NIImportOOAffixes(IspellDict * Conf, const char *filename) {
|
||||
while (fgets(str, sizeof(str), affix))
|
||||
{
|
||||
line++;
|
||||
if ( *str == '\0' || t_isspace(str) || t_iseq(str,'#') )
|
||||
if (*str == '\0' || t_isspace(str) || t_iseq(str, '#'))
|
||||
continue;
|
||||
pg_verifymbstr( str, strlen(str), false);
|
||||
pg_verifymbstr(str, strlen(str), false);
|
||||
|
||||
if ( STRNCMP(str, "COMPOUNDFLAG")==0 ) {
|
||||
char *s = str+strlen("COMPOUNDFLAG");
|
||||
while (*s && t_isspace(s)) s++;
|
||||
if ( *s && pg_mblen(s) == 1 )
|
||||
if (STRNCMP(str, "COMPOUNDFLAG") == 0)
|
||||
{
|
||||
char *s = str + strlen("COMPOUNDFLAG");
|
||||
|
||||
while (*s && t_isspace(s))
|
||||
s++;
|
||||
if (*s && pg_mblen(s) == 1)
|
||||
Conf->compoundcontrol = *s;
|
||||
continue;
|
||||
}
|
||||
@ -527,28 +578,31 @@ NIImportOOAffixes(IspellDict * Conf, const char *filename) {
|
||||
scanread = sscanf(str, scanbuf, type, sflag, find, repl, mask);
|
||||
|
||||
lowerstr(type);
|
||||
if ( scanread<4 || (STRNCMP(type,"sfx") && STRNCMP(type,"pfx")) )
|
||||
if (scanread < 4 || (STRNCMP(type, "sfx") && STRNCMP(type, "pfx")))
|
||||
continue;
|
||||
|
||||
if ( scanread == 4 ) {
|
||||
if ( strlen(sflag) != 1 )
|
||||
if (scanread == 4)
|
||||
{
|
||||
if (strlen(sflag) != 1)
|
||||
continue;
|
||||
flag = *sflag;
|
||||
isSuffix = (STRNCMP(type,"sfx")==0) ? true : false;
|
||||
isSuffix = (STRNCMP(type, "sfx") == 0) ? true : false;
|
||||
lowerstr(find);
|
||||
if ( t_iseq(find,'y') )
|
||||
if (t_iseq(find, 'y'))
|
||||
flagflags |= FF_CROSSPRODUCT;
|
||||
else
|
||||
flagflags = 0;
|
||||
} else {
|
||||
if ( strlen(sflag) != 1 || flag != *sflag || flag==0 )
|
||||
}
|
||||
else
|
||||
{
|
||||
if (strlen(sflag) != 1 || flag != *sflag || flag == 0)
|
||||
continue;
|
||||
lowerstr(repl);
|
||||
lowerstr(find);
|
||||
lowerstr(mask);
|
||||
if ( t_iseq(find,'0') )
|
||||
if (t_iseq(find, '0'))
|
||||
*find = '\0';
|
||||
if ( t_iseq(repl,'0') )
|
||||
if (t_iseq(repl, '0'))
|
||||
*repl = '\0';
|
||||
|
||||
NIAddAffix(Conf, flag, flagflags, mask, find, repl, isSuffix ? FF_SUFFIX : FF_PREFIX);
|
||||
@ -658,7 +712,7 @@ NISortDictionary(IspellDict * Conf)
|
||||
int naffix = 3;
|
||||
|
||||
/* compress affixes */
|
||||
qsort((void *) Conf->Spell, Conf->nspell, sizeof(SPELL*), cmpspellaffix);
|
||||
qsort((void *) Conf->Spell, Conf->nspell, sizeof(SPELL *), cmpspellaffix);
|
||||
for (i = 1; i < Conf->nspell; i++)
|
||||
if (strcmp(Conf->Spell[i]->p.flag, Conf->Spell[i - 1]->p.flag))
|
||||
naffix++;
|
||||
@ -685,7 +739,7 @@ NISortDictionary(IspellDict * Conf)
|
||||
Conf->Spell[i]->p.d.len = strlen(Conf->Spell[i]->word);
|
||||
}
|
||||
|
||||
qsort((void *) Conf->Spell, Conf->nspell, sizeof(SPELL*), cmpspell);
|
||||
qsort((void *) Conf->Spell, Conf->nspell, sizeof(SPELL *), cmpspell);
|
||||
Conf->Dictionary = mkSPNode(Conf, 0, Conf->nspell, 0);
|
||||
|
||||
for (i = 0; i < Conf->nspell; i++)
|
||||
@ -806,7 +860,7 @@ NISortAffixes(IspellDict * Conf)
|
||||
CMPDAffix *ptr;
|
||||
int firstsuffix = -1;
|
||||
|
||||
if (Conf->naffixes==0)
|
||||
if (Conf->naffixes == 0)
|
||||
return;
|
||||
|
||||
if (Conf->naffixes > 1)
|
||||
@ -822,7 +876,7 @@ NISortAffixes(IspellDict * Conf)
|
||||
{
|
||||
if (firstsuffix < 0)
|
||||
firstsuffix = i;
|
||||
if ((Affix->flagflags & FF_COMPOUNDONLYAFX) && Affix->replen>0 )
|
||||
if ((Affix->flagflags & FF_COMPOUNDONLYAFX) && Affix->replen > 0)
|
||||
{
|
||||
if (ptr == Conf->CompoundAffix ||
|
||||
strbncmp((const unsigned char *) (ptr - 1)->affix,
|
||||
@ -907,14 +961,16 @@ CheckAffix(const char *word, size_t len, AFFIX * Affix, char flagflags, char *ne
|
||||
{
|
||||
strcpy(newword, word);
|
||||
strcpy(newword + len - Affix->replen, Affix->find);
|
||||
if ( baselen ) /* store length of non-changed part of word */
|
||||
if (baselen) /* store length of non-changed part of word */
|
||||
*baselen = len - Affix->replen;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* if prefix is a all non-chaged part's length then all word contains only prefix and suffix,
|
||||
so out */
|
||||
if ( baselen && *baselen + strlen(Affix->find) <= Affix->replen )
|
||||
/*
|
||||
* if prefix is a all non-chaged part's length then all word contains
|
||||
* only prefix and suffix, so out
|
||||
*/
|
||||
if (baselen && *baselen + strlen(Affix->find) <= Affix->replen)
|
||||
return NULL;
|
||||
strcpy(newword, Affix->find);
|
||||
strcat(newword, word + Affix->replen);
|
||||
@ -944,6 +1000,7 @@ CheckAffix(const char *word, size_t len, AFFIX * Affix, char flagflags, char *ne
|
||||
int wmasklen,
|
||||
masklen = strlen(Affix->mask);
|
||||
pg_wchar *mask;
|
||||
|
||||
mask = (pg_wchar *) palloc((masklen + 1) * sizeof(pg_wchar));
|
||||
wmasklen = pg_mb2wchar_with_len(Affix->mask, mask, masklen);
|
||||
|
||||
@ -1040,7 +1097,7 @@ NormalizeSubWord(IspellDict * Conf, char *word, char flag)
|
||||
*/
|
||||
while (snode)
|
||||
{
|
||||
int baselen=0;
|
||||
int baselen = 0;
|
||||
|
||||
/* find possible suffix */
|
||||
suffix = FinfAffixes(snode, word, wrdlen, &slevel, FF_SUFFIX);
|
||||
@ -1111,7 +1168,8 @@ typedef struct SplitVar
|
||||
static int
|
||||
CheckCompoundAffixes(CMPDAffix ** ptr, char *word, int len, bool CheckInPlace)
|
||||
{
|
||||
if ( CheckInPlace ) {
|
||||
if (CheckInPlace)
|
||||
{
|
||||
while ((*ptr)->affix)
|
||||
{
|
||||
if (len > (*ptr)->len && strncmp((*ptr)->affix, word, (*ptr)->len) == 0)
|
||||
@ -1122,13 +1180,16 @@ CheckCompoundAffixes(CMPDAffix ** ptr, char *word, int len, bool CheckInPlace)
|
||||
}
|
||||
(*ptr)++;
|
||||
}
|
||||
} else {
|
||||
char *affbegin;
|
||||
}
|
||||
else
|
||||
{
|
||||
char *affbegin;
|
||||
|
||||
while ((*ptr)->affix)
|
||||
{
|
||||
if (len > (*ptr)->len && (affbegin = strstr(word, (*ptr)->affix)) != NULL)
|
||||
{
|
||||
len = (*ptr)->len + (affbegin-word);
|
||||
len = (*ptr)->len + (affbegin - word);
|
||||
(*ptr)++;
|
||||
return len;
|
||||
}
|
||||
@ -1227,8 +1288,8 @@ SplitToVariants(IspellDict * Conf, SPNode * snode, SplitVar * orig, char *word,
|
||||
}
|
||||
}
|
||||
|
||||
if ( !node )
|
||||
break;
|
||||
if (!node)
|
||||
break;
|
||||
|
||||
StopLow = node->data;
|
||||
StopHigh = node->data + node->length;
|
||||
@ -1243,7 +1304,8 @@ SplitToVariants(IspellDict * Conf, SPNode * snode, SplitVar * orig, char *word,
|
||||
StopHigh = StopMiddle;
|
||||
}
|
||||
|
||||
if (StopLow < StopHigh) {
|
||||
if (StopLow < StopHigh)
|
||||
{
|
||||
|
||||
/* find infinitive */
|
||||
if (StopMiddle->isword && StopMiddle->compoundallow && notprobed[level])
|
||||
@ -1264,7 +1326,7 @@ SplitToVariants(IspellDict * Conf, SPNode * snode, SplitVar * orig, char *word,
|
||||
{
|
||||
/* then we will search more big word at the same point */
|
||||
SplitVar *ptr = var;
|
||||
|
||||
|
||||
while (ptr->next)
|
||||
ptr = ptr->next;
|
||||
ptr->next = SplitToVariants(Conf, node, var, word, wordlen, startpos, level);
|
||||
@ -1279,8 +1341,9 @@ SplitToVariants(IspellDict * Conf, SPNode * snode, SplitVar * orig, char *word,
|
||||
}
|
||||
}
|
||||
node = StopMiddle->node;
|
||||
} else
|
||||
node = NULL;
|
||||
}
|
||||
else
|
||||
node = NULL;
|
||||
level++;
|
||||
}
|
||||
|
||||
@ -1436,9 +1499,12 @@ NIFree(IspellDict * Conf)
|
||||
else
|
||||
pg_regfree(&(Affix[i].reg.regex));
|
||||
}
|
||||
if ( Affix[i].mask != VoidString ) free(Affix[i].mask);
|
||||
if ( Affix[i].find != VoidString ) free(Affix[i].find);
|
||||
if ( Affix[i].repl != VoidString ) free(Affix[i].repl);
|
||||
if (Affix[i].mask != VoidString)
|
||||
free(Affix[i].mask);
|
||||
if (Affix[i].find != VoidString)
|
||||
free(Affix[i].find);
|
||||
if (Affix[i].repl != VoidString)
|
||||
free(Affix[i].repl);
|
||||
}
|
||||
if (Conf->Spell)
|
||||
{
|
||||
|
@ -42,8 +42,8 @@ typedef struct spell_struct
|
||||
int affix;
|
||||
int len;
|
||||
} d;
|
||||
} p;
|
||||
char word[1];
|
||||
} p;
|
||||
char word[1];
|
||||
} SPELL;
|
||||
|
||||
#define SPELLHDRSZ (offsetof(SPELL, word))
|
||||
@ -110,7 +110,7 @@ typedef struct
|
||||
|
||||
int nspell;
|
||||
int mspell;
|
||||
SPELL **Spell;
|
||||
SPELL **Spell;
|
||||
|
||||
AffixNode *Suffix;
|
||||
AffixNode *Prefix;
|
||||
|
@ -33,9 +33,9 @@ nstrdup(char *ptr, int len)
|
||||
{
|
||||
if (t_iseq(ptr, '\\'))
|
||||
ptr++;
|
||||
COPYCHAR( cptr, ptr );
|
||||
cptr+=pg_mblen(ptr);
|
||||
ptr+=pg_mblen(ptr);
|
||||
COPYCHAR(cptr, ptr);
|
||||
cptr += pg_mblen(ptr);
|
||||
ptr += pg_mblen(ptr);
|
||||
}
|
||||
*cptr = '\0';
|
||||
|
||||
@ -53,9 +53,9 @@ parse_cfgdict(text *in, Map ** m)
|
||||
|
||||
while (ptr - VARDATA(in) < VARSIZE(in) - VARHDRSZ)
|
||||
{
|
||||
if ( t_iseq(ptr, ',') )
|
||||
if (t_iseq(ptr, ','))
|
||||
num++;
|
||||
ptr+=pg_mblen(ptr);
|
||||
ptr += pg_mblen(ptr);
|
||||
}
|
||||
|
||||
*m = mptr = (Map *) palloc(sizeof(Map) * (num + 2));
|
||||
@ -84,7 +84,7 @@ parse_cfgdict(text *in, Map ** m)
|
||||
mptr->key = nstrdup(begin, ptr - begin);
|
||||
state = CS_WAITEQ;
|
||||
}
|
||||
else if (t_iseq(ptr,'='))
|
||||
else if (t_iseq(ptr, '='))
|
||||
{
|
||||
mptr->key = nstrdup(begin, ptr - begin);
|
||||
state = CS_WAITVALUE;
|
||||
@ -163,7 +163,7 @@ parse_cfgdict(text *in, Map ** m)
|
||||
errmsg("bad parser state"),
|
||||
errdetail("%d at position %d.",
|
||||
state, (int) (ptr - VARDATA(in)))));
|
||||
ptr+=pg_mblen(ptr);
|
||||
ptr += pg_mblen(ptr);
|
||||
}
|
||||
|
||||
if (state == CS_IN2VALUE)
|
||||
|
@ -108,11 +108,11 @@ get_weight(char *buf, int2 *weight)
|
||||
{
|
||||
*weight = 0;
|
||||
|
||||
if ( !t_iseq(buf, ':') )
|
||||
if (!t_iseq(buf, ':'))
|
||||
return buf;
|
||||
|
||||
buf++;
|
||||
while ( *buf && pg_mblen(buf) == 1 )
|
||||
while (*buf && pg_mblen(buf) == 1)
|
||||
{
|
||||
switch (*buf)
|
||||
{
|
||||
@ -153,25 +153,26 @@ gettoken_query(QPRS_STATE * state, int4 *val, int4 *lenval, char **strval, int2
|
||||
{
|
||||
case WAITFIRSTOPERAND:
|
||||
case WAITOPERAND:
|
||||
if ( t_iseq(state->buf, '!') )
|
||||
if (t_iseq(state->buf, '!'))
|
||||
{
|
||||
(state->buf)++; /* can safely ++, t_iseq guarantee that pg_mblen()==1 */
|
||||
(state->buf)++; /* can safely ++, t_iseq guarantee
|
||||
* that pg_mblen()==1 */
|
||||
*val = (int4) '!';
|
||||
return OPR;
|
||||
}
|
||||
else if ( t_iseq(state->buf, '(') )
|
||||
else if (t_iseq(state->buf, '('))
|
||||
{
|
||||
state->count++;
|
||||
(state->buf)++;
|
||||
return OPEN;
|
||||
}
|
||||
else if ( t_iseq(state->buf, ':') )
|
||||
else if (t_iseq(state->buf, ':'))
|
||||
{
|
||||
ereport(ERROR,
|
||||
(errcode(ERRCODE_SYNTAX_ERROR),
|
||||
errmsg("error at start of operand")));
|
||||
}
|
||||
else if ( !t_isspace(state->buf) )
|
||||
else if (!t_isspace(state->buf))
|
||||
{
|
||||
state->valstate.prsbuf = state->buf;
|
||||
if (gettoken_tsvector(&(state->valstate)))
|
||||
@ -191,14 +192,14 @@ gettoken_query(QPRS_STATE * state, int4 *val, int4 *lenval, char **strval, int2
|
||||
}
|
||||
break;
|
||||
case WAITOPERATOR:
|
||||
if ( t_iseq(state->buf, '&') || t_iseq(state->buf, '|') )
|
||||
if (t_iseq(state->buf, '&') || t_iseq(state->buf, '|'))
|
||||
{
|
||||
state->state = WAITOPERAND;
|
||||
*val = (int4) *(state->buf);
|
||||
(state->buf)++;
|
||||
return OPR;
|
||||
}
|
||||
else if ( t_iseq(state->buf, ')') )
|
||||
else if (t_iseq(state->buf, ')'))
|
||||
{
|
||||
(state->buf)++;
|
||||
state->count--;
|
||||
@ -206,7 +207,7 @@ gettoken_query(QPRS_STATE * state, int4 *val, int4 *lenval, char **strval, int2
|
||||
}
|
||||
else if (*(state->buf) == '\0')
|
||||
return (state->count) ? ERR : END;
|
||||
else if ( !t_isspace(state->buf) )
|
||||
else if (!t_isspace(state->buf))
|
||||
return ERR;
|
||||
break;
|
||||
case WAITSINGLEOPERAND:
|
||||
@ -221,7 +222,7 @@ gettoken_query(QPRS_STATE * state, int4 *val, int4 *lenval, char **strval, int2
|
||||
return ERR;
|
||||
break;
|
||||
}
|
||||
state->buf+=pg_mblen(state->buf);
|
||||
state->buf += pg_mblen(state->buf);
|
||||
}
|
||||
return END;
|
||||
}
|
||||
@ -604,7 +605,7 @@ findoprnd(ITEM * ptr, int4 *pos)
|
||||
* input
|
||||
*/
|
||||
static QUERYTYPE *
|
||||
queryin(char *buf, void (*pushval) (QPRS_STATE *, int, char *, int, int2), int cfg_id, bool isplain)
|
||||
queryin(char *buf, void (*pushval) (QPRS_STATE *, int, char *, int, int2), int cfg_id, bool isplain)
|
||||
{
|
||||
QPRS_STATE state;
|
||||
int4 i;
|
||||
@ -701,8 +702,9 @@ queryin(char *buf, void (*pushval) (QPRS_STATE *, int, char *, int, int2), int c
|
||||
Datum
|
||||
tsquery_in(PG_FUNCTION_ARGS)
|
||||
{
|
||||
char * in = (char*)PG_GETARG_POINTER(0);
|
||||
pg_verifymbstr( in, strlen(in), false);
|
||||
char *in = (char *) PG_GETARG_POINTER(0);
|
||||
|
||||
pg_verifymbstr(in, strlen(in), false);
|
||||
|
||||
SET_FUNCOID();
|
||||
PG_RETURN_POINTER(queryin((char *) in, pushval_asis, 0, false));
|
||||
@ -739,23 +741,23 @@ infix(INFIX * in, bool first)
|
||||
if (in->curpol->type == VAL)
|
||||
{
|
||||
char *op = in->op + in->curpol->distance;
|
||||
int clen;
|
||||
int clen;
|
||||
|
||||
RESIZEBUF(in, in->curpol->length * (pg_database_encoding_max_length()+1) + 2 + 5);
|
||||
RESIZEBUF(in, in->curpol->length * (pg_database_encoding_max_length() + 1) + 2 + 5);
|
||||
*(in->cur) = '\'';
|
||||
in->cur++;
|
||||
while (*op)
|
||||
{
|
||||
if ( t_iseq(op, '\'') )
|
||||
if (t_iseq(op, '\''))
|
||||
{
|
||||
*(in->cur) = '\'';
|
||||
in->cur++;
|
||||
}
|
||||
COPYCHAR(in->cur,op);
|
||||
COPYCHAR(in->cur, op);
|
||||
|
||||
clen = pg_mblen(op);
|
||||
op+=clen;
|
||||
in->cur+=clen;
|
||||
op += clen;
|
||||
in->cur += clen;
|
||||
}
|
||||
*(in->cur) = '\'';
|
||||
in->cur++;
|
||||
|
@ -48,7 +48,7 @@ typedef struct
|
||||
#define CLOSE 5
|
||||
#define VALSTOP 6 /* for stop words */
|
||||
|
||||
bool TS_execute(ITEM *curitem, void *checkval,
|
||||
bool calcnot, bool (*chkcond) (void *checkval, ITEM *val));
|
||||
bool TS_execute(ITEM * curitem, void *checkval,
|
||||
bool calcnot, bool (*chkcond) (void *checkval, ITEM * val));
|
||||
|
||||
#endif
|
||||
|
@ -3,7 +3,7 @@
|
||||
|
||||
#include "query.h"
|
||||
|
||||
ITEM *clean_NOT_v2(ITEM *ptr, int4 *len);
|
||||
ITEM *clean_fakeval_v2(ITEM *ptr, int4 *len);
|
||||
ITEM *clean_NOT_v2(ITEM * ptr, int4 *len);
|
||||
ITEM *clean_fakeval_v2(ITEM * ptr, int4 *len);
|
||||
|
||||
#endif
|
||||
|
@ -29,7 +29,7 @@ makesign(QUERYTYPE * a)
|
||||
for (i = 0; i < a->size; i++)
|
||||
{
|
||||
if (ptr->type == VAL)
|
||||
sign |= ((TPQTGist)1) << (ptr->val % SIGLEN);
|
||||
sign |= ((TPQTGist) 1) << (ptr->val % SIGLEN);
|
||||
ptr++;
|
||||
}
|
||||
|
||||
@ -104,7 +104,7 @@ tsq_mcontained(PG_FUNCTION_ARGS)
|
||||
PG_GETARG_DATUM(1),
|
||||
PG_GETARG_DATUM(0)
|
||||
)
|
||||
);
|
||||
);
|
||||
}
|
||||
|
||||
PG_FUNCTION_INFO_V1(gtsq_in);
|
||||
@ -272,7 +272,7 @@ typedef struct
|
||||
{
|
||||
OffsetNumber pos;
|
||||
int4 cost;
|
||||
} SPLITCOST;
|
||||
} SPLITCOST;
|
||||
|
||||
static int
|
||||
comparecost(const void *a, const void *b)
|
||||
|
@ -41,13 +41,13 @@ static float weights[] = {0.1, 0.2, 0.4, 1.0};
|
||||
|
||||
#define wpos(wep) ( w[ WEP_GETWEIGHT(wep) ] )
|
||||
|
||||
#define RANK_NO_NORM 0x00
|
||||
#define RANK_NORM_LOGLENGTH 0x01
|
||||
#define RANK_NORM_LENGTH 0x02
|
||||
#define RANK_NORM_EXTDIST 0x04
|
||||
#define RANK_NO_NORM 0x00
|
||||
#define RANK_NORM_LOGLENGTH 0x01
|
||||
#define RANK_NORM_LENGTH 0x02
|
||||
#define RANK_NORM_EXTDIST 0x04
|
||||
#define RANK_NORM_UNIQ 0x08
|
||||
#define RANK_NORM_LOGUNIQ 0x10
|
||||
#define DEF_NORM_METHOD RANK_NO_NORM
|
||||
#define DEF_NORM_METHOD RANK_NO_NORM
|
||||
|
||||
static float calc_rank_or(float *w, tsvector * t, QUERYTYPE * q);
|
||||
static float calc_rank_and(float *w, tsvector * t, QUERYTYPE * q);
|
||||
@ -334,19 +334,20 @@ calc_rank(float *w, tsvector * t, QUERYTYPE * q, int4 method)
|
||||
if (res < 0)
|
||||
res = 1e-20;
|
||||
|
||||
if ( (method & RANK_NORM_LOGLENGTH) && t->size>0 )
|
||||
if ((method & RANK_NORM_LOGLENGTH) && t->size > 0)
|
||||
res /= log((double) (cnt_length(t) + 1)) / log(2.0);
|
||||
|
||||
if ( method & RANK_NORM_LENGTH ) {
|
||||
if (method & RANK_NORM_LENGTH)
|
||||
{
|
||||
len = cnt_length(t);
|
||||
if ( len>0 )
|
||||
if (len > 0)
|
||||
res /= (float) len;
|
||||
}
|
||||
|
||||
if ( (method & RANK_NORM_UNIQ) && t->size > 0 )
|
||||
res /= (float)( t->size );
|
||||
if ((method & RANK_NORM_UNIQ) && t->size > 0)
|
||||
res /= (float) (t->size);
|
||||
|
||||
if ( (method & RANK_NORM_LOGUNIQ) && t->size > 0 )
|
||||
if ((method & RANK_NORM_LOGUNIQ) && t->size > 0)
|
||||
res /= log((double) (t->size + 1)) / log(2.0);
|
||||
|
||||
return res;
|
||||
@ -457,17 +458,18 @@ reset_istrue_flag(QUERYTYPE * query)
|
||||
}
|
||||
}
|
||||
|
||||
typedef struct {
|
||||
int pos;
|
||||
int p;
|
||||
int q;
|
||||
DocRepresentation *begin;
|
||||
DocRepresentation *end;
|
||||
} Extention;
|
||||
typedef struct
|
||||
{
|
||||
int pos;
|
||||
int p;
|
||||
int q;
|
||||
DocRepresentation *begin;
|
||||
DocRepresentation *end;
|
||||
} Extention;
|
||||
|
||||
|
||||
static bool
|
||||
Cover(DocRepresentation * doc, int len, QUERYTYPE * query, Extention *ext)
|
||||
Cover(DocRepresentation * doc, int len, QUERYTYPE * query, Extention * ext)
|
||||
{
|
||||
DocRepresentation *ptr;
|
||||
int lastpos = ext->pos;
|
||||
@ -513,7 +515,8 @@ Cover(DocRepresentation * doc, int len, QUERYTYPE * query, Extention *ext)
|
||||
ptr->item[i]->istrue = 1;
|
||||
if (TS_execute(GETQUERY(query), NULL, true, checkcondition_ITEM))
|
||||
{
|
||||
if (ptr->pos < ext->p) {
|
||||
if (ptr->pos < ext->p)
|
||||
{
|
||||
ext->begin = ptr;
|
||||
ext->p = ptr->pos;
|
||||
}
|
||||
@ -629,69 +632,77 @@ get_docrep(tsvector * txt, QUERYTYPE * query, int *doclen)
|
||||
}
|
||||
|
||||
static float4
|
||||
calc_rank_cd(float4 *arrdata, tsvector *txt, QUERYTYPE *query, int method) {
|
||||
calc_rank_cd(float4 *arrdata, tsvector * txt, QUERYTYPE * query, int method)
|
||||
{
|
||||
DocRepresentation *doc;
|
||||
int len,
|
||||
int len,
|
||||
i,
|
||||
doclen = 0;
|
||||
Extention ext;
|
||||
double Wdoc = 0.0;
|
||||
double invws[lengthof(weights)];
|
||||
double SumDist=0.0, PrevExtPos=0.0, CurExtPos=0.0;
|
||||
int NExtent=0;
|
||||
double SumDist = 0.0,
|
||||
PrevExtPos = 0.0,
|
||||
CurExtPos = 0.0;
|
||||
int NExtent = 0;
|
||||
|
||||
for (i = 0; i < lengthof(weights); i++)
|
||||
{
|
||||
invws[i] = ((double)((arrdata[i] >= 0) ? arrdata[i] : weights[i]));
|
||||
invws[i] = ((double) ((arrdata[i] >= 0) ? arrdata[i] : weights[i]));
|
||||
if (invws[i] > 1.0)
|
||||
ereport(ERROR,
|
||||
(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
|
||||
errmsg("weight out of range")));
|
||||
invws[i] = 1.0/invws[i];
|
||||
invws[i] = 1.0 / invws[i];
|
||||
}
|
||||
|
||||
doc = get_docrep(txt, query, &doclen);
|
||||
if (!doc)
|
||||
if (!doc)
|
||||
return 0.0;
|
||||
|
||||
MemSet( &ext, 0, sizeof(Extention) );
|
||||
while (Cover(doc, doclen, query, &ext)) {
|
||||
double Cpos = 0.0;
|
||||
double InvSum = 0.0;
|
||||
MemSet(&ext, 0, sizeof(Extention));
|
||||
while (Cover(doc, doclen, query, &ext))
|
||||
{
|
||||
double Cpos = 0.0;
|
||||
double InvSum = 0.0;
|
||||
DocRepresentation *ptr = ext.begin;
|
||||
|
||||
while ( ptr<=ext.end ) {
|
||||
InvSum += invws[ ptr->wclass ];
|
||||
while (ptr <= ext.end)
|
||||
{
|
||||
InvSum += invws[ptr->wclass];
|
||||
ptr++;
|
||||
}
|
||||
|
||||
Cpos = ((double)( ext.end-ext.begin+1 )) / InvSum;
|
||||
Wdoc += Cpos / ( (double)(( 1 + (ext.q - ext.p) - (ext.end - ext.begin) )) );
|
||||
Cpos = ((double) (ext.end - ext.begin + 1)) / InvSum;
|
||||
Wdoc += Cpos / ((double) ((1 + (ext.q - ext.p) - (ext.end - ext.begin))));
|
||||
|
||||
CurExtPos = ((double)(ext.q + ext.p))/2.0;
|
||||
if ( NExtent>0 && CurExtPos > PrevExtPos /* prevent devision by zero in a case of multiple lexize */ )
|
||||
SumDist += 1.0/( CurExtPos - PrevExtPos );
|
||||
CurExtPos = ((double) (ext.q + ext.p)) / 2.0;
|
||||
if (NExtent > 0 && CurExtPos > PrevExtPos /* prevent devision by
|
||||
* zero in a case of
|
||||
multiple lexize */ )
|
||||
SumDist += 1.0 / (CurExtPos - PrevExtPos);
|
||||
|
||||
PrevExtPos = CurExtPos;
|
||||
NExtent++;
|
||||
NExtent++;
|
||||
}
|
||||
|
||||
if ( (method & RANK_NORM_LOGLENGTH) && txt->size > 0 )
|
||||
if ((method & RANK_NORM_LOGLENGTH) && txt->size > 0)
|
||||
Wdoc /= log((double) (cnt_length(txt) + 1));
|
||||
|
||||
if ( method & RANK_NORM_LENGTH ) {
|
||||
if (method & RANK_NORM_LENGTH)
|
||||
{
|
||||
len = cnt_length(txt);
|
||||
if ( len>0 )
|
||||
if (len > 0)
|
||||
Wdoc /= (double) len;
|
||||
}
|
||||
|
||||
if ( (method & RANK_NORM_EXTDIST) && SumDist > 0 )
|
||||
Wdoc /= ((double)NExtent) / SumDist;
|
||||
if ((method & RANK_NORM_EXTDIST) && SumDist > 0)
|
||||
Wdoc /= ((double) NExtent) / SumDist;
|
||||
|
||||
if ( (method & RANK_NORM_UNIQ) && txt->size > 0 )
|
||||
Wdoc /= (double)( txt->size );
|
||||
if ((method & RANK_NORM_UNIQ) && txt->size > 0)
|
||||
Wdoc /= (double) (txt->size);
|
||||
|
||||
if ( (method & RANK_NORM_LOGUNIQ) && txt->size > 0 )
|
||||
if ((method & RANK_NORM_LOGUNIQ) && txt->size > 0)
|
||||
Wdoc /= log((double) (txt->size + 1)) / log(2.0);
|
||||
|
||||
for (i = 0; i < doclen; i++)
|
||||
@ -699,13 +710,13 @@ calc_rank_cd(float4 *arrdata, tsvector *txt, QUERYTYPE *query, int method) {
|
||||
pfree(doc[i].item);
|
||||
pfree(doc);
|
||||
|
||||
return (float4)Wdoc;
|
||||
}
|
||||
return (float4) Wdoc;
|
||||
}
|
||||
|
||||
Datum
|
||||
rank_cd(PG_FUNCTION_ARGS)
|
||||
{
|
||||
ArrayType *win = (ArrayType *) PG_DETOAST_DATUM(PG_GETARG_DATUM(0));
|
||||
ArrayType *win = (ArrayType *) PG_DETOAST_DATUM(PG_GETARG_DATUM(0));
|
||||
tsvector *txt = (tsvector *) PG_DETOAST_DATUM(PG_GETARG_DATUM(1));
|
||||
QUERYTYPE *query = (QUERYTYPE *) PG_DETOAST_DATUM_COPY(PG_GETARG_DATUM(2));
|
||||
int method = DEF_NORM_METHOD;
|
||||
@ -729,7 +740,7 @@ rank_cd(PG_FUNCTION_ARGS)
|
||||
if (PG_NARGS() == 4)
|
||||
method = PG_GETARG_INT32(3);
|
||||
|
||||
res = calc_rank_cd( (float4 *) ARR_DATA_PTR(win), txt, query, method);
|
||||
res = calc_rank_cd((float4 *) ARR_DATA_PTR(win), txt, query, method);
|
||||
|
||||
PG_FREE_IF_COPY(win, 0);
|
||||
PG_FREE_IF_COPY(txt, 1);
|
||||
@ -744,10 +755,10 @@ rank_cd_def(PG_FUNCTION_ARGS)
|
||||
{
|
||||
tsvector *txt = (tsvector *) PG_DETOAST_DATUM(PG_GETARG_DATUM(0));
|
||||
QUERYTYPE *query = (QUERYTYPE *) PG_DETOAST_DATUM_COPY(PG_GETARG_DATUM(1));
|
||||
float4 res;
|
||||
float4 res;
|
||||
|
||||
res = calc_rank_cd(weights, txt, query, (PG_NARGS() == 3) ? PG_GETARG_DATUM(2) : DEF_NORM_METHOD);
|
||||
|
||||
res = calc_rank_cd( weights, txt, query, (PG_NARGS() == 3) ? PG_GETARG_DATUM(2) : DEF_NORM_METHOD);
|
||||
|
||||
PG_FREE_IF_COPY(txt, 0);
|
||||
PG_FREE_IF_COPY(query, 1);
|
||||
|
||||
@ -791,7 +802,7 @@ get_covers(PG_FUNCTION_ARGS)
|
||||
text *out;
|
||||
char *cptr;
|
||||
DocRepresentation *doc;
|
||||
int olddwpos = 0;
|
||||
int olddwpos = 0;
|
||||
int ncover = 1;
|
||||
Extention ext;
|
||||
|
||||
@ -833,7 +844,7 @@ get_covers(PG_FUNCTION_ARGS)
|
||||
}
|
||||
qsort((void *) dw, dlen, sizeof(DocWord), compareDocWord);
|
||||
|
||||
MemSet( &ext, 0, sizeof(Extention) );
|
||||
MemSet(&ext, 0, sizeof(Extention));
|
||||
while (Cover(doc, rlen, query, &ext))
|
||||
{
|
||||
dwptr = dw + olddwpos;
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -2,15 +2,16 @@
|
||||
/* This file was generated automatically by the Snowball to ANSI C compiler */
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
extern "C"
|
||||
{
|
||||
#endif
|
||||
|
||||
extern struct SN_env * russian_UTF_8_create_env(void);
|
||||
extern void russian_UTF_8_close_env(struct SN_env * z);
|
||||
extern struct SN_env *russian_UTF_8_create_env(void);
|
||||
extern void russian_UTF_8_close_env(struct SN_env * z);
|
||||
|
||||
extern int russian_UTF_8_stem(struct SN_env * z);
|
||||
extern int russian_UTF_8_stem(struct SN_env * z);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
@ -48,7 +48,7 @@ readstoplist(text *in, StopList * s)
|
||||
while (fgets(buf, STOPBUFLEN, hin))
|
||||
{
|
||||
buf[strlen(buf) - 1] = '\0';
|
||||
pg_verifymbstr( buf, strlen(buf), false );
|
||||
pg_verifymbstr(buf, strlen(buf), false);
|
||||
lowerstr(buf);
|
||||
if (*buf == '\0')
|
||||
continue;
|
||||
|
@ -301,14 +301,15 @@ parsetext_v2(TSCfgInfo * cfg, PRSTEXT * prs, char *buf, int4 buflen)
|
||||
|
||||
LexizeInit(&ldata, cfg);
|
||||
|
||||
do {
|
||||
do
|
||||
{
|
||||
type = DatumGetInt32(FunctionCall3(
|
||||
&(prsobj->getlexeme_info),
|
||||
PointerGetDatum(prsobj->prs),
|
||||
PointerGetDatum(&lemm),
|
||||
&(prsobj->getlexeme_info),
|
||||
PointerGetDatum(prsobj->prs),
|
||||
PointerGetDatum(&lemm),
|
||||
PointerGetDatum(&lenlemm)));
|
||||
|
||||
if (type>0 && lenlemm >= MAXSTRLEN)
|
||||
if (type > 0 && lenlemm >= MAXSTRLEN)
|
||||
{
|
||||
#ifdef IGNORE_LONGLEXEME
|
||||
ereport(NOTICE,
|
||||
@ -324,9 +325,9 @@ parsetext_v2(TSCfgInfo * cfg, PRSTEXT * prs, char *buf, int4 buflen)
|
||||
|
||||
LexizeAddLemm(&ldata, type, lemm, lenlemm);
|
||||
|
||||
while( (norms = LexizeExec(&ldata, NULL)) != NULL )
|
||||
while ((norms = LexizeExec(&ldata, NULL)) != NULL)
|
||||
{
|
||||
TSLexeme *ptr = norms;
|
||||
TSLexeme *ptr = norms;
|
||||
|
||||
prs->pos++; /* set pos */
|
||||
|
||||
@ -338,7 +339,7 @@ parsetext_v2(TSCfgInfo * cfg, PRSTEXT * prs, char *buf, int4 buflen)
|
||||
prs->words = (TSWORD *) repalloc((void *) prs->words, prs->lenwords * sizeof(TSWORD));
|
||||
}
|
||||
|
||||
if ( ptr->flags & TSL_ADDPOS )
|
||||
if (ptr->flags & TSL_ADDPOS)
|
||||
prs->pos++;
|
||||
prs->words[prs->curwords].len = strlen(ptr->lexeme);
|
||||
prs->words[prs->curwords].word = ptr->lexeme;
|
||||
@ -349,8 +350,8 @@ parsetext_v2(TSCfgInfo * cfg, PRSTEXT * prs, char *buf, int4 buflen)
|
||||
prs->curwords++;
|
||||
}
|
||||
pfree(norms);
|
||||
}
|
||||
} while(type>0);
|
||||
}
|
||||
} while (type > 0);
|
||||
|
||||
FunctionCall1(
|
||||
&(prsobj->end_info),
|
||||
@ -407,30 +408,35 @@ hlfinditem(HLPRSTEXT * prs, QUERYTYPE * query, char *buf, int buflen)
|
||||
}
|
||||
|
||||
static void
|
||||
addHLParsedLex(HLPRSTEXT *prs, QUERYTYPE * query, ParsedLex *lexs, TSLexeme *norms) {
|
||||
ParsedLex *tmplexs;
|
||||
TSLexeme *ptr;
|
||||
addHLParsedLex(HLPRSTEXT * prs, QUERYTYPE * query, ParsedLex * lexs, TSLexeme * norms)
|
||||
{
|
||||
ParsedLex *tmplexs;
|
||||
TSLexeme *ptr;
|
||||
|
||||
while( lexs ) {
|
||||
|
||||
if ( lexs->type > 0 )
|
||||
while (lexs)
|
||||
{
|
||||
|
||||
if (lexs->type > 0)
|
||||
hladdword(prs, lexs->lemm, lexs->lenlemm, lexs->type);
|
||||
|
||||
ptr = norms;
|
||||
while( ptr && ptr->lexeme ) {
|
||||
while (ptr && ptr->lexeme)
|
||||
{
|
||||
hlfinditem(prs, query, ptr->lexeme, strlen(ptr->lexeme));
|
||||
ptr++;
|
||||
}
|
||||
|
||||
tmplexs = lexs->next;
|
||||
pfree( lexs );
|
||||
pfree(lexs);
|
||||
lexs = tmplexs;
|
||||
}
|
||||
|
||||
if ( norms ) {
|
||||
if (norms)
|
||||
{
|
||||
ptr = norms;
|
||||
while( ptr->lexeme ) {
|
||||
pfree( ptr->lexeme );
|
||||
while (ptr->lexeme)
|
||||
{
|
||||
pfree(ptr->lexeme);
|
||||
ptr++;
|
||||
}
|
||||
pfree(norms);
|
||||
@ -445,8 +451,8 @@ hlparsetext(TSCfgInfo * cfg, HLPRSTEXT * prs, QUERYTYPE * query, char *buf, int4
|
||||
char *lemm = NULL;
|
||||
WParserInfo *prsobj = findprs(cfg->prs_id);
|
||||
LexizeData ldata;
|
||||
TSLexeme *norms;
|
||||
ParsedLex *lexs;
|
||||
TSLexeme *norms;
|
||||
ParsedLex *lexs;
|
||||
|
||||
prsobj->prs = (void *) DatumGetPointer(
|
||||
FunctionCall2(
|
||||
@ -458,14 +464,15 @@ hlparsetext(TSCfgInfo * cfg, HLPRSTEXT * prs, QUERYTYPE * query, char *buf, int4
|
||||
|
||||
LexizeInit(&ldata, cfg);
|
||||
|
||||
do {
|
||||
do
|
||||
{
|
||||
type = DatumGetInt32(FunctionCall3(
|
||||
&(prsobj->getlexeme_info),
|
||||
PointerGetDatum(prsobj->prs),
|
||||
PointerGetDatum(&lemm),
|
||||
PointerGetDatum(&lenlemm)));
|
||||
&(prsobj->getlexeme_info),
|
||||
PointerGetDatum(prsobj->prs),
|
||||
PointerGetDatum(&lemm),
|
||||
PointerGetDatum(&lenlemm)));
|
||||
|
||||
if (type>0 && lenlemm >= MAXSTRLEN)
|
||||
if (type > 0 && lenlemm >= MAXSTRLEN)
|
||||
{
|
||||
#ifdef IGNORE_LONGLEXEME
|
||||
ereport(NOTICE,
|
||||
@ -481,14 +488,15 @@ hlparsetext(TSCfgInfo * cfg, HLPRSTEXT * prs, QUERYTYPE * query, char *buf, int4
|
||||
|
||||
LexizeAddLemm(&ldata, type, lemm, lenlemm);
|
||||
|
||||
do {
|
||||
if ( (norms = LexizeExec(&ldata,&lexs)) != NULL )
|
||||
do
|
||||
{
|
||||
if ((norms = LexizeExec(&ldata, &lexs)) != NULL)
|
||||
addHLParsedLex(prs, query, lexs, norms);
|
||||
else
|
||||
else
|
||||
addHLParsedLex(prs, query, lexs, NULL);
|
||||
} while( norms );
|
||||
} while (norms);
|
||||
|
||||
} while( type>0 );
|
||||
} while (type > 0);
|
||||
|
||||
FunctionCall1(
|
||||
&(prsobj->end_info),
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* lexize stream of lexemes
|
||||
* lexize stream of lexemes
|
||||
* Teodor Sigaev <teodor@sigaev.ru>
|
||||
*/
|
||||
#include "postgres.h"
|
||||
@ -11,34 +11,39 @@
|
||||
#include "dict.h"
|
||||
|
||||
void
|
||||
LexizeInit(LexizeData *ld, TSCfgInfo *cfg) {
|
||||
LexizeInit(LexizeData * ld, TSCfgInfo * cfg)
|
||||
{
|
||||
ld->cfg = cfg;
|
||||
ld->curDictId = InvalidOid;
|
||||
ld->posDict = 0;
|
||||
ld->towork.head = ld->towork.tail = ld->curSub = NULL;
|
||||
ld->waste.head = ld->waste.tail = NULL;
|
||||
ld->lastRes=NULL;
|
||||
ld->tmpRes=NULL;
|
||||
ld->lastRes = NULL;
|
||||
ld->tmpRes = NULL;
|
||||
}
|
||||
|
||||
static void
|
||||
LPLAddTail(ListParsedLex *list, ParsedLex *newpl) {
|
||||
if ( list->tail ) {
|
||||
LPLAddTail(ListParsedLex * list, ParsedLex * newpl)
|
||||
{
|
||||
if (list->tail)
|
||||
{
|
||||
list->tail->next = newpl;
|
||||
list->tail = newpl;
|
||||
} else
|
||||
}
|
||||
else
|
||||
list->head = list->tail = newpl;
|
||||
newpl->next = NULL;
|
||||
}
|
||||
|
||||
static ParsedLex*
|
||||
LPLRemoveHead(ListParsedLex *list) {
|
||||
ParsedLex *res = list->head;
|
||||
static ParsedLex *
|
||||
LPLRemoveHead(ListParsedLex * list)
|
||||
{
|
||||
ParsedLex *res = list->head;
|
||||
|
||||
if ( list->head )
|
||||
if (list->head)
|
||||
list->head = list->head->next;
|
||||
|
||||
if ( list->head == NULL )
|
||||
if (list->head == NULL)
|
||||
list->tail = NULL;
|
||||
|
||||
return res;
|
||||
@ -46,10 +51,11 @@ LPLRemoveHead(ListParsedLex *list) {
|
||||
|
||||
|
||||
void
|
||||
LexizeAddLemm(LexizeData *ld, int type, char *lemm, int lenlemm) {
|
||||
ParsedLex *newpl = (ParsedLex*)palloc( sizeof(ParsedLex) );
|
||||
LexizeAddLemm(LexizeData * ld, int type, char *lemm, int lenlemm)
|
||||
{
|
||||
ParsedLex *newpl = (ParsedLex *) palloc(sizeof(ParsedLex));
|
||||
|
||||
newpl = (ParsedLex*)palloc( sizeof(ParsedLex) );
|
||||
newpl = (ParsedLex *) palloc(sizeof(ParsedLex));
|
||||
newpl->type = type;
|
||||
newpl->lemm = lemm;
|
||||
newpl->lenlemm = lenlemm;
|
||||
@ -58,20 +64,27 @@ LexizeAddLemm(LexizeData *ld, int type, char *lemm, int lenlemm) {
|
||||
}
|
||||
|
||||
static void
|
||||
RemoveHead(LexizeData *ld) {
|
||||
RemoveHead(LexizeData * ld)
|
||||
{
|
||||
LPLAddTail(&ld->waste, LPLRemoveHead(&ld->towork));
|
||||
|
||||
ld->posDict = 0;
|
||||
}
|
||||
|
||||
static void
|
||||
setCorrLex(LexizeData *ld, ParsedLex **correspondLexem) {
|
||||
if ( correspondLexem ) {
|
||||
setCorrLex(LexizeData * ld, ParsedLex ** correspondLexem)
|
||||
{
|
||||
if (correspondLexem)
|
||||
{
|
||||
*correspondLexem = ld->waste.head;
|
||||
} else {
|
||||
ParsedLex *tmp, *ptr = ld->waste.head;
|
||||
}
|
||||
else
|
||||
{
|
||||
ParsedLex *tmp,
|
||||
*ptr = ld->waste.head;
|
||||
|
||||
while(ptr) {
|
||||
while (ptr)
|
||||
{
|
||||
tmp = ptr->next;
|
||||
pfree(ptr);
|
||||
ptr = tmp;
|
||||
@ -81,11 +94,14 @@ setCorrLex(LexizeData *ld, ParsedLex **correspondLexem) {
|
||||
}
|
||||
|
||||
static void
|
||||
moveToWaste(LexizeData *ld, ParsedLex *stop) {
|
||||
bool go = true;
|
||||
moveToWaste(LexizeData * ld, ParsedLex * stop)
|
||||
{
|
||||
bool go = true;
|
||||
|
||||
while( ld->towork.head && go) {
|
||||
if (ld->towork.head == stop) {
|
||||
while (ld->towork.head && go)
|
||||
{
|
||||
if (ld->towork.head == stop)
|
||||
{
|
||||
ld->curSub = stop->next;
|
||||
go = false;
|
||||
}
|
||||
@ -94,110 +110,124 @@ moveToWaste(LexizeData *ld, ParsedLex *stop) {
|
||||
}
|
||||
|
||||
static void
|
||||
setNewTmpRes(LexizeData *ld, ParsedLex *lex, TSLexeme *res) {
|
||||
if ( ld->tmpRes ) {
|
||||
TSLexeme *ptr;
|
||||
for( ptr=ld->tmpRes; ptr->lexeme; ptr++ )
|
||||
pfree( ptr->lexeme );
|
||||
pfree( ld->tmpRes );
|
||||
setNewTmpRes(LexizeData * ld, ParsedLex * lex, TSLexeme * res)
|
||||
{
|
||||
if (ld->tmpRes)
|
||||
{
|
||||
TSLexeme *ptr;
|
||||
|
||||
for (ptr = ld->tmpRes; ptr->lexeme; ptr++)
|
||||
pfree(ptr->lexeme);
|
||||
pfree(ld->tmpRes);
|
||||
}
|
||||
ld->tmpRes = res;
|
||||
ld->lastRes = lex;
|
||||
}
|
||||
|
||||
TSLexeme*
|
||||
LexizeExec(LexizeData *ld, ParsedLex **correspondLexem) {
|
||||
int i;
|
||||
ListDictionary *map;
|
||||
DictInfo *dict;
|
||||
TSLexeme *res;
|
||||
TSLexeme *
|
||||
LexizeExec(LexizeData * ld, ParsedLex ** correspondLexem)
|
||||
{
|
||||
int i;
|
||||
ListDictionary *map;
|
||||
DictInfo *dict;
|
||||
TSLexeme *res;
|
||||
|
||||
if ( ld->curDictId == InvalidOid ) {
|
||||
/*
|
||||
* usial mode: dictionary wants only one word,
|
||||
* but we should keep in mind that we should go through
|
||||
* all stack
|
||||
if (ld->curDictId == InvalidOid)
|
||||
{
|
||||
/*
|
||||
* usial mode: dictionary wants only one word, but we should keep in
|
||||
* mind that we should go through all stack
|
||||
*/
|
||||
|
||||
while( ld->towork.head ) {
|
||||
ParsedLex *curVal = ld->towork.head;
|
||||
while (ld->towork.head)
|
||||
{
|
||||
ParsedLex *curVal = ld->towork.head;
|
||||
|
||||
map = ld->cfg->map + curVal->type;
|
||||
|
||||
if (curVal->type == 0 || curVal->type >= ld->cfg->len || map->len == 0 ) {
|
||||
if (curVal->type == 0 || curVal->type >= ld->cfg->len || map->len == 0)
|
||||
{
|
||||
/* skip this type of lexeme */
|
||||
RemoveHead(ld);
|
||||
continue;
|
||||
}
|
||||
|
||||
for (i = ld->posDict; i < map->len; i++) {
|
||||
for (i = ld->posDict; i < map->len; i++)
|
||||
{
|
||||
dict = finddict(DatumGetObjectId(map->dict_id[i]));
|
||||
|
||||
ld->dictState.isend = ld->dictState.getnext = false;
|
||||
ld->dictState.private = NULL;
|
||||
res = (TSLexeme *) DatumGetPointer( FunctionCall4(
|
||||
&(dict->lexize_info),
|
||||
PointerGetDatum(dict->dictionary),
|
||||
PointerGetDatum(curVal->lemm),
|
||||
Int32GetDatum(curVal->lenlemm),
|
||||
PointerGetDatum(&ld->dictState)
|
||||
));
|
||||
res = (TSLexeme *) DatumGetPointer(FunctionCall4(
|
||||
&(dict->lexize_info),
|
||||
PointerGetDatum(dict->dictionary),
|
||||
PointerGetDatum(curVal->lemm),
|
||||
Int32GetDatum(curVal->lenlemm),
|
||||
PointerGetDatum(&ld->dictState)
|
||||
));
|
||||
|
||||
if ( ld->dictState.getnext ) {
|
||||
/*
|
||||
* dictinary wants next word, so setup and store
|
||||
* current position and go to multiword mode
|
||||
if (ld->dictState.getnext)
|
||||
{
|
||||
/*
|
||||
* dictinary wants next word, so setup and store current
|
||||
* position and go to multiword mode
|
||||
*/
|
||||
|
||||
|
||||
ld->curDictId = DatumGetObjectId(map->dict_id[i]);
|
||||
ld->posDict = i+1;
|
||||
ld->posDict = i + 1;
|
||||
ld->curSub = curVal->next;
|
||||
if ( res )
|
||||
if (res)
|
||||
setNewTmpRes(ld, curVal, res);
|
||||
return LexizeExec(ld, correspondLexem);
|
||||
}
|
||||
|
||||
if (!res) /* dictionary doesn't know this lexeme */
|
||||
if (!res) /* dictionary doesn't know this lexeme */
|
||||
continue;
|
||||
|
||||
|
||||
RemoveHead(ld);
|
||||
setCorrLex(ld, correspondLexem);
|
||||
return res;
|
||||
}
|
||||
|
||||
RemoveHead(ld);
|
||||
}
|
||||
} else { /* curDictId is valid */
|
||||
}
|
||||
}
|
||||
else
|
||||
{ /* curDictId is valid */
|
||||
dict = finddict(ld->curDictId);
|
||||
|
||||
|
||||
/*
|
||||
* Dictionary ld->curDictId asks us about following words
|
||||
*/
|
||||
|
||||
while( ld->curSub ) {
|
||||
ParsedLex *curVal = ld->curSub;
|
||||
while (ld->curSub)
|
||||
{
|
||||
ParsedLex *curVal = ld->curSub;
|
||||
|
||||
map = ld->cfg->map + curVal->type;
|
||||
|
||||
if (curVal->type != 0) {
|
||||
bool dictExists = false;
|
||||
if (curVal->type != 0)
|
||||
{
|
||||
bool dictExists = false;
|
||||
|
||||
if (curVal->type >= ld->cfg->len || map->len == 0 ) {
|
||||
if (curVal->type >= ld->cfg->len || map->len == 0)
|
||||
{
|
||||
/* skip this type of lexeme */
|
||||
ld->curSub = curVal->next;
|
||||
continue;
|
||||
}
|
||||
|
||||
/*
|
||||
* We should be sure that current type of lexeme is recognized by
|
||||
* our dictinonary: we just check is it exist in
|
||||
* list of dictionaries ?
|
||||
* We should be sure that current type of lexeme is recognized
|
||||
* by our dictinonary: we just check is it exist in list of
|
||||
* dictionaries ?
|
||||
*/
|
||||
for(i=0;i < map->len && !dictExists; i++)
|
||||
if ( ld->curDictId == DatumGetObjectId(map->dict_id[i]) )
|
||||
for (i = 0; i < map->len && !dictExists; i++)
|
||||
if (ld->curDictId == DatumGetObjectId(map->dict_id[i]))
|
||||
dictExists = true;
|
||||
|
||||
if ( !dictExists ) {
|
||||
if (!dictExists)
|
||||
{
|
||||
/*
|
||||
* Dictionary can't work with current tpe of lexeme,
|
||||
* return to basic mode and redo all stored lexemes
|
||||
@ -205,38 +235,43 @@ LexizeExec(LexizeData *ld, ParsedLex **correspondLexem) {
|
||||
ld->curDictId = InvalidOid;
|
||||
return LexizeExec(ld, correspondLexem);
|
||||
}
|
||||
}
|
||||
|
||||
ld->dictState.isend = (curVal->type==0) ? true : false;
|
||||
}
|
||||
|
||||
ld->dictState.isend = (curVal->type == 0) ? true : false;
|
||||
ld->dictState.getnext = false;
|
||||
|
||||
res = (TSLexeme *) DatumGetPointer( FunctionCall4(
|
||||
&(dict->lexize_info),
|
||||
PointerGetDatum(dict->dictionary),
|
||||
PointerGetDatum(curVal->lemm),
|
||||
Int32GetDatum(curVal->lenlemm),
|
||||
PointerGetDatum(&ld->dictState)
|
||||
));
|
||||
res = (TSLexeme *) DatumGetPointer(FunctionCall4(
|
||||
&(dict->lexize_info),
|
||||
PointerGetDatum(dict->dictionary),
|
||||
PointerGetDatum(curVal->lemm),
|
||||
Int32GetDatum(curVal->lenlemm),
|
||||
PointerGetDatum(&ld->dictState)
|
||||
));
|
||||
|
||||
if ( ld->dictState.getnext ) {
|
||||
if (ld->dictState.getnext)
|
||||
{
|
||||
/* Dictionary wants one more */
|
||||
ld->curSub = curVal->next;
|
||||
if ( res )
|
||||
if (res)
|
||||
setNewTmpRes(ld, curVal, res);
|
||||
continue;
|
||||
}
|
||||
|
||||
if ( res || ld->tmpRes ) {
|
||||
if (res || ld->tmpRes)
|
||||
{
|
||||
/*
|
||||
* Dictionary normalizes lexemes,
|
||||
* so we remove from stack all used lexemes ,
|
||||
* return to basic mode and redo end of stack (if it exists)
|
||||
* Dictionary normalizes lexemes, so we remove from stack all
|
||||
* used lexemes , return to basic mode and redo end of stack
|
||||
* (if it exists)
|
||||
*/
|
||||
if ( res ) {
|
||||
moveToWaste( ld, ld->curSub );
|
||||
} else {
|
||||
if (res)
|
||||
{
|
||||
moveToWaste(ld, ld->curSub);
|
||||
}
|
||||
else
|
||||
{
|
||||
res = ld->tmpRes;
|
||||
moveToWaste( ld, ld->lastRes );
|
||||
moveToWaste(ld, ld->lastRes);
|
||||
}
|
||||
|
||||
/* reset to initial state */
|
||||
@ -248,14 +283,15 @@ LexizeExec(LexizeData *ld, ParsedLex **correspondLexem) {
|
||||
return res;
|
||||
}
|
||||
|
||||
/* Dict don't want next lexem and didn't recognize anything,
|
||||
redo from ld->towork.head */
|
||||
/*
|
||||
* Dict don't want next lexem and didn't recognize anything, redo
|
||||
* from ld->towork.head
|
||||
*/
|
||||
ld->curDictId = InvalidOid;
|
||||
return LexizeExec(ld, correspondLexem);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
setCorrLex(ld, correspondLexem);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
@ -70,54 +70,59 @@ char2wchar(wchar_t *to, const char *from, size_t len)
|
||||
|
||||
return mbstowcs(to, from, len);
|
||||
}
|
||||
|
||||
#endif /* WIN32 */
|
||||
#endif /* WIN32 */
|
||||
|
||||
int
|
||||
_t_isalpha( const char *ptr ) {
|
||||
wchar_t character;
|
||||
_t_isalpha(const char *ptr)
|
||||
{
|
||||
wchar_t character;
|
||||
|
||||
char2wchar(&character, ptr, 1);
|
||||
|
||||
return iswalpha( (wint_t)character );
|
||||
return iswalpha((wint_t) character);
|
||||
}
|
||||
|
||||
int
|
||||
_t_isprint( const char *ptr ) {
|
||||
wchar_t character;
|
||||
_t_isprint(const char *ptr)
|
||||
{
|
||||
wchar_t character;
|
||||
|
||||
char2wchar(&character, ptr, 1);
|
||||
|
||||
return iswprint( (wint_t)character );
|
||||
return iswprint((wint_t) character);
|
||||
}
|
||||
|
||||
#endif /* TS_USE_WIDE */
|
||||
#endif /* TS_USE_WIDE */
|
||||
|
||||
char *
|
||||
lowerstr(char *str)
|
||||
{
|
||||
char *ptr = str;
|
||||
char *ptr = str;
|
||||
|
||||
#ifdef TS_USE_WIDE
|
||||
|
||||
/*
|
||||
* Use wide char code only when max encoding length > 1 and ctype != C.
|
||||
* Some operating systems fail with multi-byte encodings and a C locale.
|
||||
* Also, for a C locale there is no need to process as multibyte. From
|
||||
* backend/utils/adt/oracle_compat.c Teodor
|
||||
*/
|
||||
if (pg_database_encoding_max_length() > 1 && !lc_ctype_is_c()) {
|
||||
wchar_t *wstr, *wptr;
|
||||
int len = strlen(str);
|
||||
if (pg_database_encoding_max_length() > 1 && !lc_ctype_is_c())
|
||||
{
|
||||
wchar_t *wstr,
|
||||
*wptr;
|
||||
int len = strlen(str);
|
||||
|
||||
wptr = wstr = (wchar_t *) palloc(sizeof(wchar_t) * (len+1));
|
||||
char2wchar(wstr, str, len+1);
|
||||
while (*wptr) {
|
||||
*wptr = towlower((wint_t) *wptr);
|
||||
wptr++;
|
||||
}
|
||||
wchar2char(str, wstr, len);
|
||||
pfree( wstr );
|
||||
} else
|
||||
wptr = wstr = (wchar_t *) palloc(sizeof(wchar_t) * (len + 1));
|
||||
char2wchar(wstr, str, len + 1);
|
||||
while (*wptr)
|
||||
{
|
||||
*wptr = towlower((wint_t) *wptr);
|
||||
wptr++;
|
||||
}
|
||||
wchar2char(str, wstr, len);
|
||||
pfree(wstr);
|
||||
}
|
||||
else
|
||||
#endif
|
||||
while (*ptr)
|
||||
{
|
||||
@ -126,4 +131,3 @@ lowerstr(char *str)
|
||||
}
|
||||
return str;
|
||||
}
|
||||
|
||||
|
@ -35,44 +35,44 @@
|
||||
|
||||
size_t wchar2char(char *to, const wchar_t *from, size_t len);
|
||||
size_t char2wchar(wchar_t *to, const char *from, size_t len);
|
||||
#else /* WIN32 */
|
||||
#else /* WIN32 */
|
||||
|
||||
/* correct mbstowcs */
|
||||
#define char2wchar mbstowcs
|
||||
#define wchar2char wcstombs
|
||||
#endif /* WIN32 */
|
||||
|
||||
#define t_isdigit(x) ( pg_mblen(x)==1 && isdigit( TOUCHAR(x) ) )
|
||||
#define t_isspace(x) ( pg_mblen(x)==1 && isspace( TOUCHAR(x) ) )
|
||||
extern int _t_isalpha( const char *ptr );
|
||||
#define t_isalpha(x) ( (pg_mblen(x)==1) ? isalpha( TOUCHAR(x) ) : _t_isalpha(x) )
|
||||
extern int _t_isprint( const char *ptr );
|
||||
#define t_isprint(x) ( (pg_mblen(x)==1) ? isprint( TOUCHAR(x) ) : _t_isprint(x) )
|
||||
#define t_isdigit(x) ( pg_mblen(x)==1 && isdigit( TOUCHAR(x) ) )
|
||||
#define t_isspace(x) ( pg_mblen(x)==1 && isspace( TOUCHAR(x) ) )
|
||||
extern int _t_isalpha(const char *ptr);
|
||||
|
||||
#define t_isalpha(x) ( (pg_mblen(x)==1) ? isalpha( TOUCHAR(x) ) : _t_isalpha(x) )
|
||||
extern int _t_isprint(const char *ptr);
|
||||
|
||||
#define t_isprint(x) ( (pg_mblen(x)==1) ? isprint( TOUCHAR(x) ) : _t_isprint(x) )
|
||||
/*
|
||||
* t_iseq() should be called only for ASCII symbols
|
||||
* t_iseq() should be called only for ASCII symbols
|
||||
*/
|
||||
#define t_iseq(x,c) ( (pg_mblen(x)==1) ? ( TOUCHAR(x) == ((unsigned char)(c)) ) : false )
|
||||
#define t_iseq(x,c) ( (pg_mblen(x)==1) ? ( TOUCHAR(x) == ((unsigned char)(c)) ) : false )
|
||||
|
||||
#define COPYCHAR(d,s) do { \
|
||||
int lll = pg_mblen( s ); \
|
||||
\
|
||||
while( lll-- ) \
|
||||
while( lll-- ) \
|
||||
TOUCHAR((d)+lll) = TOUCHAR((s)+lll); \
|
||||
} while(0)
|
||||
|
||||
|
||||
#else /* not def TS_USE_WIDE */
|
||||
#else /* not def TS_USE_WIDE */
|
||||
|
||||
#define t_isdigit(x) isdigit( TOUCHAR(x) )
|
||||
#define t_isspace(x) isspace( TOUCHAR(x) )
|
||||
#define t_isalpha(x) isalpha( TOUCHAR(x) )
|
||||
#define t_isprint(x) isprint( TOUCHAR(x) )
|
||||
#define t_iseq(x,c) ( TOUCHAR(x) == ((unsigned char)(c)) )
|
||||
|
||||
#define COPYCHAR(d,s) TOUCHAR(d) = TOUCHAR(s)
|
||||
#define t_isdigit(x) isdigit( TOUCHAR(x) )
|
||||
#define t_isspace(x) isspace( TOUCHAR(x) )
|
||||
#define t_isalpha(x) isalpha( TOUCHAR(x) )
|
||||
#define t_isprint(x) isprint( TOUCHAR(x) )
|
||||
#define t_iseq(x,c) ( TOUCHAR(x) == ((unsigned char)(c)) )
|
||||
|
||||
#define COPYCHAR(d,s) TOUCHAR(d) = TOUCHAR(s)
|
||||
#endif
|
||||
|
||||
char* lowerstr(char *str);
|
||||
char *lowerstr(char *str);
|
||||
|
||||
#endif /* __TSLOCALE_H__ */
|
||||
|
@ -477,7 +477,8 @@ ts_stat_sql(text *txt, text *ws)
|
||||
buf = VARDATA(ws);
|
||||
while (buf - VARDATA(ws) < VARSIZE(ws) - VARHDRSZ)
|
||||
{
|
||||
if ( pg_mblen(buf) == 1 ) {
|
||||
if (pg_mblen(buf) == 1)
|
||||
{
|
||||
switch (*buf)
|
||||
{
|
||||
case 'A':
|
||||
@ -500,7 +501,7 @@ ts_stat_sql(text *txt, text *ws)
|
||||
stat->weight |= 0;
|
||||
}
|
||||
}
|
||||
buf+=pg_mblen(buf);
|
||||
buf += pg_mblen(buf);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -165,13 +165,13 @@ uniqueentry(WordEntryIN * a, int4 l, char *buf, int4 *outbuflen)
|
||||
}
|
||||
|
||||
#define WAITWORD 1
|
||||
#define WAITENDWORD 2
|
||||
#define WAITENDWORD 2
|
||||
#define WAITNEXTCHAR 3
|
||||
#define WAITENDCMPLX 4
|
||||
#define WAITPOSINFO 5
|
||||
#define WAITPOSINFO 5
|
||||
#define INPOSINFO 6
|
||||
#define WAITPOSDELIM 7
|
||||
#define WAITCHARCMPLX 8
|
||||
#define WAITCHARCMPLX 8
|
||||
|
||||
#define RESIZEPRSBUF \
|
||||
do { \
|
||||
@ -200,9 +200,9 @@ gettoken_tsvector(TI_IN_STATE * state)
|
||||
{
|
||||
if (*(state->prsbuf) == '\0')
|
||||
return 0;
|
||||
else if ( t_iseq(state->prsbuf, '\'') )
|
||||
else if (t_iseq(state->prsbuf, '\''))
|
||||
state->state = WAITENDCMPLX;
|
||||
else if ( t_iseq(state->prsbuf, '\\') )
|
||||
else if (t_iseq(state->prsbuf, '\\'))
|
||||
{
|
||||
state->state = WAITNEXTCHAR;
|
||||
oldstate = WAITENDWORD;
|
||||
@ -214,7 +214,7 @@ gettoken_tsvector(TI_IN_STATE * state)
|
||||
else if (!t_isspace(state->prsbuf))
|
||||
{
|
||||
COPYCHAR(state->curpos, state->prsbuf);
|
||||
state->curpos+=pg_mblen(state->prsbuf);
|
||||
state->curpos += pg_mblen(state->prsbuf);
|
||||
state->state = WAITENDWORD;
|
||||
}
|
||||
}
|
||||
@ -228,18 +228,18 @@ gettoken_tsvector(TI_IN_STATE * state)
|
||||
{
|
||||
RESIZEPRSBUF;
|
||||
COPYCHAR(state->curpos, state->prsbuf);
|
||||
state->curpos+=pg_mblen(state->prsbuf);
|
||||
state->curpos += pg_mblen(state->prsbuf);
|
||||
state->state = oldstate;
|
||||
}
|
||||
}
|
||||
else if (state->state == WAITENDWORD)
|
||||
{
|
||||
if ( t_iseq(state->prsbuf, '\\') )
|
||||
if (t_iseq(state->prsbuf, '\\'))
|
||||
{
|
||||
state->state = WAITNEXTCHAR;
|
||||
oldstate = WAITENDWORD;
|
||||
}
|
||||
else if ( t_isspace(state->prsbuf) || *(state->prsbuf) == '\0' ||
|
||||
else if (t_isspace(state->prsbuf) || *(state->prsbuf) == '\0' ||
|
||||
(state->oprisdelim && ISOPERATOR(state->prsbuf)))
|
||||
{
|
||||
RESIZEPRSBUF;
|
||||
@ -250,7 +250,7 @@ gettoken_tsvector(TI_IN_STATE * state)
|
||||
*(state->curpos) = '\0';
|
||||
return 1;
|
||||
}
|
||||
else if ( t_iseq(state->prsbuf,':') )
|
||||
else if (t_iseq(state->prsbuf, ':'))
|
||||
{
|
||||
if (state->curpos == state->word)
|
||||
ereport(ERROR,
|
||||
@ -266,15 +266,16 @@ gettoken_tsvector(TI_IN_STATE * state)
|
||||
{
|
||||
RESIZEPRSBUF;
|
||||
COPYCHAR(state->curpos, state->prsbuf);
|
||||
state->curpos+=pg_mblen(state->prsbuf);
|
||||
state->curpos += pg_mblen(state->prsbuf);
|
||||
}
|
||||
}
|
||||
else if (state->state == WAITENDCMPLX)
|
||||
{
|
||||
if ( t_iseq(state->prsbuf, '\'') ) {
|
||||
state->state = WAITCHARCMPLX;
|
||||
if (t_iseq(state->prsbuf, '\''))
|
||||
{
|
||||
state->state = WAITCHARCMPLX;
|
||||
}
|
||||
else if ( t_iseq(state->prsbuf, '\\') )
|
||||
else if (t_iseq(state->prsbuf, '\\'))
|
||||
{
|
||||
state->state = WAITNEXTCHAR;
|
||||
oldstate = WAITENDCMPLX;
|
||||
@ -287,18 +288,20 @@ gettoken_tsvector(TI_IN_STATE * state)
|
||||
{
|
||||
RESIZEPRSBUF;
|
||||
COPYCHAR(state->curpos, state->prsbuf);
|
||||
state->curpos+=pg_mblen(state->prsbuf);
|
||||
state->curpos += pg_mblen(state->prsbuf);
|
||||
}
|
||||
}
|
||||
else if (state->state == WAITCHARCMPLX)
|
||||
{
|
||||
if ( t_iseq(state->prsbuf, '\'') )
|
||||
if (t_iseq(state->prsbuf, '\''))
|
||||
{
|
||||
RESIZEPRSBUF;
|
||||
COPYCHAR(state->curpos, state->prsbuf);
|
||||
state->curpos+=pg_mblen(state->prsbuf);
|
||||
state->curpos += pg_mblen(state->prsbuf);
|
||||
state->state = WAITENDCMPLX;
|
||||
} else {
|
||||
}
|
||||
else
|
||||
{
|
||||
RESIZEPRSBUF;
|
||||
*(state->curpos) = '\0';
|
||||
if (state->curpos == state->word)
|
||||
@ -312,12 +315,12 @@ gettoken_tsvector(TI_IN_STATE * state)
|
||||
}
|
||||
else
|
||||
state->state = WAITPOSINFO;
|
||||
continue; /* recheck current character */
|
||||
continue; /* recheck current character */
|
||||
}
|
||||
}
|
||||
else if (state->state == WAITPOSINFO)
|
||||
{
|
||||
if ( t_iseq(state->prsbuf, ':') )
|
||||
if (t_iseq(state->prsbuf, ':'))
|
||||
state->state = INPOSINFO;
|
||||
else
|
||||
return 1;
|
||||
@ -353,9 +356,9 @@ gettoken_tsvector(TI_IN_STATE * state)
|
||||
}
|
||||
else if (state->state == WAITPOSDELIM)
|
||||
{
|
||||
if ( t_iseq(state->prsbuf, ',') )
|
||||
if (t_iseq(state->prsbuf, ','))
|
||||
state->state = INPOSINFO;
|
||||
else if ( t_iseq(state->prsbuf, 'a') || t_iseq(state->prsbuf, 'A') || t_iseq(state->prsbuf, '*') )
|
||||
else if (t_iseq(state->prsbuf, 'a') || t_iseq(state->prsbuf, 'A') || t_iseq(state->prsbuf, '*'))
|
||||
{
|
||||
if (WEP_GETWEIGHT(state->pos[*(uint16 *) (state->pos)]))
|
||||
ereport(ERROR,
|
||||
@ -363,7 +366,7 @@ gettoken_tsvector(TI_IN_STATE * state)
|
||||
errmsg("syntax error")));
|
||||
WEP_SETWEIGHT(state->pos[*(uint16 *) (state->pos)], 3);
|
||||
}
|
||||
else if ( t_iseq(state->prsbuf, 'b') || t_iseq(state->prsbuf, 'B') )
|
||||
else if (t_iseq(state->prsbuf, 'b') || t_iseq(state->prsbuf, 'B'))
|
||||
{
|
||||
if (WEP_GETWEIGHT(state->pos[*(uint16 *) (state->pos)]))
|
||||
ereport(ERROR,
|
||||
@ -371,7 +374,7 @@ gettoken_tsvector(TI_IN_STATE * state)
|
||||
errmsg("syntax error")));
|
||||
WEP_SETWEIGHT(state->pos[*(uint16 *) (state->pos)], 2);
|
||||
}
|
||||
else if ( t_iseq(state->prsbuf, 'c') || t_iseq(state->prsbuf, 'C') )
|
||||
else if (t_iseq(state->prsbuf, 'c') || t_iseq(state->prsbuf, 'C'))
|
||||
{
|
||||
if (WEP_GETWEIGHT(state->pos[*(uint16 *) (state->pos)]))
|
||||
ereport(ERROR,
|
||||
@ -379,7 +382,7 @@ gettoken_tsvector(TI_IN_STATE * state)
|
||||
errmsg("syntax error")));
|
||||
WEP_SETWEIGHT(state->pos[*(uint16 *) (state->pos)], 1);
|
||||
}
|
||||
else if ( t_iseq(state->prsbuf, 'd') || t_iseq(state->prsbuf, 'D') )
|
||||
else if (t_iseq(state->prsbuf, 'd') || t_iseq(state->prsbuf, 'D'))
|
||||
{
|
||||
if (WEP_GETWEIGHT(state->pos[*(uint16 *) (state->pos)]))
|
||||
ereport(ERROR,
|
||||
@ -400,7 +403,7 @@ gettoken_tsvector(TI_IN_STATE * state)
|
||||
elog(ERROR, "internal error");
|
||||
|
||||
/* get next char */
|
||||
state->prsbuf+=pg_mblen(state->prsbuf);
|
||||
state->prsbuf += pg_mblen(state->prsbuf);
|
||||
}
|
||||
|
||||
return 0;
|
||||
@ -423,7 +426,7 @@ tsvector_in(PG_FUNCTION_ARGS)
|
||||
|
||||
SET_FUNCOID();
|
||||
|
||||
pg_verifymbstr( buf, strlen(buf), false );
|
||||
pg_verifymbstr(buf, strlen(buf), false);
|
||||
state.prsbuf = buf;
|
||||
state.len = 32;
|
||||
state.word = (char *) palloc(state.len);
|
||||
@ -517,13 +520,14 @@ tsvector_out(PG_FUNCTION_ARGS)
|
||||
lenbuf = 0,
|
||||
pp;
|
||||
WordEntry *ptr = ARRPTR(out);
|
||||
char *curbegin, *curin,
|
||||
char *curbegin,
|
||||
*curin,
|
||||
*curout;
|
||||
|
||||
lenbuf = out->size * 2 /* '' */ + out->size - 1 /* space */ + 2 /* \0 */ ;
|
||||
for (i = 0; i < out->size; i++)
|
||||
{
|
||||
lenbuf += ptr[i].len * 2 * pg_database_encoding_max_length()/* for escape */ ;
|
||||
lenbuf += ptr[i].len * 2 * pg_database_encoding_max_length() /* for escape */ ;
|
||||
if (ptr[i].haspos)
|
||||
lenbuf += 7 * POSDATALEN(out, &(ptr[i]));
|
||||
}
|
||||
@ -535,10 +539,11 @@ tsvector_out(PG_FUNCTION_ARGS)
|
||||
if (i != 0)
|
||||
*curout++ = ' ';
|
||||
*curout++ = '\'';
|
||||
while ( curin-curbegin < ptr->len )
|
||||
while (curin - curbegin < ptr->len)
|
||||
{
|
||||
int len = pg_mblen(curin);
|
||||
if ( t_iseq(curin, '\'') )
|
||||
int len = pg_mblen(curin);
|
||||
|
||||
if (t_iseq(curin, '\''))
|
||||
{
|
||||
int4 pos = curout - outbuf;
|
||||
|
||||
@ -546,7 +551,7 @@ tsvector_out(PG_FUNCTION_ARGS)
|
||||
curout = outbuf + pos;
|
||||
*curout++ = '\'';
|
||||
}
|
||||
while(len--)
|
||||
while (len--)
|
||||
*curout++ = *curin++;
|
||||
}
|
||||
*curout++ = '\'';
|
||||
@ -983,36 +988,49 @@ silly_cmp_tsvector(const tsvector * a, const tsvector * b)
|
||||
{
|
||||
WordEntry *aptr = ARRPTR(a);
|
||||
WordEntry *bptr = ARRPTR(b);
|
||||
int i = 0;
|
||||
int res;
|
||||
int i = 0;
|
||||
int res;
|
||||
|
||||
|
||||
for(i=0;i<a->size;i++) {
|
||||
if ( aptr->haspos != bptr->haspos ) {
|
||||
return ( aptr->haspos > bptr->haspos ) ? -1 : 1;
|
||||
} else if ( aptr->len != bptr->len ) {
|
||||
return ( aptr->len > bptr->len ) ? -1 : 1;
|
||||
} else if ( (res=strncmp(STRPTR(a) + aptr->pos, STRPTR(b) + bptr->pos, bptr->len))!= 0 ) {
|
||||
for (i = 0; i < a->size; i++)
|
||||
{
|
||||
if (aptr->haspos != bptr->haspos)
|
||||
{
|
||||
return (aptr->haspos > bptr->haspos) ? -1 : 1;
|
||||
}
|
||||
else if (aptr->len != bptr->len)
|
||||
{
|
||||
return (aptr->len > bptr->len) ? -1 : 1;
|
||||
}
|
||||
else if ((res = strncmp(STRPTR(a) + aptr->pos, STRPTR(b) + bptr->pos, bptr->len)) != 0)
|
||||
{
|
||||
return res;
|
||||
} else if ( aptr->haspos ) {
|
||||
WordEntryPos *ap = POSDATAPTR(a, aptr);
|
||||
WordEntryPos *bp = POSDATAPTR(b, bptr);
|
||||
int j;
|
||||
}
|
||||
else if (aptr->haspos)
|
||||
{
|
||||
WordEntryPos *ap = POSDATAPTR(a, aptr);
|
||||
WordEntryPos *bp = POSDATAPTR(b, bptr);
|
||||
int j;
|
||||
|
||||
if ( POSDATALEN(a, aptr) != POSDATALEN(b, bptr) )
|
||||
return ( POSDATALEN(a, aptr) > POSDATALEN(b, bptr) ) ? -1 : 1;
|
||||
if (POSDATALEN(a, aptr) != POSDATALEN(b, bptr))
|
||||
return (POSDATALEN(a, aptr) > POSDATALEN(b, bptr)) ? -1 : 1;
|
||||
|
||||
for(j=0;j<POSDATALEN(a, aptr);j++) {
|
||||
if ( WEP_GETPOS(*ap) != WEP_GETPOS(*bp) ) {
|
||||
return ( WEP_GETPOS(*ap) > WEP_GETPOS(*bp) ) ? -1 : 1;
|
||||
} else if ( WEP_GETWEIGHT(*ap) != WEP_GETWEIGHT(*bp) ) {
|
||||
return ( WEP_GETWEIGHT(*ap) > WEP_GETWEIGHT(*bp) ) ? -1 : 1;
|
||||
for (j = 0; j < POSDATALEN(a, aptr); j++)
|
||||
{
|
||||
if (WEP_GETPOS(*ap) != WEP_GETPOS(*bp))
|
||||
{
|
||||
return (WEP_GETPOS(*ap) > WEP_GETPOS(*bp)) ? -1 : 1;
|
||||
}
|
||||
else if (WEP_GETWEIGHT(*ap) != WEP_GETWEIGHT(*bp))
|
||||
{
|
||||
return (WEP_GETWEIGHT(*ap) > WEP_GETWEIGHT(*bp)) ? -1 : 1;
|
||||
}
|
||||
ap++, bp++;
|
||||
}
|
||||
}
|
||||
|
||||
aptr++; bptr++;
|
||||
aptr++;
|
||||
bptr++;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -49,17 +49,17 @@ typedef uint16 WordEntryPos;
|
||||
|
||||
/*
|
||||
* Structure of tsvector datatype:
|
||||
* 1) int4 len - varlena's length
|
||||
* 1) int4 len - varlena's length
|
||||
* 2) int4 size - number of lexemes or WordEntry array, which is the same
|
||||
* 3) Array of WordEntry - sorted array, comparison based on word's length
|
||||
* and strncmp(). WordEntry->pos points number of
|
||||
* bytes from end of WordEntry array to start of
|
||||
* corresponding lexeme.
|
||||
* 4) Lexeme's storage:
|
||||
* SHORTALIGNED(lexeme) and position information if it exists
|
||||
* Position information: first int2 - is a number of positions and it
|
||||
* follows array of WordEntryPos
|
||||
*/
|
||||
* SHORTALIGNED(lexeme) and position information if it exists
|
||||
* Position information: first int2 - is a number of positions and it
|
||||
* follows array of WordEntryPos
|
||||
*/
|
||||
|
||||
typedef struct
|
||||
{
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $PostgreSQL: pgsql/contrib/tsearch2/wordparser/parser.c,v 1.10 2006/03/11 04:38:30 momjian Exp $ */
|
||||
/* $PostgreSQL: pgsql/contrib/tsearch2/wordparser/parser.c,v 1.11 2006/10/04 00:29:47 momjian Exp $ */
|
||||
|
||||
#include "postgres.h"
|
||||
|
||||
@ -458,7 +458,7 @@ static TParserStateActionItem actionTPS_InVerVersion[] = {
|
||||
|
||||
static TParserStateActionItem actionTPS_InSVerVersion[] = {
|
||||
{p_isEOF, 0, A_POP, TPS_Null, 0, NULL},
|
||||
{p_isdigit, 0, A_BINGO|A_CLRALL, TPS_InUnsignedInt, SPACE, NULL},
|
||||
{p_isdigit, 0, A_BINGO | A_CLRALL, TPS_InUnsignedInt, SPACE, NULL},
|
||||
{NULL, 0, A_NEXT, TPS_Null, 0, NULL}
|
||||
};
|
||||
|
||||
@ -613,7 +613,7 @@ static TParserStateActionItem actionTPS_InTagEnd[] = {
|
||||
static TParserStateActionItem actionTPS_InCommentFirst[] = {
|
||||
{p_isEOF, 0, A_POP, TPS_Null, 0, NULL},
|
||||
{p_iseqC, '-', A_NEXT, TPS_InCommentLast, 0, NULL},
|
||||
/* <!DOCTYPE ...>*/
|
||||
/* <!DOCTYPE ...> */
|
||||
{p_iseqC, 'D', A_NEXT, TPS_InTag, 0, NULL},
|
||||
{p_iseqC, 'd', A_NEXT, TPS_InTag, 0, NULL},
|
||||
{NULL, 0, A_POP, TPS_Null, 0, NULL}
|
||||
@ -753,10 +753,10 @@ static TParserStateActionItem actionTPS_InPathFirstFirst[] = {
|
||||
};
|
||||
|
||||
static TParserStateActionItem actionTPS_InPathSecond[] = {
|
||||
{p_isEOF, 0, A_BINGO|A_CLEAR, TPS_Base, FILEPATH, NULL},
|
||||
{p_iseqC, '/', A_NEXT|A_PUSH, TPS_InFileFirst, 0, NULL},
|
||||
{p_iseqC, '/', A_BINGO|A_CLEAR, TPS_Base, FILEPATH, NULL},
|
||||
{p_isspace, 0, A_BINGO|A_CLEAR, TPS_Base, FILEPATH, NULL},
|
||||
{p_isEOF, 0, A_BINGO | A_CLEAR, TPS_Base, FILEPATH, NULL},
|
||||
{p_iseqC, '/', A_NEXT | A_PUSH, TPS_InFileFirst, 0, NULL},
|
||||
{p_iseqC, '/', A_BINGO | A_CLEAR, TPS_Base, FILEPATH, NULL},
|
||||
{p_isspace, 0, A_BINGO | A_CLEAR, TPS_Base, FILEPATH, NULL},
|
||||
{NULL, 0, A_POP, TPS_Null, 0, NULL}
|
||||
};
|
||||
|
||||
|
@ -347,8 +347,8 @@ typedef struct
|
||||
|
||||
typedef struct
|
||||
{
|
||||
int cur;
|
||||
int len;
|
||||
int cur;
|
||||
int len;
|
||||
LexemeEntry *list;
|
||||
} PrsStorage;
|
||||
|
||||
|
@ -671,7 +671,7 @@ xpath_table(PG_FUNCTION_ARGS)
|
||||
* document */
|
||||
int had_values; /* To determine end of nodeset results */
|
||||
|
||||
StringInfoData query_buf;
|
||||
StringInfoData query_buf;
|
||||
|
||||
/* We only have a valid tuple description in table function mode */
|
||||
if (rsinfo == NULL || !IsA(rsinfo, ReturnSetInfo))
|
||||
|
Reference in New Issue
Block a user