homework-jianmu/source/libs/geometry/test/geomRelationFuncTest.cpp

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);
}