/** * Copyright (c) 2023 OceanBase * OceanBase CE is licensed under Mulan PubL v2. * You can use this software according to the terms and conditions of the Mulan PubL v2. * You may obtain a copy of Mulan PubL v2 at: * http://license.coscl.org.cn/MulanPubL-2.0 * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. * See the Mulan PubL v2 for more details. */ #include #include #include "lib/geo/ob_geo_func_register.h" #include "ob_geo_func_testx.h" #include "ob_geo_func_testy.h" #include "lib/json_type/ob_json_common.h" using namespace oceanbase::common; namespace oceanbase { namespace sql { class TestGisDispatcher : public ::testing::Test { public: TestGisDispatcher() {} ~TestGisDispatcher() {} virtual void SetUp() {} virtual void TearDown() {} static void SetUpTestCase() {} static void TearDownTestCase() {} private: // disallow copy DISALLOW_COPY_AND_ASSIGN(TestGisDispatcher); }; // X will call functor Y enum class ObGeoFuncTestType { NotImplemented = 0, TypeX = 1, TypeY = 2 }; template struct ObGisTestFunc { typedef ObGeoFuncNotImplemented geo_func; }; template <> struct ObGisTestFunc { typedef ObGeoFuncTypeX geo_func; }; template <> struct ObGisTestFunc { typedef ObGeoFuncMockY geo_func; }; TEST_F(TestGisDispatcher, not_impl) { ObIWkbGeomPoint cp; ObIWkbGeogPoint gp; int ret = OB_SUCCESS; int result; ObGeoEvalCtx gis_context; ret = ObGisTestFunc::geo_func::eval(gis_context, result); ASSERT_EQ(ret, OB_ERR_GIS_INVALID_DATA); ret = OB_SUCCESS; ret = ObGeoFunc::geo_func::eval(gis_context, result); ASSERT_EQ(ret, OB_ERR_GIS_INVALID_DATA); } TEST_F(TestGisDispatcher, dispatcher) { ObString dumy_wkb(4, 4, "dumy"); ObIWkbGeomPoint cp; ObIWkbGeomLineString cl; ObIWkbGeomPolygon ca; ObIWkbGeomMultiPoint cmp; ObIWkbGeomMultiLineString cml; ObIWkbGeomMultiPolygon cma; ObIWkbGeomCollection cc; ObIWkbGeogPoint gp; ObIWkbGeogLineString gl; ObIWkbGeogPolygon ga; ObIWkbGeogMultiPoint gmp; ObIWkbGeogMultiLineString gml; ObIWkbGeogMultiPolygon gma; ObIWkbGeogCollection gc; ObArenaAllocator allocator(ObModIds::TEST); ObSrsItem srs(NULL); ObGeoEvalCtx gis_context(&allocator, &srs); ObGeometry *gis_args[3][8] = {{0}}; gis_args[static_cast(ObGeoCRS::Cartesian)][static_cast(ObGeoType::POINT)] = &cp; gis_args[static_cast(ObGeoCRS::Cartesian)][static_cast(ObGeoType::LINESTRING)] = &cl; gis_args[static_cast(ObGeoCRS::Cartesian)][static_cast(ObGeoType::POLYGON)] = &ca; gis_args[static_cast(ObGeoCRS::Cartesian)][static_cast(ObGeoType::MULTIPOINT)] = &cmp; gis_args[static_cast(ObGeoCRS::Cartesian)][static_cast(ObGeoType::MULTILINESTRING)] = &cml; gis_args[static_cast(ObGeoCRS::Cartesian)][static_cast(ObGeoType::MULTIPOLYGON)] = &cma; gis_args[static_cast(ObGeoCRS::Cartesian)][static_cast(ObGeoType::GEOMETRYCOLLECTION)] = &cc; gis_args[static_cast(ObGeoCRS::Geographic)][static_cast(ObGeoType::POINT)] = &gp; gis_args[static_cast(ObGeoCRS::Geographic)][static_cast(ObGeoType::LINESTRING)] = ≷ gis_args[static_cast(ObGeoCRS::Geographic)][static_cast(ObGeoType::POLYGON)] = &ga; gis_args[static_cast(ObGeoCRS::Geographic)][static_cast(ObGeoType::MULTIPOINT)] = &gmp; gis_args[static_cast(ObGeoCRS::Geographic)][static_cast(ObGeoType::MULTILINESTRING)] = &gml; gis_args[static_cast(ObGeoCRS::Geographic)][static_cast(ObGeoType::MULTIPOLYGON)] = &gma; gis_args[static_cast(ObGeoCRS::Geographic)][static_cast(ObGeoType::GEOMETRYCOLLECTION)] = &gc; int result = 0; int ret = OB_SUCCESS; for (int crs_type = 1; crs_type < static_cast(ObGeoCRS::Geographic) + 1; crs_type++) { for (int g1_type = 1; g1_type < static_cast(ObGeoType::GEOMETRYCOLLECTION) + 1; g1_type++) { gis_args[crs_type][g1_type]->set_data(dumy_wkb); } } for (int crs_type = 1; crs_type < static_cast(ObGeoCRS::Geographic) + 1; crs_type++) { for (int g1_type = 1; g1_type < static_cast(ObGeoType::GEOMETRYCOLLECTION) + 1; g1_type++) { gis_context.ut_set_geo_count(1); gis_context.ut_set_geo_arg(0, gis_args[crs_type][g1_type]); ret = ObGisTestFunc::geo_func::eval(gis_context, result); ASSERT_EQ(ret, OB_SUCCESS); ASSERT_EQ(result, g_test_geo_unary_func_result[crs_type][g1_type]); } } for (int crs_type = 1; crs_type < static_cast(ObGeoCRS::Geographic) + 1; crs_type++) { for (int g1_type = 1; g1_type < static_cast(ObGeoType::GEOMETRYCOLLECTION) + 1; g1_type++) { for (int g2_type = 1; g2_type < static_cast(ObGeoType::GEOMETRYCOLLECTION) + 1; g2_type++) { gis_context.ut_set_geo_count(2); gis_context.ut_set_geo_arg(0, gis_args[crs_type][g1_type]); gis_context.ut_set_geo_arg(1, gis_args[crs_type][g2_type]); ret = ObGisTestFunc::geo_func::eval(gis_context, result); ASSERT_EQ(ret, OB_SUCCESS); ASSERT_EQ(result, g_test_geo_binary_func_result[crs_type][g1_type][crs_type][g2_type]); } } } } TEST_F(TestGisDispatcher, specialization_and_exception_test) { ObIWkbGeomPoint cp; ObIWkbGeomPolygon ca; ObIWkbGeogPoint gp; ObIWkbGeogLineString gl; ObIWkbGeogPolygon ga; ObIWkbGeogCollection gm; ObString dumy_wkb(4, 4, "dumy"); cp.set_data(dumy_wkb); ca.set_data(dumy_wkb); gp.set_data(dumy_wkb); gl.set_data(dumy_wkb); ga.set_data(dumy_wkb); gm.set_data(dumy_wkb); int ret = OB_SUCCESS; ObArenaAllocator allocator(ObModIds::TEST); ObSrsItem srs(NULL); ObGeoEvalCtx gis_context(&allocator, &srs); ret = gis_context.append_geo_arg(&cp); ASSERT_EQ(ret, OB_SUCCESS); int result = 0; ret = ObGisTestFunc::geo_func::eval(gis_context, result); ASSERT_EQ(ret, OB_SUCCESS); ASSERT_EQ(result, 1); gis_context.ut_set_geo_arg(0, &ca); ret = ObGisTestFunc::geo_func::eval(gis_context, result); ASSERT_EQ(ret, OB_SUCCESS); ASSERT_EQ(result, 3); gis_context.ut_set_geo_arg(0, &gp); ret = ObGisTestFunc::geo_func::eval(gis_context, result); ASSERT_EQ(ret, OB_SUCCESS); ASSERT_EQ(result, 1); gis_context.ut_set_geo_arg(0, &ga); ret = ObGisTestFunc::geo_func::eval(gis_context, result); ASSERT_EQ(ret, OB_SUCCESS); ASSERT_EQ(result, 3); gis_context.ut_set_geo_arg(0, &gm); ret = ObGisTestFunc::geo_func::eval(gis_context, result); ASSERT_EQ(ret, OB_ERR_NOT_IMPLEMENTED_FOR_GEOGRAPHIC_SRS); ASSERT_EQ(result, 7); gis_context.ut_set_geo_count(2); gis_context.ut_set_geo_arg(0, &ca); gis_context.ut_set_geo_arg(1, &ca); ret = ObGisTestFunc::geo_func::eval(gis_context, result); ASSERT_EQ(ret, OB_SUCCESS); ASSERT_EQ(result, 6); gis_context.ut_set_geo_arg(0, &ga); gis_context.ut_set_geo_arg(1, &ga); ret = ObGisTestFunc::geo_func::eval(gis_context, result); ASSERT_EQ(ret, OB_SUCCESS); ASSERT_EQ(result, 800); gis_context.ut_set_geo_arg(0, &gm); gis_context.ut_set_geo_arg(1, &gm); ret = ObGisTestFunc::geo_func::eval(gis_context, result); ASSERT_EQ(ret, OB_ERR_NOT_IMPLEMENTED_FOR_GEOGRAPHIC_SRS); ASSERT_EQ(result, 14); // test "functor" call "functor" ObIWkbGeogMultiPoint gmp; gmp.set_data(dumy_wkb); gis_context.ut_set_geo_arg(0, &gmp); gis_context.ut_set_geo_arg(1, &gmp); ret = ObGisTestFunc::geo_func::eval(gis_context, result); ASSERT_EQ(ret, OB_SUCCESS); ASSERT_EQ(result, 814); gis_context.ut_set_geo_arg(0, &gp); gis_context.ut_set_geo_arg(1, &gmp); ret = ObGisTestFunc::geo_func::eval(gis_context, result); ASSERT_EQ(ret, OB_SUCCESS); ASSERT_EQ(result, 100); gis_context.ut_set_geo_arg(0, &gmp); gis_context.ut_set_geo_arg(1, &gp); ret = ObGisTestFunc::geo_func::eval(gis_context, result); ASSERT_EQ(ret, OB_SUCCESS); ASSERT_EQ(result, -100); gis_context.ut_set_geo_arg(0, &gp); gis_context.ut_set_geo_arg(1, &ga); ret = ObGisTestFunc::geo_func::eval(gis_context, result); ASSERT_EQ(ret, OB_SUCCESS); ASSERT_EQ(result, -400); gis_context.ut_set_geo_arg(0, &ga); gis_context.ut_set_geo_arg(1, &gp); ret = ObGisTestFunc::geo_func::eval(gis_context, result); ASSERT_EQ(ret, OB_SUCCESS); ASSERT_EQ(result, 400); // exception test gis_context.ut_set_geo_arg(0, &ga); gis_context.ut_set_geo_arg(1, &gl); ret = ObGisTestFunc::geo_func::eval(gis_context, result); ASSERT_EQ(ret, OB_ERR_BOOST_GEOMETRY_CENTROID_EXCEPTION); ASSERT_EQ(result, 777); gis_context.ut_set_geo_arg(0, &gl); gis_context.ut_set_geo_arg(1, &ga); ret = ObGisTestFunc::geo_func::eval(gis_context, result); ASSERT_EQ(ret, OB_ERR_BOOST_GEOMETRY_CENTROID_EXCEPTION); ASSERT_EQ(result, 666); } } // namespace sql } // namespace oceanbase int main(int argc, char** argv) { ::testing::InitGoogleTest(&argc, argv); /* system("rm -f test_gis_dispatcher.log"); OB_LOGGER.set_file_name("test_json_bin.log"); OB_LOGGER.set_log_level("INFO"); */ return RUN_ALL_TESTS(); }