예제 #1
0
Datum
jsquery_gt(PG_FUNCTION_ARGS)
{
	JsQuery		*jq1 = PG_GETARG_JSQUERY(0);
	JsQuery		*jq2 = PG_GETARG_JSQUERY(1);
	int32		res;

	res = compareJsQuery(VARDATA(jq1), 0, VARDATA(jq2), 0); 

	PG_FREE_IF_COPY(jq1, 0);
	PG_FREE_IF_COPY(jq2, 1);

	PG_RETURN_BOOL(res > 0);
}
예제 #2
0
파일: jsquery_op.c 프로젝트: kaplun/jsquery
Datum
jsquery_gt(PG_FUNCTION_ARGS)
{
	JsQuery			*jq1 = PG_GETARG_JSQUERY(0);
	JsQuery			*jq2 = PG_GETARG_JSQUERY(1);
	int32			res;
	JsQueryItem		v1, v2;

	jsqInit(&v1, jq1);
	jsqInit(&v2, jq2);

	res = compareJsQuery(&v1, &v2);

	PG_FREE_IF_COPY(jq1, 0);
	PG_FREE_IF_COPY(jq2, 1);

	PG_RETURN_BOOL(res > 0);
}
예제 #3
0
파일: jsquery_op.c 프로젝트: kaplun/jsquery
static int
compareJsQuery(JsQueryItem *v1, JsQueryItem *v2)
{
	JsQueryItem	elem1, elem2;
	int32			res = 0;

	check_stack_depth();

	if (v1->type != v2->type)
		return (v1->type > v2->type) ? 1 : -1;

	switch(v1->type)
	{
		case jqiNull:
		case jqiCurrent:
		case jqiLength:
		case jqiAny:
		case jqiAnyArray:
		case jqiAnyKey:
		case jqiAll:
		case jqiAllArray:
		case jqiAllKey:
			break;
		case jqiKey:
		case jqiString:
			{
				int32 len1, len2;
				char *s1, *s2;

				s1 = jsqGetString(v1, &len1);
				s2 = jsqGetString(v2, &len2);

				if (len1 != len2)
					res = (len1 > len2) ? 1 : -1;
				else
					res = memcmp(s1, s2, len1);
			}
			break;
		case jqiNumeric:
			res = compareNumeric(jsqGetNumeric(v1), jsqGetNumeric(v2));
			break;
		case jqiBool:
			if (jsqGetBool(v1) != jsqGetBool(v2))
				res = (jsqGetBool(v1) > jsqGetBool(v2)) ? 1 : -1;
			break;
		case jqiArray:
			if (v1->array.nelems != v2->array.nelems)
				res = (v1->array.nelems > v2->array.nelems) ? 1 : -1;

			while(res == 0 && jsqIterateArray(v1, &elem1) && jsqIterateArray(v2, &elem2))
				res = compareJsQuery(&elem1, &elem2);
			break;
		case jqiAnd:
		case jqiOr:
			jsqGetLeftArg(v1, &elem1);
			jsqGetLeftArg(v2, &elem2);

			res = compareJsQuery(&elem1, &elem2);

			if (res == 0)
			{
				jsqGetRightArg(v1, &elem1);
				jsqGetRightArg(v2, &elem2);

				res = compareJsQuery(&elem1, &elem2);
			}
			break;
		case jqiEqual:
		case jqiIn:
		case jqiLess:
		case jqiGreater:
		case jqiLessOrEqual:
		case jqiGreaterOrEqual:
		case jqiContains:
		case jqiContained:
		case jqiOverlap:
		case jqiNot:
			jsqGetArg(v1, &elem1);
			jsqGetArg(v2, &elem2);

			res = compareJsQuery(&elem1, &elem2);
			break;
		default:
			elog(ERROR, "Unknown JsQueryItem type: %d", v1->type);
	}

	if (res == 0)
	{
		if (jsqGetNext(v1, &elem1))
		{
			if (jsqGetNext(v2, &elem2))
				res = compareJsQuery(&elem1, &elem2);
			else
				res = 1;
		}
		else if (jsqGetNext(v2, &elem2))
		{
			res = -1;
		}
	}

	return res;
}
예제 #4
0
static int
compareJsQuery(char *base1, int32 pos1, char *base2, int32 pos2)
{
	int32	type1,
			nextPos1,
			type2,
			nextPos2;
	int32	res = 0;

	check_stack_depth();

	pos1 = readJsQueryHeader(base1, pos1, &type1, &nextPos1);
	pos2 = readJsQueryHeader(base2, pos2, &type2, &nextPos2);

	if (type1 != type2)
		return (type1 > type2) ? 1 : -1;

	switch(type1)
	{
		case jqiNull:
		case jqiAny:
		case jqiAnyArray:
			break;
		case jqiKey:
		case jqiString:
			{
				int32 len1, len2;

				read_int32(len1, base1, pos1);
				read_int32(len2, base2, pos2);

				if (len1 != len2)
					res = (len1 > len2) ? 1 : -1;
				else
					res = memcmp(base1 + pos1, base2 + pos2, len1);
			}
			break;
		case jqiNumeric:
			res = compareNumeric((Numeric)(base1 + pos1), (Numeric)(base2 + pos2));
			break;
		case jqiBool:
			{
				bool v1, v2;

				read_byte(v1, base1, pos1);
				read_byte(v2, base2, pos2);

				if (v1 != v2)
					res = (v1 > v2) ? 1 : -1;
			}
			break;
		case jqiArray:
			{
				int32	i;
				int32	nelems1, *arrayPos1,
						nelems2, *arrayPos2;

				read_int32(nelems1, base1, pos1);
				arrayPos1 = (int32*)(base1 + pos1);
				read_int32(nelems2, base2, pos2);
				arrayPos2 = (int32*)(base2 + pos2);

				if (nelems1 != nelems2)
					res = (nelems1 > nelems2) ? 1 : -1;

				for(i=0; i<nelems1 && res == 0; i++)
					res = compareJsQuery(base1, arrayPos1[i], base2, arrayPos2[i]);
			}
			break;
		case jqiAnd:
		case jqiOr:
			{
				int32	left1, right1,
						left2, right2;

				read_int32(left1, base1, pos1);
				read_int32(right1, base1, pos1);
				read_int32(left2, base2, pos2);
				read_int32(right2, base2, pos2);

				res = compareJsQuery(base1, left1, base2, left2);
				if (res == 0)
					res = compareJsQuery(base1, right1, base2, right2);
			}
			break;
		case jqiEqual:
		case jqiIn:
		case jqiLess:
		case jqiGreater:
		case jqiLessOrEqual:
		case jqiGreaterOrEqual:
		case jqiContains:
		case jqiContained:
		case jqiOverlap:
		case jqiNot:
			{
				int32	arg1, arg2;

				read_int32(arg1, base1, pos1);
				read_int32(arg2, base2, pos2);

				res = compareJsQuery(base1, arg1, base2, arg2);
			}
			break;
		default:
			elog(ERROR, "Unknown JsQueryItem type: %d", type1);
	}

	if (res == 0 && !(nextPos2 == 0 && nextPos1 == 0))
	{
		if (nextPos1 == 0 || nextPos2 == 0)
			res = (nextPos1 > nextPos2) ? 1 : -1;
		else
			res = compareJsQuery(base1, nextPos1, base2, nextPos2);
	}

	return res;
}