240 lines
10 KiB
C++
240 lines
10 KiB
C++
/*
|
|
* Copyright (c) 2019 TAOS Data, Inc. <jhtao@taosdata.com>
|
|
*
|
|
* This program is free software: you can use, redistribute, and/or modify
|
|
* it under the terms of the GNU Affero General Public License, version 3
|
|
* or later ("AGPL"), as published by the Free Software Foundation.
|
|
*
|
|
* This program is distributed in the hope that it will be useful, but WITHOUT
|
|
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
|
* FITNESS FOR A PARTICULAR PURPOSE.
|
|
*
|
|
* You should have received a copy of the GNU Affero General Public License
|
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
*/
|
|
|
|
#include "geomFuncTestUtil.h"
|
|
|
|
void callGeomRelationFuncAndCompareResult(FScalarExecProcess geomRelationFunc,
|
|
SScalarParam *pInput, int32_t rowNum,
|
|
int32_t expectedCode, int8_t expectedResult[]) {
|
|
SScalarParam *pOutput;
|
|
makeOneScalarParam(&pOutput, TSDB_DATA_TYPE_BOOL, 0, 0, rowNum);
|
|
int32_t code = geomRelationFunc(pInput, 2, pOutput);
|
|
ASSERT_EQ(code, expectedCode);
|
|
|
|
if (code == TSDB_CODE_SUCCESS) {
|
|
int8_t res = -1;
|
|
for (int32_t i = 0; i < rowNum; ++i) {
|
|
bool isNull1 = colDataIsNull_s(pOutput->columnData, i);
|
|
if (isNull1) {
|
|
res = -1;
|
|
}
|
|
else {
|
|
res = *(bool*)colDataGetData(pOutput->columnData, i);
|
|
}
|
|
|
|
ASSERT_EQ(res, expectedResult[i]);
|
|
}
|
|
}
|
|
|
|
destroyScalarParam(pOutput, 1);
|
|
destroyScalarParam(pInput, 2);
|
|
}
|
|
|
|
/*
|
|
-- Use the following SQL to get expected results for all relation functions in PostgreSQL with PostGIS
|
|
WITH geom_str AS
|
|
(SELECT 'POINT(3.5 7.0)' AS g1, 'POINT(3.5 7.0)' AS g2
|
|
UNION ALL
|
|
SELECT 'POINT(3.0 3.0)' AS g1, 'LINESTRING(1.0 1.0, 2.0 2.0, 5.0 6.0)' AS g2
|
|
UNION ALL
|
|
SELECT 'POINT(3.0 6.0)' AS g1, 'POLYGON((3.0 6.0, 5.0 6.0, 5.0 8.0, 3.0 8.0, 3.0 6.0))' AS g2
|
|
UNION ALL
|
|
SELECT 'LINESTRING(1.0 1.0, 2.0 2.0, 5.0 5.0)' AS g1, 'LINESTRING(1.0 4.0, 2.0 3.0, 5.0 0.0)' AS g2
|
|
UNION ALL
|
|
SELECT 'LINESTRING(3.0 7.0, 4.0 7.0, 5.0 7.0)' AS g1, 'POLYGON((3.0 6.0, 5.0 6.0, 5.0 8.0, 3.0 8.0, 3.0 6.0))' AS g2
|
|
UNION ALL
|
|
SELECT 'POLYGON((3.0 6.0, 5.0 6.0, 5.0 8.0, 3.0 8.0, 3.0 6.0))' AS g1, 'POLYGON((5.0 6.0, 7.0 6.0, 7.0 8.0, 5.0 8.0, 5.0 6.0))' AS g2
|
|
)
|
|
SELECT ST_Intersects(g1, g2), ST_Equals(g1, g2), ST_Touches(g1, g2), ST_Covers(g1, g2), ST_Contains(g1, g2), ST_ContainsProperly(g1, g2) FROM geom_str
|
|
*/
|
|
void geomRelationFuncTest(FScalarExecProcess geomRelationFunc, int8_t expectedResults[6][6]) {
|
|
const int32_t rowNum = 6;
|
|
|
|
char strArray1[rowNum][TSDB_MAX_BINARY_LEN];
|
|
STR_TO_VARSTR(strArray1[0], "POINT(3.5 7.0)");
|
|
STR_TO_VARSTR(strArray1[1], "POINT(3.0 3.0)");
|
|
STR_TO_VARSTR(strArray1[2], "POINT(3.0 6.0)");
|
|
STR_TO_VARSTR(strArray1[3], "LINESTRING(1.0 1.0, 2.0 2.0, 5.0 5.0)");
|
|
STR_TO_VARSTR(strArray1[4], "LINESTRING(3.0 7.0, 4.0 7.0, 5.0 7.0)");
|
|
STR_TO_VARSTR(strArray1[5], "POLYGON((3.0 6.0, 5.0 6.0, 5.0 8.0, 3.0 8.0, 3.0 6.0))");
|
|
TDRowValT valTypeArray1[rowNum] = {TD_VTYPE_NORM, TD_VTYPE_NORM, TD_VTYPE_NORM, TD_VTYPE_NORM, TD_VTYPE_NORM, TD_VTYPE_NORM};
|
|
|
|
char strArray2[rowNum][TSDB_MAX_BINARY_LEN];
|
|
STR_TO_VARSTR(strArray2[0], "POINT(3.5 7.0)");
|
|
STR_TO_VARSTR(strArray2[1], "LINESTRING(1.0 1.0, 2.0 2.0, 5.0 6.0)");
|
|
STR_TO_VARSTR(strArray2[2], "POLYGON((3.0 6.0, 5.0 6.0, 5.0 8.0, 3.0 8.0, 3.0 6.0))");
|
|
STR_TO_VARSTR(strArray2[3], "LINESTRING(1.0 4.0, 2.0 3.0, 5.0 0.0)");
|
|
STR_TO_VARSTR(strArray2[4], "POLYGON((3.0 6.0, 5.0 6.0, 5.0 8.0, 3.0 8.0, 3.0 6.0))");
|
|
STR_TO_VARSTR(strArray2[5], "POLYGON((5.0 6.0, 7.0 6.0, 7.0 8.0, 5.0 8.0, 5.0 6.0))");
|
|
TDRowValT valTypeArray2[rowNum] = {TD_VTYPE_NORM, TD_VTYPE_NORM, TD_VTYPE_NORM, TD_VTYPE_NORM, TD_VTYPE_NORM, TD_VTYPE_NORM};
|
|
|
|
// two columns input
|
|
SScalarParam *pInput = (SScalarParam *)taosMemoryCalloc(2, sizeof(SScalarParam));
|
|
callGeomFromTextWrapper5(strArray1, valTypeArray1, rowNum, pInput); //pInput come from GeomFromText()
|
|
callGeomFromTextWrapper5(strArray2, valTypeArray2, rowNum, pInput + 1);
|
|
callGeomRelationFuncAndCompareResult(geomRelationFunc, pInput, rowNum, TSDB_CODE_SUCCESS, expectedResults[0]);
|
|
|
|
// swap two columns
|
|
pInput = (SScalarParam *)taosMemoryCalloc(2, sizeof(SScalarParam));
|
|
callGeomFromTextWrapper5(strArray2, valTypeArray2, rowNum, pInput);
|
|
callGeomFromTextWrapper5(strArray1, valTypeArray1, rowNum, pInput + 1);
|
|
callGeomRelationFuncAndCompareResult(geomRelationFunc, pInput, rowNum, TSDB_CODE_SUCCESS, expectedResults[1]);
|
|
|
|
// constant and column input
|
|
pInput = (SScalarParam *)taosMemoryCalloc(2, sizeof(SScalarParam));
|
|
callGeomFromTextWrapper5(strArray1, valTypeArray1, 1, pInput);
|
|
callGeomFromTextWrapper5(strArray2, valTypeArray2, rowNum, pInput + 1);
|
|
callGeomRelationFuncAndCompareResult(geomRelationFunc, pInput, rowNum, TSDB_CODE_SUCCESS, expectedResults[2]);
|
|
|
|
// column and constant input
|
|
pInput = (SScalarParam *)taosMemoryCalloc(2, sizeof(SScalarParam));
|
|
callGeomFromTextWrapper5(strArray1, valTypeArray1, rowNum, pInput);
|
|
callGeomFromTextWrapper5(strArray2, valTypeArray2, 1, pInput + 1);
|
|
callGeomRelationFuncAndCompareResult(geomRelationFunc, pInput, rowNum, TSDB_CODE_SUCCESS, expectedResults[3]);
|
|
|
|
// two constants input
|
|
pInput = (SScalarParam *)taosMemoryCalloc(2, sizeof(SScalarParam));
|
|
callGeomFromTextWrapper5(strArray1, valTypeArray1, 1, pInput);
|
|
callGeomFromTextWrapper5(strArray2, valTypeArray2, 1, pInput + 1);
|
|
callGeomRelationFuncAndCompareResult(geomRelationFunc, pInput, 1, TSDB_CODE_SUCCESS, expectedResults[4]);
|
|
|
|
// two columns with NULL value input
|
|
pInput = (SScalarParam *)taosMemoryCalloc(2, sizeof(SScalarParam));
|
|
valTypeArray1[2] = TD_VTYPE_NULL;
|
|
valTypeArray2[4] = TD_VTYPE_NULL;
|
|
callGeomFromTextWrapper5(strArray1, valTypeArray1, rowNum, pInput);
|
|
callGeomFromTextWrapper5(strArray2, valTypeArray2, rowNum, pInput + 1);
|
|
callGeomRelationFuncAndCompareResult(geomRelationFunc, pInput, rowNum, TSDB_CODE_SUCCESS, expectedResults[5]);
|
|
|
|
// first NULL type input
|
|
pInput = (SScalarParam *)taosMemoryCalloc(2, sizeof(SScalarParam));
|
|
setScalarParam(pInput, TSDB_DATA_TYPE_NULL, 0, 0, 1);
|
|
callGeomFromTextWrapper5(strArray2, valTypeArray2, rowNum, pInput + 1);
|
|
int8_t expectedResultNullType[rowNum] = {-1, -1, -1, -1, -1, -1};
|
|
callGeomRelationFuncAndCompareResult(geomRelationFunc, pInput, rowNum, TSDB_CODE_SUCCESS, expectedResultNullType);
|
|
|
|
// second NULL type input
|
|
pInput = (SScalarParam *)taosMemoryCalloc(2, sizeof(SScalarParam));
|
|
callGeomFromTextWrapper5(strArray1, valTypeArray1, rowNum, pInput);
|
|
setScalarParam(pInput + 1, TSDB_DATA_TYPE_NULL, 0, 0, 1);
|
|
callGeomRelationFuncAndCompareResult(geomRelationFunc, pInput, rowNum, TSDB_CODE_SUCCESS, expectedResultNullType);
|
|
|
|
// first empty content input
|
|
pInput = (SScalarParam *)taosMemoryCalloc(2, sizeof(SScalarParam));
|
|
char strInput[TSDB_MAX_BINARY_LEN];
|
|
STR_TO_VARSTR(strInput, "");
|
|
setScalarParam(pInput, TSDB_DATA_TYPE_GEOMETRY, strInput, valTypeArray1, 1);
|
|
callGeomFromTextWrapper5(strArray2, valTypeArray2, rowNum, pInput + 1);
|
|
callGeomRelationFuncAndCompareResult(geomRelationFunc, pInput, rowNum, TSDB_CODE_SUCCESS, expectedResultNullType);
|
|
|
|
// first wrong type input
|
|
pInput = (SScalarParam *)taosMemoryCalloc(2, sizeof(SScalarParam));
|
|
int32_t intInput = 3;
|
|
setScalarParam(pInput, TSDB_DATA_TYPE_INT, &intInput, valTypeArray1, 1);
|
|
callGeomFromTextWrapper5(strArray2, valTypeArray2, rowNum, pInput + 1);
|
|
callGeomRelationFuncAndCompareResult(geomRelationFunc, pInput, rowNum, TSDB_CODE_FUNC_FUNTION_PARA_VALUE, 0);
|
|
|
|
// second wrong content input
|
|
pInput = (SScalarParam *)taosMemoryCalloc(2, sizeof(SScalarParam));
|
|
STR_TO_VARSTR(strInput, "XXX");
|
|
callGeomFromTextWrapper5(strArray1, valTypeArray1, rowNum, pInput);
|
|
setScalarParam(pInput + 1, TSDB_DATA_TYPE_GEOMETRY, strInput, valTypeArray2, 1);
|
|
callGeomRelationFuncAndCompareResult(geomRelationFunc, pInput, rowNum, TSDB_CODE_FUNC_FUNTION_PARA_VALUE, 0);
|
|
}
|
|
|
|
TEST(GeomRelationFuncTest, intersectsFunction) {
|
|
// 1: true, 0: false, -1: null
|
|
int8_t expectedResults[6][6] = {
|
|
{1, 0, 1, 1, 1, 1}, // two columns
|
|
{1, 0, 1, 1, 1, 1}, // two columns swpped
|
|
{1, 0, 1, 0, 1, 0}, // first constant
|
|
{1, 0, 0, 0, 1, 1}, // second constant
|
|
{1}, // two constant
|
|
{1, 0, -1, 1, -1, 1} // with Null value
|
|
};
|
|
|
|
geomRelationFuncTest(intersectsFunction, expectedResults);
|
|
}
|
|
|
|
TEST(GeomRelationFuncTest, equalsFunction) {
|
|
// 1: true, 0: false, -1: null
|
|
int8_t expectedResults[6][6] = {
|
|
{1, 0, 0, 0, 0, 0}, // two columns
|
|
{1, 0, 0, 0, 0, 0}, // two columns swapped
|
|
{1, 0, 0, 0, 0, 0}, // first constant
|
|
{1, 0, 0, 0, 0, 0}, // second constant
|
|
{1}, // two constant
|
|
{1, 0, -1, 0, -1, 0} // with Null value
|
|
};
|
|
|
|
geomRelationFuncTest(equalsFunction, expectedResults);
|
|
}
|
|
|
|
TEST(GeomRelationFuncTest, touchesFunction) {
|
|
// 1: true, 0: false, -1: null
|
|
int8_t expectedResults[6][6] = {
|
|
{0, 0, 1, 0, 0, 1}, // two columns
|
|
{0, 0, 1, 0, 0, 1}, // two columns swapped
|
|
{0, 0, 0, 0, 0, 0}, // first constant
|
|
{0, 0, 0, 0, 0, 0}, // second constant
|
|
{0}, // two constant
|
|
{0, 0, -1, 0, -1, 1} // with Null value
|
|
};
|
|
|
|
geomRelationFuncTest(touchesFunction, expectedResults);
|
|
}
|
|
|
|
TEST(GeomRelationFuncTest, coversFunction) {
|
|
// 1: true, 0: false, -1: null
|
|
int8_t expectedResults[6][6] = {
|
|
{1, 0, 0, 0, 0, 0}, // two columns
|
|
{1, 0, 1, 0, 1, 0}, // two columns swapped
|
|
{1, 0, 0, 0, 0, 0}, // first constant
|
|
{1, 0, 0, 0, 1, 1}, // second constant
|
|
{1}, // two constant
|
|
{1, 0, -1, 0, -1, 0} // with Null value
|
|
};
|
|
|
|
geomRelationFuncTest(coversFunction, expectedResults);
|
|
}
|
|
|
|
TEST(GeomRelationFuncTest, containsFunction) {
|
|
// 1: true, 0: false, -1: null
|
|
int8_t expectedResults[6][6] = {
|
|
{1, 0, 0, 0, 0, 0}, // two columns
|
|
{1, 0, 0, 0, 1, 0}, // two columns swapped
|
|
{1, 0, 0, 0, 0, 0}, // first constant
|
|
{1, 0, 0, 0, 1, 1}, // second constant
|
|
{1}, // two constant
|
|
{1, 0, -1, 0, -1, 0} // with Null value
|
|
};
|
|
|
|
geomRelationFuncTest(containsFunction, expectedResults);
|
|
}
|
|
|
|
TEST(GeomRelationFuncTest, containsProperlyFunction) {
|
|
// 1: true, 0: false, -1: null
|
|
int8_t expectedResults[6][6] = {
|
|
{1, 0, 0, 0, 0, 0}, // two columns
|
|
{1, 0, 0, 0, 0, 0}, // two columns swapped
|
|
{1, 0, 0, 0, 0, 0}, // first constant
|
|
{1, 0, 0, 0, 1, 1}, // second constant
|
|
{1}, // two constant
|
|
{1, 0, -1, 0, -1, 0} // with Null value
|
|
};
|
|
|
|
geomRelationFuncTest(containsProperlyFunction, expectedResults);
|
|
}
|