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