Ejemplo n.º 1
0
static bool
executeArrayOp(char *jqBase, int32 jqPos, int32 type, int32 op, JsonbValue *jb)
{
	int32   		i, nelems, *arrayPos;
	int32			r;
	JsonbIterator	*it;
	JsonbValue		v;
	int32			nres = 0, nval = 0;

	if (jb->type != jbvBinary)
		return false;
	if (type != jqiArray)
		return false;

	read_int32(nelems, jqBase, jqPos);
	arrayPos = (int32*)(jqBase + jqPos);

	it = JsonbIteratorInit(jb->val.binary.data);

	while((r = JsonbIteratorNext(&it, &v, true)) != WJB_DONE)
	{
		if (r == WJB_BEGIN_ARRAY)
			nval = v.val.array.nElems;

		if (r == WJB_ELEM)
		{
			bool res = false;

			for(i=0; i<nelems; i++)
			{
				if (executeExpr(jqBase, arrayPos[i], jqiEqual, &v))
				{
					if (op == jqiOverlap)
						return true;
					nres++;
					res = true;
					break;
				}
			}
		}
	}

	if (op == jqiContains)
		return (nres == nelems && nelems > 0);
	if (op == jqiContained)
		return (nres == nval && nval > 0);

	return false;
}
Ejemplo n.º 2
0
static bool
checkIn(char *jqBase, int32 jqPos, int32 type, JsonbValue *jb)
{
	int32   i, nelems, *arrayPos;

	if (jb->type == jbvBinary)
		return false;

	if (type != jqiArray)
		return false;

	read_int32(nelems, jqBase, jqPos);
	arrayPos = (int32*)(jqBase + jqPos);

	for(i=0; i<nelems; i++)
		if (executeExpr(jqBase, arrayPos[i], jqiEqual, jb))
			return true;

	return false;
}
Ejemplo n.º 3
0
static bool
checkArrayEquality(char *jqBase, int32 jqPos, int32 type, JsonbValue *jb)
{
	int32   		i, nelems, *arrayPos;
	int32			r;
	JsonbIterator	*it;
	JsonbValue		v;

	if (!(type == jqiArray && jb->type == jbvBinary))
		return false;

	read_int32(nelems, jqBase, jqPos);
	arrayPos = (int32*)(jqBase + jqPos);

	it = JsonbIteratorInit(jb->val.binary.data);

	r = JsonbIteratorNext(&it, &v, true);

	if (r != WJB_BEGIN_ARRAY)
		return false;

	if (v.val.array.nElems != nelems)
		return false;

	i = 0;
	while((r = JsonbIteratorNext(&it, &v, true)) != WJB_DONE)
	{
		if (r == WJB_ELEM && i<nelems)
		{
			if (executeExpr(jqBase, arrayPos[i], jqiEqual, &v) == false)
				return false;
			i++;
		}
	}
	
	return true;
}
Ejemplo n.º 4
0
static bool
recursiveExecute(JsQueryItem *jsq, JsonbValue *jb, JsQueryItem *jsqLeftArg)
{
	JsQueryItem		elem;
	bool			res = false;

	check_stack_depth();

	switch(jsq->type) {
		case jqiAnd:
			jsqGetLeftArg(jsq, &elem);
			res = recursiveExecute(&elem, jb, jsqLeftArg);
			if (res == true)
			{
				jsqGetRightArg(jsq, &elem);
				res = recursiveExecute(&elem, jb, jsqLeftArg);
			}
			break;
		case jqiOr:
			jsqGetLeftArg(jsq, &elem);
			res = recursiveExecute(&elem, jb, jsqLeftArg);
			if (res == false)
			{
				jsqGetRightArg(jsq, &elem);
				res = recursiveExecute(&elem, jb, jsqLeftArg);
			}
			break;
		case jqiNot:
			jsqGetArg(jsq, &elem);
			res = !recursiveExecute(&elem, jb, jsqLeftArg);
			break;
		case jqiKey:
			if (JsonbType(jb) == jbvObject) {
				JsonbValue	*v, key;

				key.type = jbvString;
				key.val.string.val = jsqGetString(jsq, &key.val.string.len);

				v = findJsonbValueFromContainer(jb->val.binary.data, JB_FOBJECT, &key);

				if (v != NULL)
				{
					jsqGetNext(jsq, &elem);
					res = recursiveExecute(&elem, v, NULL);
					pfree(v);
				}
			}
			break;
		case jqiCurrent:
			jsqGetNext(jsq, &elem);
			if (JsonbType(jb) == jbvScalar)
			{
				JsonbIterator	*it;
				int32			r;
				JsonbValue		v;

				it = JsonbIteratorInit(jb->val.binary.data);

				r = JsonbIteratorNext(&it, &v, true);
				Assert(r == WJB_BEGIN_ARRAY);
				Assert(v.val.array.rawScalar == 1);
				Assert(v.val.array.nElems == 1);

				r = JsonbIteratorNext(&it, &v, true);
				Assert(r == WJB_ELEM);

				res = recursiveExecute(&elem, &v, jsqLeftArg);
			}
			else
			{
				res = recursiveExecute(&elem, jb, jsqLeftArg);
			}
			break;
		case jqiAny:
			jsqGetNext(jsq, &elem);
			if (recursiveExecute(&elem, jb, NULL))
				res = true;
			else if (jb->type == jbvBinary)
				res = recursiveAny(&elem, jb);
			break;
		case jqiAll:
			jsqGetNext(jsq, &elem);
			if ((res = recursiveExecute(&elem, jb, NULL)) == true)
			{
				if (jb->type == jbvBinary)
					res = recursiveAll(&elem, jb);
			}
			break;
		case jqiAnyArray:
		case jqiAllArray:
			if (JsonbType(jb) == jbvArray)
			{
				JsonbIterator	*it;
				int32			r;
				JsonbValue		v;

				jsqGetNext(jsq, &elem);
				it = JsonbIteratorInit(jb->val.binary.data);

				if (jsq->type == jqiAllArray)
					res = true;

				while((r = JsonbIteratorNext(&it, &v, true)) != WJB_DONE)
				{
					if (r == WJB_ELEM)
					{
						res = recursiveExecute(&elem, &v, NULL);

						if (jsq->type == jqiAnyArray)
						{
							if (res == true)
								break;
						}
						else if (jsq->type == jqiAllArray)
						{
							if (res == false)
								break;
						}
					}
				}
			}
			break;
		case jqiAnyKey:
		case jqiAllKey:
			if (JsonbType(jb) == jbvObject)
			{
				JsonbIterator	*it;
				int32			r;
				JsonbValue		v;

				jsqGetNext(jsq, &elem);
				it = JsonbIteratorInit(jb->val.binary.data);

				if (jsq->type == jqiAllKey)
					res = true;

				while((r = JsonbIteratorNext(&it, &v, true)) != WJB_DONE)
				{
					if (r == WJB_VALUE)
					{
						res = recursiveExecute(&elem, &v, NULL);

						if (jsq->type == jqiAnyKey)
						{
							if (res == true)
								break;
						}
						else if (jsq->type == jqiAllKey)
						{
							if (res == false)
								break;
						}
					}
				}
			}
			break;
		case jqiEqual:
		case jqiIn:
		case jqiLess:
		case jqiGreater:
		case jqiLessOrEqual:
		case jqiGreaterOrEqual:
		case jqiContains:
		case jqiContained:
		case jqiOverlap:
			jsqGetArg(jsq, &elem);
			res = executeExpr(&elem, jsq->type, jb, jsqLeftArg);
			break;
		case jqiLength:
			jsqGetNext(jsq, &elem);
			res = recursiveExecute(&elem, jb, jsq);
			break;
		case jqiIs:
			if (JsonbType(jb) == jbvScalar)
			{
				JsonbIterator	*it;
				int32			r;
				JsonbValue		v;

				it = JsonbIteratorInit(jb->val.binary.data);

				r = JsonbIteratorNext(&it, &v, true);
				Assert(r == WJB_BEGIN_ARRAY);
				Assert(v.val.array.rawScalar == 1);
				Assert(v.val.array.nElems == 1);

				r = JsonbIteratorNext(&it, &v, true);
				Assert(r == WJB_ELEM);

				res = (jsqGetIsType(jsq) == JsonbType(&v));
			}
			else
			{
				res = (jsqGetIsType(jsq) == JsonbType(jb));
			}
			break;
		default:
			elog(ERROR,"Wrong state: %d", jsq->type);
	}

	return res;
}
Ejemplo n.º 5
0
static bool
recursiveExecute(char *jqBase, int32 jqPos, JsonbValue *jb)
{
	int32	type;
	int32	nextPos;
	int32	left, right, arg;
	bool	res = false;

	check_stack_depth();

	jqPos = readJsQueryHeader(jqBase, jqPos, &type, &nextPos);

	switch(type) {
		case jqiAnd:
			read_int32(left, jqBase, jqPos);
			read_int32(right, jqBase, jqPos);
			Assert(nextPos == 0);
			res = (recursiveExecute(jqBase, left, jb) && recursiveExecute(jqBase, right, jb));
			break;
		case jqiOr:
			read_int32(left, jqBase, jqPos);
			read_int32(right, jqBase, jqPos);
			Assert(nextPos == 0);
			res = (recursiveExecute(jqBase, left, jb) || recursiveExecute(jqBase, right, jb));
			break;
		case jqiNot:
			read_int32(arg, jqBase, jqPos);
			Assert(nextPos == 0);
			res = ! recursiveExecute(jqBase, arg, jb);
			break;
		case jqiKey:
			if (jb->type == jbvBinary) {
				int32 		len;
				JsonbValue	*v, key;

				read_int32(len, jqBase, jqPos);
				key.type = jbvString;
				key.val.string.val = jqBase + jqPos;
				key.val.string.len = len;
				jqPos += len + 1;

				v = findJsonbValueFromSuperHeader(jb->val.binary.data, JB_FOBJECT, NULL, &key);

				Assert(nextPos != 0);
				res = ((v != NULL) && recursiveExecute(jqBase, nextPos, v));
			}
			break;
		case jqiAny:
			Assert(nextPos != 0);
			if (recursiveExecute(jqBase, nextPos, jb))
				res = true;
			else if (jb->type == jbvBinary)
				res = recursiveAny(jqBase, nextPos, jb);
			break;
		case jqiAnyArray:
			Assert(nextPos != 0);
			if (jb->type == jbvBinary) {
				JsonbIterator	*it;
				int32			r;
				JsonbValue		v;

				it = JsonbIteratorInit(jb->val.binary.data);

				while(res == false && (r = JsonbIteratorNext(&it, &v, true)) != WJB_DONE)
				{
					if (r == WJB_KEY)
						break;

					if (r == WJB_ELEM)
						res = recursiveExecute(jqBase, nextPos, &v);
				}
			}
			break;
		case jqiEqual:
		case jqiIn:
		case jqiLess:
		case jqiGreater:
		case jqiLessOrEqual:
		case jqiGreaterOrEqual:
		case jqiContains:
		case jqiContained:
		case jqiOverlap:
			read_int32(arg, jqBase, jqPos);
			res = executeExpr(jqBase, arg, type, jb);
			break;
		default:
			elog(ERROR,"Wrong state: %d", type);
	}

	return res;
}