#include "postgres.h"#include "miscadmin.h"#include "utils/builtins.h"#include "_int.h"
Go to the source code of this file.
Data Structures | |
| struct | NODE |
| struct | WORKSTATE |
| struct | CHKVAL |
| struct | GinChkVal |
| struct | INFIX |
Defines | |
| #define | WAITOPERAND 1 |
| #define | WAITENDOPERAND 2 |
| #define | WAITOPERATOR 3 |
| #define | STACKDEPTH 16 |
| #define | RESIZEBUF(inf, addsize) |
Typedefs | |
| typedef struct NODE | NODE |
Functions | |
| PG_FUNCTION_INFO_V1 (bqarr_in) | |
| PG_FUNCTION_INFO_V1 (bqarr_out) | |
| Datum | bqarr_in (PG_FUNCTION_ARGS) |
| Datum | bqarr_out (PG_FUNCTION_ARGS) |
| PG_FUNCTION_INFO_V1 (boolop) | |
| Datum | boolop (PG_FUNCTION_ARGS) |
| PG_FUNCTION_INFO_V1 (rboolop) | |
| Datum | rboolop (PG_FUNCTION_ARGS) |
| PG_FUNCTION_INFO_V1 (querytree) | |
| Datum | querytree (PG_FUNCTION_ARGS) |
| static int32 | gettoken (WORKSTATE *state, int32 *val) |
| static void | pushquery (WORKSTATE *state, int32 type, int32 val) |
| static int32 | makepol (WORKSTATE *state) |
| static bool | checkcondition_arr (void *checkval, ITEM *item) |
| static bool | checkcondition_bit (void *checkval, ITEM *item) |
| static bool | execute (ITEM *curitem, void *checkval, bool calcnot, bool(*chkcond)(void *checkval, ITEM *item)) |
| bool | signconsistent (QUERYTYPE *query, BITVEC sign, bool calcnot) |
| bool | execconsistent (QUERYTYPE *query, ArrayType *array, bool calcnot) |
| static bool | checkcondition_gin (void *checkval, ITEM *item) |
| bool | gin_bool_consistent (QUERYTYPE *query, bool *check) |
| static bool | contains_required_value (ITEM *curitem) |
| bool | query_has_required_values (QUERYTYPE *query) |
| static void | findoprnd (ITEM *ptr, int32 *pos) |
| static void | infix (INFIX *in, bool first) |
| #define RESIZEBUF | ( | inf, | ||
| addsize | ||||
| ) |
| #define STACKDEPTH 16 |
Definition at line 156 of file _int_bool.c.
Referenced by makepol().
| #define WAITENDOPERAND 2 |
Definition at line 28 of file _int_bool.c.
Referenced by gettoken().
| #define WAITOPERAND 1 |
Definition at line 27 of file _int_bool.c.
Referenced by gettoken().
| #define WAITOPERATOR 3 |
Definition at line 29 of file _int_bool.c.
Referenced by gettoken().
| Datum boolop | ( | PG_FUNCTION_ARGS | ) |
Definition at line 428 of file _int_bool.c.
References CHKVAL::arrb, CHKVAL::arre, ARRNELEMS, ARRPTR, CHECKARRVALID, checkcondition_arr(), execute(), GETQUERY, pfree(), PG_FREE_IF_COPY, PG_GETARG_ARRAYTYPE_P_COPY, PG_GETARG_QUERYTYPE_P, PG_RETURN_BOOL, PREPAREARR, QUERYTYPE::size, and val.
Referenced by _copyBoolExpr(), _equalBoolExpr(), and_clause(), not_clause(), or_clause(), and rboolop().
{
ArrayType *val = PG_GETARG_ARRAYTYPE_P_COPY(0);
QUERYTYPE *query = PG_GETARG_QUERYTYPE_P(1);
CHKVAL chkval;
bool result;
CHECKARRVALID(val);
PREPAREARR(val);
chkval.arrb = ARRPTR(val);
chkval.arre = chkval.arrb + ARRNELEMS(val);
result = execute(GETQUERY(query) + query->size - 1,
&chkval, true,
checkcondition_arr);
pfree(val);
PG_FREE_IF_COPY(query, 1);
PG_RETURN_BOOL(result);
}
| Datum bqarr_in | ( | PG_FUNCTION_ARGS | ) |
Definition at line 483 of file _int_bool.c.
References appendStringInfo(), WORKSTATE::buf, buf, COMPUTESIZE, WORKSTATE::count, StringInfoData::data, DEBUG3, elog, ereport, errcode(), errmsg(), ERROR, findoprnd(), GETQUERY, i, initStringInfo(), NODE::left, makepol(), NODE::next, WORKSTATE::num, OPR, palloc(), pfree(), PG_GETARG_POINTER, PG_RETURN_POINTER, SET_VARSIZE, QUERYTYPE::size, WORKSTATE::state, WORKSTATE::str, NODE::type, ITEM::type, val, NODE::val, and ITEM::val.
{
char *buf = (char *) PG_GETARG_POINTER(0);
WORKSTATE state;
int32 i;
QUERYTYPE *query;
int32 commonlen;
ITEM *ptr;
NODE *tmp;
int32 pos = 0;
#ifdef BS_DEBUG
StringInfoData pbuf;
#endif
state.buf = buf;
state.state = WAITOPERAND;
state.count = 0;
state.num = 0;
state.str = NULL;
/* make polish notation (postfix, but in reverse order) */
makepol(&state);
if (!state.num)
ereport(ERROR,
(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
errmsg("empty query")));
commonlen = COMPUTESIZE(state.num);
query = (QUERYTYPE *) palloc(commonlen);
SET_VARSIZE(query, commonlen);
query->size = state.num;
ptr = GETQUERY(query);
for (i = state.num - 1; i >= 0; i--)
{
ptr[i].type = state.str->type;
ptr[i].val = state.str->val;
tmp = state.str->next;
pfree(state.str);
state.str = tmp;
}
pos = query->size - 1;
findoprnd(ptr, &pos);
#ifdef BS_DEBUG
initStringInfo(&pbuf);
for (i = 0; i < query->size; i++)
{
if (ptr[i].type == OPR)
appendStringInfo(&pbuf, "%c(%d) ", ptr[i].val, ptr[i].left);
else
appendStringInfo(&pbuf, "%d ", ptr[i].val);
}
elog(DEBUG3, "POR: %s", pbuf.data);
pfree(pbuf.data);
#endif
PG_RETURN_POINTER(query);
}
| Datum bqarr_out | ( | PG_FUNCTION_ARGS | ) |
Definition at line 638 of file _int_bool.c.
References INFIX::buf, INFIX::buflen, INFIX::cur, INFIX::curpol, ereport, errcode(), errmsg(), ERROR, GETQUERY, infix(), palloc(), PG_FREE_IF_COPY, PG_GETARG_QUERYTYPE_P, PG_RETURN_POINTER, and QUERYTYPE::size.
{
QUERYTYPE *query = PG_GETARG_QUERYTYPE_P(0);
INFIX nrm;
if (query->size == 0)
ereport(ERROR,
(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
errmsg("empty query")));
nrm.curpol = GETQUERY(query) + query->size - 1;
nrm.buflen = 32;
nrm.cur = nrm.buf = (char *) palloc(sizeof(char) * nrm.buflen);
*(nrm.cur) = '\0';
infix(&nrm, true);
PG_FREE_IF_COPY(query, 0);
PG_RETURN_POINTER(nrm.buf);
}
Definition at line 244 of file _int_bool.c.
References val, and ITEM::val.
Referenced by boolop(), and execconsistent().
{
int32 *StopLow = ((CHKVAL *) checkval)->arrb;
int32 *StopHigh = ((CHKVAL *) checkval)->arre;
int32 *StopMiddle;
/* Loop invariant: StopLow <= val < StopHigh */
while (StopLow < StopHigh)
{
StopMiddle = StopLow + (StopHigh - StopLow) / 2;
if (*StopMiddle == item->val)
return (true);
else if (*StopMiddle < item->val)
StopLow = StopMiddle + 1;
else
StopHigh = StopMiddle;
}
return false;
}
Definition at line 266 of file _int_bool.c.
References GETBIT, HASHVAL, and ITEM::val.
Referenced by signconsistent().
Definition at line 337 of file _int_bool.c.
References GinChkVal::first, and GinChkVal::mapped_check.
Referenced by gin_bool_consistent().
{
GinChkVal *gcv = (GinChkVal *) checkval;
return gcv->mapped_check[item - gcv->first];
}
Definition at line 373 of file _int_bool.c.
References check_stack_depth(), ITEM::left, ITEM::type, ITEM::val, and VAL.
Referenced by query_has_required_values().
{
/* since this function recurses, it could be driven to stack overflow */
check_stack_depth();
if (curitem->type == VAL)
return true;
else if (curitem->val == (int32) '!')
{
/*
* Assume anything under a NOT is non-required. For some cases with
* nested NOTs, we could prove there's a required value, but it seems
* unlikely to be worth the trouble.
*/
return false;
}
else if (curitem->val == (int32) '&')
{
/* If either side has a required value, we're good */
if (contains_required_value(curitem + curitem->left))
return true;
else
return contains_required_value(curitem - 1);
}
else
{ /* |-operator */
/* Both sides must have required values */
if (contains_required_value(curitem + curitem->left))
return contains_required_value(curitem - 1);
else
return false;
}
}
Definition at line 318 of file _int_bool.c.
References CHKVAL::arrb, CHKVAL::arre, ARRNELEMS, ARRPTR, CHECKARRVALID, checkcondition_arr(), execute(), GETQUERY, and QUERYTYPE::size.
Referenced by g_int_consistent().
| static bool execute | ( | ITEM * | curitem, | |
| void * | checkval, | |||
| bool | calcnot, | |||
| bool(*)(void *checkval, ITEM *item) | chkcond | |||
| ) | [static] |
Definition at line 275 of file _int_bool.c.
References check_stack_depth(), ITEM::left, ITEM::type, ITEM::val, and VAL.
Referenced by boolop(), execconsistent(), gin_bool_consistent(), and signconsistent().
{
/* since this function recurses, it could be driven to stack overflow */
check_stack_depth();
if (curitem->type == VAL)
return (*chkcond) (checkval, curitem);
else if (curitem->val == (int32) '!')
{
return (calcnot) ?
((execute(curitem - 1, checkval, calcnot, chkcond)) ? false : true)
: true;
}
else if (curitem->val == (int32) '&')
{
if (execute(curitem + curitem->left, checkval, calcnot, chkcond))
return execute(curitem - 1, checkval, calcnot, chkcond);
else
return false;
}
else
{ /* |-operator */
if (execute(curitem + curitem->left, checkval, calcnot, chkcond))
return true;
else
return execute(curitem - 1, checkval, calcnot, chkcond);
}
}
Definition at line 449 of file _int_bool.c.
References DEBUG3, elog, ITEM::left, OPR, NODE::type, VAL, and val.
Referenced by bqarr_in().
{
#ifdef BS_DEBUG
elog(DEBUG3, (ptr[*pos].type == OPR) ?
"%d %c" : "%d %d", *pos, ptr[*pos].val);
#endif
if (ptr[*pos].type == VAL)
{
ptr[*pos].left = 0;
(*pos)--;
}
else if (ptr[*pos].val == (int32) '!')
{
ptr[*pos].left = -1;
(*pos)--;
findoprnd(ptr, pos);
}
else
{
ITEM *curitem = &ptr[*pos];
int32 tmp = *pos;
(*pos)--;
findoprnd(ptr, pos);
curitem->left = *pos - tmp;
findoprnd(ptr, pos);
}
}
Definition at line 57 of file _int_bool.c.
References WORKSTATE::buf, WORKSTATE::count, ERR, NULL, WORKSTATE::state, VAL, WAITENDOPERAND, WAITOPERAND, and WAITOPERATOR.
Referenced by makepol().
{
char nnn[16];
int innn;
*val = 0; /* default result */
innn = 0;
while (1)
{
if (innn >= sizeof(nnn))
return ERR; /* buffer overrun => syntax error */
switch (state->state)
{
case WAITOPERAND:
innn = 0;
if ((*(state->buf) >= '0' && *(state->buf) <= '9') ||
*(state->buf) == '-')
{
state->state = WAITENDOPERAND;
nnn[innn++] = *(state->buf);
}
else if (*(state->buf) == '!')
{
(state->buf)++;
*val = (int32) '!';
return OPR;
}
else if (*(state->buf) == '(')
{
state->count++;
(state->buf)++;
return OPEN;
}
else if (*(state->buf) != ' ')
return ERR;
break;
case WAITENDOPERAND:
if (*(state->buf) >= '0' && *(state->buf) <= '9')
{
nnn[innn++] = *(state->buf);
}
else
{
long lval;
nnn[innn] = '\0';
errno = 0;
lval = strtol(nnn, NULL, 0);
*val = (int32) lval;
if (errno != 0 || (long) *val != lval)
return ERR;
state->state = WAITOPERATOR;
return (state->count && *(state->buf) == '\0')
? ERR : VAL;
}
break;
case WAITOPERATOR:
if (*(state->buf) == '&' || *(state->buf) == '|')
{
state->state = WAITOPERAND;
*val = (int32) *(state->buf);
(state->buf)++;
return OPR;
}
else if (*(state->buf) == ')')
{
(state->buf)++;
state->count--;
return (state->count < 0) ? ERR : CLOSE;
}
else if (*(state->buf) == '\0')
return (state->count) ? ERR : END;
else if (*(state->buf) != ' ')
return ERR;
break;
default:
return ERR;
break;
}
(state->buf)++;
}
}
Definition at line 345 of file _int_bool.c.
References checkcondition_gin(), execute(), GinChkVal::first, GETQUERY, i, GinChkVal::mapped_check, palloc(), QUERYTYPE::size, NODE::type, and VAL.
Referenced by ginint4_consistent().
{
GinChkVal gcv;
ITEM *items = GETQUERY(query);
int i,
j = 0;
if (query->size <= 0)
return FALSE;
/*
* Set up data for checkcondition_gin. This must agree with the query
* extraction code in ginint4_queryextract.
*/
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++];
}
return execute(GETQUERY(query) + query->size - 1,
(void *) &gcv, true,
checkcondition_gin);
}
Definition at line 564 of file _int_bool.c.
References INFIX::buf, INFIX::buflen, INFIX::cur, INFIX::curpol, OPR, palloc(), pfree(), RESIZEBUF, ITEM::type, ITEM::val, and VAL.
Referenced by bqarr_out().
{
if (in->curpol->type == VAL)
{
RESIZEBUF(in, 11);
sprintf(in->cur, "%d", in->curpol->val);
in->cur = strchr(in->cur, '\0');
in->curpol--;
}
else if (in->curpol->val == (int32) '!')
{
bool isopr = false;
RESIZEBUF(in, 1);
*(in->cur) = '!';
in->cur++;
*(in->cur) = '\0';
in->curpol--;
if (in->curpol->type == OPR)
{
isopr = true;
RESIZEBUF(in, 2);
sprintf(in->cur, "( ");
in->cur = strchr(in->cur, '\0');
}
infix(in, isopr);
if (isopr)
{
RESIZEBUF(in, 2);
sprintf(in->cur, " )");
in->cur = strchr(in->cur, '\0');
}
}
else
{
int32 op = in->curpol->val;
INFIX nrm;
in->curpol--;
if (op == (int32) '|' && !first)
{
RESIZEBUF(in, 2);
sprintf(in->cur, "( ");
in->cur = strchr(in->cur, '\0');
}
nrm.curpol = in->curpol;
nrm.buflen = 16;
nrm.cur = nrm.buf = (char *) palloc(sizeof(char) * nrm.buflen);
/* get right operand */
infix(&nrm, false);
/* get & print left operand */
in->curpol = nrm.curpol;
infix(in, false);
/* print operator & right operand */
RESIZEBUF(in, 3 + (nrm.cur - nrm.buf));
sprintf(in->cur, " %c %s", op, nrm.buf);
in->cur = strchr(in->cur, '\0');
pfree(nrm.buf);
if (op == (int32) '|' && !first)
{
RESIZEBUF(in, 2);
sprintf(in->cur, " )");
in->cur = strchr(in->cur, '\0');
}
}
}
Definition at line 162 of file _int_bool.c.
References check_stack_depth(), CLOSE, END, ereport, ERR, errcode(), errmsg(), ERROR, gettoken(), OPEN, OPR, pushquery(), STACKDEPTH, NODE::type, VAL, and val.
Referenced by bqarr_in().
{
int32 val,
type;
int32 stack[STACKDEPTH];
int32 lenstack = 0;
/* since this function recurses, it could be driven to stack overflow */
check_stack_depth();
while ((type = gettoken(state, &val)) != END)
{
switch (type)
{
case VAL:
pushquery(state, type, val);
while (lenstack && (stack[lenstack - 1] == (int32) '&' ||
stack[lenstack - 1] == (int32) '!'))
{
lenstack--;
pushquery(state, OPR, stack[lenstack]);
}
break;
case OPR:
if (lenstack && val == (int32) '|')
pushquery(state, OPR, val);
else
{
if (lenstack == STACKDEPTH)
ereport(ERROR,
(errcode(ERRCODE_STATEMENT_TOO_COMPLEX),
errmsg("statement too complex")));
stack[lenstack] = val;
lenstack++;
}
break;
case OPEN:
if (makepol(state) == ERR)
return ERR;
while (lenstack && (stack[lenstack - 1] == (int32) '&' ||
stack[lenstack - 1] == (int32) '!'))
{
lenstack--;
pushquery(state, OPR, stack[lenstack]);
}
break;
case CLOSE:
while (lenstack)
{
lenstack--;
pushquery(state, OPR, stack[lenstack]);
};
return END;
break;
case ERR:
default:
ereport(ERROR,
(errcode(ERRCODE_SYNTAX_ERROR),
errmsg("syntax error")));
return ERR;
}
}
while (lenstack)
{
lenstack--;
pushquery(state, OPR, stack[lenstack]);
};
return END;
}
| PG_FUNCTION_INFO_V1 | ( | querytree | ) |
| PG_FUNCTION_INFO_V1 | ( | bqarr_out | ) |
| PG_FUNCTION_INFO_V1 | ( | boolop | ) |
| PG_FUNCTION_INFO_V1 | ( | bqarr_in | ) |
| PG_FUNCTION_INFO_V1 | ( | rboolop | ) |
Definition at line 145 of file _int_bool.c.
References NODE::next, WORKSTATE::num, palloc(), WORKSTATE::str, NODE::type, and NODE::val.
Referenced by makepol().
Definition at line 408 of file _int_bool.c.
References contains_required_value(), GETQUERY, and QUERYTYPE::size.
Referenced by ginint4_queryextract().
{
if (query->size <= 0)
return false;
return contains_required_value(GETQUERY(query) + query->size - 1);
}
| Datum querytree | ( | PG_FUNCTION_ARGS | ) |
Definition at line 661 of file _int_bool.c.
References elog, ERROR, and PG_RETURN_NULL.
{
elog(ERROR, "querytree is no longer implemented");
PG_RETURN_NULL();
}
| Datum rboolop | ( | PG_FUNCTION_ARGS | ) |
Definition at line 419 of file _int_bool.c.
References boolop(), DirectFunctionCall2, and PG_GETARG_DATUM.
{
/* just reverse the operands */
return DirectFunctionCall2(boolop,
PG_GETARG_DATUM(1),
PG_GETARG_DATUM(0));
}
Definition at line 309 of file _int_bool.c.
References checkcondition_bit(), execute(), GETQUERY, and QUERYTYPE::size.
Referenced by g_intbig_consistent().
{
return execute(GETQUERY(query) + query->size - 1,
(void *) sign, calcnot,
checkcondition_bit);
}
1.7.1