diff --git a/contrib/babelfishpg_common/Makefile b/contrib/babelfishpg_common/Makefile index 3512f4ba32..21c47f2e59 100644 --- a/contrib/babelfishpg_common/Makefile +++ b/contrib/babelfishpg_common/Makefile @@ -52,7 +52,8 @@ include $(PGXS) MODULEPATH = $$libdir/$(EXTENSION)-$(BBFPGCMN_MAJOR_VERSION) -UPGRADES = $(patsubst sql/upgrades/%.sql,sql/%.sql,$(wildcard sql/upgrades/*.sql)) +UPGRADES = $(patsubst sql/upgrades/babelfishpg_common--%.sql,sql/babelfishpg_common--%.sql,$(wildcard sql/upgrades/babelfishpg_common--*.sql)) +GENERATED_UPGRADES = sql/$(EXTENSION)--3.2.0--3.3.0.sql ifdef PREV_EXTVERSION DATA = sql/$(EXTENSION)--$(PREV_EXTVERSION).sql @@ -60,7 +61,8 @@ endif DATA_built = \ $(EXTENSION).control \ - sql/$(EXTENSION)--$(EXTVERSION).sql $(UPGRADES) + sql/$(EXTENSION)--$(EXTVERSION).sql $(UPGRADES) \ + $(GENERATED_UPGRADES) #include ../Makefile.common @@ -78,7 +80,7 @@ include $(PGXS) ifeq ($(GE91),yes) all: sql/$(EXTENSION)--$(EXTVERSION).sql $(UPGRADES) -all: sql/upgrades/$(EXTENSION)--3.2.0--3.3.0.sql sql/upgrades/babelfishpg_upgrades.in +all: $(GENERATED_UPGRADES) endif $(EXTENSION).control: $(EXTENSION).control.in @@ -96,18 +98,18 @@ ifeq (,$(filter $(FLAG_TO_CHECK),$(PG_CPPFLAGS))) sql/$(EXTENSION)--$(EXTVERSION).sql: sql/$(EXTENSION).in cpp $< | sed 's/^# /-- /g' > $@ - sql/upgrades/$(EXTENSION)--3.2.0--3.3.0.sql: sql/upgrades/babelfishpg_upgrades.in + sql/$(EXTENSION)--3.2.0--3.3.0.sql: sql/upgrades/babelfishpg_upgrades.in cpp -D PREV_VERSION=3.2.0 -D CUR_VERSION=3.3.0 $< | sed 's/^# /-- /g' > $@ else # The flag is present build the .in file including the spatial type files sql/$(EXTENSION)--$(EXTVERSION).sql: sql/$(EXTENSION).in cpp -D ENABLE_SPATIAL_TYPES=1 $< | sed 's/^# /-- /g' > $@ - sql/upgrades/$(EXTENSION)--3.2.0--3.3.0.sql: sql/upgrades/babelfishpg_upgrades.in + sql/$(EXTENSION)--3.2.0--3.3.0.sql: sql/upgrades/babelfishpg_upgrades.in cpp -D ENABLE_SPATIAL_TYPES=1 -D PREV_VERSION=3.2.0 -D CUR_VERSION=3.3.0 $< | sed 's/^# /-- /g' > $@ endif -sql/%.sql: sql/upgrades/%.sql +sql/babelfishpg_common--%.sql: sql/upgrades/babelfishpg_common--%.sql cp $< $@ diff --git a/contrib/babelfishpg_common/sql/geography.sql b/contrib/babelfishpg_common/sql/geography.sql index 451b5a84b2..b79eb1493b 100644 --- a/contrib/babelfishpg_common/sql/geography.sql +++ b/contrib/babelfishpg_common/sql/geography.sql @@ -55,18 +55,127 @@ CREATE OR REPLACE FUNCTION sys.GEOGRAPHY(sys.GEOGRAPHY, integer, boolean) CREATE CAST (sys.GEOGRAPHY AS sys.GEOGRAPHY) WITH FUNCTION sys.GEOGRAPHY(sys.GEOGRAPHY, integer, boolean) AS IMPLICIT; +CREATE OR REPLACE FUNCTION sys.get_valid_srids() + RETURNS integer[] + AS $$ + DECLARE + valid_srids integer[] := ARRAY[ + 4120, 4121, 4122, 4123, 4124, 4127, 4128, 4129, 4130, 4131, 4132, 4133, 4134, 4135, 4136, 4137, 4138, 4139, 4141, + 4142, 4143, 4144, 4145, 4146, 4147, 4148, 4149, 4150, 4151, 4152, 4153, 4154, 4155, 4156, 4157, 4158, 4159, 4160, + 4161, 4162, 4163, 4164, 4165, 4166, 4167, 4168, 4169, 4170, 4171, 4173, 4174, 4175, 4176, 4178, 4179, 4180, 4181, + 4182, 4183, 4184, 4188, 4189, 4190, 4191, 4192, 4193, 4194, 4195, 4196, 4197, 4198, 4199, 4200, 4201, 4202, 4203, + 4204, 4205, 4206, 4207, 4208, 4209, 4210, 4211, 4212, 4213, 4214, 4215, 4216, 4218, 4219, 4220, 4221, 4222, 4223, + 4224, 4225, 4227, 4229, 4230, 4231, 4232, 4236, 4237, 4238, 4239, 4240, 4241, 4242, 4243, 4244, 4245, 4246, 4247, + 4248, 4249, 4250, 4251, 4252, 4253, 4254, 4255, 4256, 4257, 4258, 4259, 4261, 4262, 4263, 4265, 4266, 4267, 4268, + 4269, 4270, 4271, 4272, 4273, 4274, 4275, 4276, 4277, 4278, 4279, 4280, 4281, 4282, 4283, 4284, 4285, 4286, 4288, + 4289, 4292, 4293, 4295, 4297, 4298, 4299, 4300, 4301, 4302, 4303, 4304, 4306, 4307, 4308, 4309, 4310, 4311, 4312, + 4313, 4314, 4315, 4316, 4317, 4318, 4319, 4322, 4324, 4326, 4600, 4601, 4602, 4603, 4604, 4605, 4606, 4607, 4608, + 4609, 4610, 4611, 4612, 4613, 4614, 4615, 4616, 4617, 4618, 4619, 4620, 4621, 4622, 4623, 4624, 4625, 4626, 4627, + 4628, 4629, 4630, 4632, 4633, 4636, 4637, 4638, 4639, 4640, 4641, 4642, 4643, 4644, 4646, 4657, 4658, 4659, 4660, + 4661, 4662, 4663, 4664, 4665, 4666, 4667, 4668, 4669, 4670, 4671, 4672, 4673, 4674, 4675, 4676, 4677, 4678, 4679, + 4680, 4682, 4683, 4684, 4686, 4687, 4688, 4689, 4690, 4691, 4692, 4693, 4694, 4695, 4696, 4697, 4698, 4699, 4700, + 4701, 4702, 4703, 4704, 4705, 4706, 4707, 4708, 4709, 4710, 4711, 4712, 4713, 4714, 4715, 4716, 4717, 4718, 4719, + 4720, 4721, 4722, 4723, 4724, 4725, 4726, 4727, 4728, 4729, 4730, 4732, 4733, 4734, 4735, 4736, 4737, 4738, 4739, + 4740, 4741, 4742, 4743, 4744, 4745, 4746, 4747, 4748, 4749, 4750, 4751, 4752, 4753, 4754, 4755, 4756, 4757, 4758, + 4801, 4802, 4803, 4804, 4805, 4806, 4807, 4808, 4809, 4810, 4811, 4813, 4814, 4815, 4816, 4817, 4818, 4820, 4821, + 4895, 4898, 4900, 4901, 4902, 4903, 4904, 4907, 4909, 4921, 4923, 4925, 4927, 4929, 4931, 4933, 4935, 4937, 4939, + 4941, 4943, 4945, 4947, 4949, 4951, 4953, 4955, 4957, 4959, 4961, 4963, 4965, 4967, 4971, 4973, 4975, 4977, 4979, + 4981, 4983, 4985, 4987, 4989, 4991, 4993, 4995, 4997, 4999, 7843, 7844, 104001 + ]; + BEGIN + RETURN valid_srids; + END; + $$ LANGUAGE plpgsql IMMUTABLE STRICT PARALLEL SAFE; + CREATE OR REPLACE FUNCTION sys.GEOGRAPHY(bytea) RETURNS sys.GEOGRAPHY - AS '$libdir/postgis-3','geography_from_binary' - LANGUAGE 'c' IMMUTABLE STRICT PARALLEL SAFE; + AS $$ + DECLARE + len integer; + varBin bytea; + geomType bytea; + srid integer; + newVarBin bytea; + lat float8; + byte_position integer := 6; + coord_NaN bytea := E'\\x000000000000f87f'; + input_coord bytea; + reversed_bytea bytea := E'\\x'; + i integer := 14; + isNaN integer = 0; + valid_srids integer[]; + BEGIN + -- Call the function to retrieve the valid SRIDs + SELECT sys.get_valid_srids() INTO valid_srids; + varBin := $1; + len := LENGTH(varBin); + IF len >= 22 THEN + -- General Logic: We are preprocessing it by removing 2 constant Geometry Type bytes -> 01 0c (for 2-D Point Type) Then adding 5 Bytes -> 01 (little endianess) + 4 Bytes (Geography Type). It is expected by the driver + -- Here we are calculating SRID which is initially in little endian order + srid := (get_byte(varBin, 3) << 24) | (get_byte(varBin, 2) << 16) | (get_byte(varBin, 1) << 8) | get_byte(varBin, 0); + -- Here we are calculating value of latitude which is initially in little endian order to check if it lies in the range [-90, 90] + WHILE i > 6 LOOP + reversed_bytea := reversed_bytea || substring(varBin from i for 1); + i = i - 1; + END LOOP; + lat := varbinaryfloat8(CAST (reversed_bytea AS bbf_varbinary)); + WHILE byte_position < len LOOP + -- Get the coordinate to check if it is NaN + input_coord := substring(varBin from byte_position + 1 for 8); + IF encode(input_coord, 'hex') = encode(coord_NaN, 'hex') THEN + isNaN := 1; + END IF; + byte_position := byte_position + 8; + END LOOP; + geomType := substring(varBin from 5 for 2); + varBin := substring(varBin from 1 for 4) || substring(varBin from 7); + IF srid = ANY(valid_srids) AND isNaN = 0 THEN + IF encode(geomType, 'hex') = encode(E'\\x010c', 'hex') THEN + IF lat >= -90.0 AND lat <= 90.0 THEN + newVarBin := E'\\x0101000020' || varBin; + ELSE + RAISE EXCEPTION 'Error converting data type varbinary to geography.'; + END IF; + ELSE + RAISE EXCEPTION 'Unsupported geometry type'; + END IF; + ELSE + RAISE EXCEPTION 'Error converting data type varbinary to geography.'; + END IF; + -- Call the underlying function after preprocessing + RETURN (SELECT sys.GEOGRAPHY_helper(newVarBin)); + ELSE + RAISE EXCEPTION 'Invalid Geography'; + END IF; + END; + $$ LANGUAGE plpgsql IMMUTABLE STRICT PARALLEL SAFE; CREATE OR REPLACE FUNCTION sys.bytea(sys.GEOGRAPHY) RETURNS bytea AS '$libdir/postgis-3','LWGEOM_to_bytea' LANGUAGE 'c' IMMUTABLE STRICT PARALLEL SAFE; +CREATE OR REPLACE FUNCTION sys.GEOGRAPHY(sys.bbf_varbinary) + RETURNS sys.GEOGRAPHY + AS $$ + DECLARE + varBin bytea; + BEGIN + varBin := (SELECT CAST ($1 AS bytea)); + -- Call the underlying function after preprocessing + RETURN (SELECT CAST (varBin AS GEOGRAPHY)); + END; + $$ LANGUAGE plpgsql IMMUTABLE STRICT PARALLEL SAFE; + +CREATE OR REPLACE FUNCTION sys.bbf_varbinary(sys.GEOGRAPHY) + RETURNS sys.bbf_varbinary + AS '$libdir/postgis-3','LWGEOM_to_bytea' + LANGUAGE 'c' IMMUTABLE STRICT PARALLEL SAFE; + CREATE CAST (bytea AS sys.GEOGRAPHY) WITH FUNCTION sys.GEOGRAPHY(bytea) AS IMPLICIT; CREATE CAST (sys.GEOGRAPHY AS bytea) WITH FUNCTION sys.bytea(sys.GEOGRAPHY) AS IMPLICIT; +CREATE CAST (sys.bbf_varbinary AS sys.GEOGRAPHY) WITH FUNCTION sys.GEOGRAPHY(sys.bbf_varbinary) AS IMPLICIT; +CREATE CAST (sys.GEOGRAPHY AS sys.bbf_varbinary) WITH FUNCTION sys.bbf_varbinary(sys.GEOGRAPHY) AS IMPLICIT; CREATE OR REPLACE FUNCTION sys.GEOGRAPHY(sys.GEOMETRY) RETURNS sys.GEOGRAPHY @@ -93,42 +202,34 @@ CREATE OR REPLACE FUNCTION sys.Geography__stgeomfromtext(text, integer) AS $$ DECLARE srid integer; - valid_srids integer[] := ARRAY[ - 4120, 4121, 4122, 4123, 4124, 4127, 4128, 4129, 4130, 4131, 4132, 4133, 4134, 4135, 4136, 4137, 4138, 4139, 4141, - 4142, 4143, 4144, 4145, 4146, 4147, 4148, 4149, 4150, 4151, 4152, 4153, 4154, 4155, 4156, 4157, 4158, 4159, 4160, - 4161, 4162, 4163, 4164, 4165, 4166, 4167, 4168, 4169, 4170, 4171, 4173, 4174, 4175, 4176, 4178, 4179, 4180, 4181, - 4182, 4183, 4184, 4188, 4189, 4190, 4191, 4192, 4193, 4194, 4195, 4196, 4197, 4198, 4199, 4200, 4201, 4202, 4203, - 4204, 4205, 4206, 4207, 4208, 4209, 4210, 4211, 4212, 4213, 4214, 4215, 4216, 4218, 4219, 4220, 4221, 4222, 4223, - 4224, 4225, 4227, 4229, 4230, 4231, 4232, 4236, 4237, 4238, 4239, 4240, 4241, 4242, 4243, 4244, 4245, 4246, 4247, - 4248, 4249, 4250, 4251, 4252, 4253, 4254, 4255, 4256, 4257, 4258, 4259, 4261, 4262, 4263, 4265, 4266, 4267, 4268, - 4269, 4270, 4271, 4272, 4273, 4274, 4275, 4276, 4277, 4278, 4279, 4280, 4281, 4282, 4283, 4284, 4285, 4286, 4288, - 4289, 4292, 4293, 4295, 4297, 4298, 4299, 4300, 4301, 4302, 4303, 4304, 4306, 4307, 4308, 4309, 4310, 4311, 4312, - 4313, 4314, 4315, 4316, 4317, 4318, 4319, 4322, 4324, 4326, 4600, 4601, 4602, 4603, 4604, 4605, 4606, 4607, 4608, - 4609, 4610, 4611, 4612, 4613, 4614, 4615, 4616, 4617, 4618, 4619, 4620, 4621, 4622, 4623, 4624, 4625, 4626, 4627, - 4628, 4629, 4630, 4632, 4633, 4636, 4637, 4638, 4639, 4640, 4641, 4642, 4643, 4644, 4646, 4657, 4658, 4659, 4660, - 4661, 4662, 4663, 4664, 4665, 4666, 4667, 4668, 4669, 4670, 4671, 4672, 4673, 4674, 4675, 4676, 4677, 4678, 4679, - 4680, 4682, 4683, 4684, 4686, 4687, 4688, 4689, 4690, 4691, 4692, 4693, 4694, 4695, 4696, 4697, 4698, 4699, 4700, - 4701, 4702, 4703, 4704, 4705, 4706, 4707, 4708, 4709, 4710, 4711, 4712, 4713, 4714, 4715, 4716, 4717, 4718, 4719, - 4720, 4721, 4722, 4723, 4724, 4725, 4726, 4727, 4728, 4729, 4730, 4732, 4733, 4734, 4735, 4736, 4737, 4738, 4739, - 4740, 4741, 4742, 4743, 4744, 4745, 4746, 4747, 4748, 4749, 4750, 4751, 4752, 4753, 4754, 4755, 4756, 4757, 4758, - 4801, 4802, 4803, 4804, 4805, 4806, 4807, 4808, 4809, 4810, 4811, 4813, 4814, 4815, 4816, 4817, 4818, 4820, 4821, - 4895, 4898, 4900, 4901, 4902, 4903, 4904, 4907, 4909, 4921, 4923, 4925, 4927, 4929, 4931, 4933, 4935, 4937, 4939, - 4941, 4943, 4945, 4947, 4949, 4951, 4953, 4955, 4957, 4959, 4961, 4963, 4965, 4967, 4971, 4973, 4975, 4977, 4979, - 4981, 4983, 4985, 4987, 4989, 4991, 4993, 4995, 4997, 4999, 7843, 7844, 104001 - ]; + Geomtype text; + geom sys.GEOGRAPHY; + valid_srids integer[]; lat float8; - BEGIN + BEGIN + -- Call the function to retrieve the valid SRIDs + SELECT sys.get_valid_srids() INTO valid_srids; srid := $2; - -- Here we're flipping the coordinates since Geography Datatype stores the point from STGeomFromText and STPointFromText in Reverse Order i.e. (long, lat) - lat = (SELECT sys.lat(sys.Geography__STFlipCoordinates(sys.stgeogfromtext_helper($1, $2)))); - IF srid = ANY(valid_srids) AND lat >= -90.0 AND lat <= 90.0 THEN - -- Call the underlying function after preprocessing - -- Here we're flipping the coordinates since Geography Datatype stores the point from STGeomFromText and STPointFromText in Reverse Order i.e. (long, lat) - RETURN (SELECT sys.Geography__STFlipCoordinates(sys.stgeogfromtext_helper($1, $2))); - ELSEIF lat < -90.0 OR lat > 90.0 THEN - RAISE EXCEPTION 'Latitude values must be between -90 and 90 degrees'; + -- Here we are flipping the coordinates since Geography Datatype stores the point from STGeomFromText and STPointFromText in Reverse Order i.e. (long, lat) + geom = (SELECT sys.stgeogfromtext_helper($1, $2)); + Geomtype = (SELECT sys.ST_GeometryType(geom)); + IF Geomtype = 'ST_Point' THEN + lat = (SELECT sys.lat(sys.Geography__STFlipCoordinates(sys.stgeogfromtext_helper($1, $2)))); + IF srid = ANY(valid_srids) AND lat >= -90.0 AND lat <= 90.0 THEN + -- Call the underlying function after preprocessing + -- Here we are flipping the coordinates since Geography Datatype stores the point from STGeomFromText and STPointFromText in Reverse Order i.e. (long, lat) + IF (SELECT sys.ST_Zmflag(geom)) = 1 OR (SELECT sys.ST_Zmflag(geom)) = 2 OR (SELECT sys.ST_Zmflag(geom)) = 3 THEN + RAISE EXCEPTION 'Unsupported flags'; + ELSE + RETURN (SELECT sys.Geography__STFlipCoordinates(geom)); + END IF; + ELSEIF lat < -90.0 OR lat > 90.0 THEN + RAISE EXCEPTION 'Latitude values must be between -90 and 90 degrees'; + ELSE + RAISE EXCEPTION 'Inavalid SRID'; + END IF; ELSE - RAISE EXCEPTION 'Inavalid SRID'; + RAISE EXCEPTION '% is not supported', Geomtype; END IF; END; $$ LANGUAGE plpgsql IMMUTABLE STRICT PARALLEL SAFE; @@ -138,7 +239,7 @@ CREATE OR REPLACE FUNCTION sys.STAsText(sys.GEOGRAPHY) AS $$ BEGIN -- Call the underlying function after preprocessing - -- Here we're flipping the coordinates since Geography Datatype stores the point from STGeomFromText and STPointFromText in Reverse Order i.e. (long, lat) + -- Here we are flipping the coordinates since Geography Datatype stores the point from STGeomFromText and STPointFromText in Reverse Order i.e. (long, lat) RETURN (SELECT sys.STAsText_helper(sys.Geography__STFlipCoordinates($1))); END; $$ LANGUAGE plpgsql IMMUTABLE STRICT PARALLEL SAFE; @@ -154,30 +255,10 @@ CREATE OR REPLACE FUNCTION sys.Geography__Point(float8, float8, srid integer) DECLARE srid integer; lat float8; - valid_srids integer[] := ARRAY[ - 4120, 4121, 4122, 4123, 4124, 4127, 4128, 4129, 4130, 4131, 4132, 4133, 4134, 4135, 4136, 4137, 4138, 4139, 4141, - 4142, 4143, 4144, 4145, 4146, 4147, 4148, 4149, 4150, 4151, 4152, 4153, 4154, 4155, 4156, 4157, 4158, 4159, 4160, - 4161, 4162, 4163, 4164, 4165, 4166, 4167, 4168, 4169, 4170, 4171, 4173, 4174, 4175, 4176, 4178, 4179, 4180, 4181, - 4182, 4183, 4184, 4188, 4189, 4190, 4191, 4192, 4193, 4194, 4195, 4196, 4197, 4198, 4199, 4200, 4201, 4202, 4203, - 4204, 4205, 4206, 4207, 4208, 4209, 4210, 4211, 4212, 4213, 4214, 4215, 4216, 4218, 4219, 4220, 4221, 4222, 4223, - 4224, 4225, 4227, 4229, 4230, 4231, 4232, 4236, 4237, 4238, 4239, 4240, 4241, 4242, 4243, 4244, 4245, 4246, 4247, - 4248, 4249, 4250, 4251, 4252, 4253, 4254, 4255, 4256, 4257, 4258, 4259, 4261, 4262, 4263, 4265, 4266, 4267, 4268, - 4269, 4270, 4271, 4272, 4273, 4274, 4275, 4276, 4277, 4278, 4279, 4280, 4281, 4282, 4283, 4284, 4285, 4286, 4288, - 4289, 4292, 4293, 4295, 4297, 4298, 4299, 4300, 4301, 4302, 4303, 4304, 4306, 4307, 4308, 4309, 4310, 4311, 4312, - 4313, 4314, 4315, 4316, 4317, 4318, 4319, 4322, 4324, 4326, 4600, 4601, 4602, 4603, 4604, 4605, 4606, 4607, 4608, - 4609, 4610, 4611, 4612, 4613, 4614, 4615, 4616, 4617, 4618, 4619, 4620, 4621, 4622, 4623, 4624, 4625, 4626, 4627, - 4628, 4629, 4630, 4632, 4633, 4636, 4637, 4638, 4639, 4640, 4641, 4642, 4643, 4644, 4646, 4657, 4658, 4659, 4660, - 4661, 4662, 4663, 4664, 4665, 4666, 4667, 4668, 4669, 4670, 4671, 4672, 4673, 4674, 4675, 4676, 4677, 4678, 4679, - 4680, 4682, 4683, 4684, 4686, 4687, 4688, 4689, 4690, 4691, 4692, 4693, 4694, 4695, 4696, 4697, 4698, 4699, 4700, - 4701, 4702, 4703, 4704, 4705, 4706, 4707, 4708, 4709, 4710, 4711, 4712, 4713, 4714, 4715, 4716, 4717, 4718, 4719, - 4720, 4721, 4722, 4723, 4724, 4725, 4726, 4727, 4728, 4729, 4730, 4732, 4733, 4734, 4735, 4736, 4737, 4738, 4739, - 4740, 4741, 4742, 4743, 4744, 4745, 4746, 4747, 4748, 4749, 4750, 4751, 4752, 4753, 4754, 4755, 4756, 4757, 4758, - 4801, 4802, 4803, 4804, 4805, 4806, 4807, 4808, 4809, 4810, 4811, 4813, 4814, 4815, 4816, 4817, 4818, 4820, 4821, - 4895, 4898, 4900, 4901, 4902, 4903, 4904, 4907, 4909, 4921, 4923, 4925, 4927, 4929, 4931, 4933, 4935, 4937, 4939, - 4941, 4943, 4945, 4947, 4949, 4951, 4953, 4955, 4957, 4959, 4961, 4963, 4965, 4967, 4971, 4973, 4975, 4977, 4979, - 4981, 4983, 4985, 4987, 4989, 4991, 4993, 4995, 4997, 4999, 7843, 7844, 104001 - ]; + valid_srids integer[]; BEGIN + -- Call the function to retrieve the valid SRIDs + SELECT sys.get_valid_srids() INTO valid_srids; srid := $3; lat := $1; IF srid = ANY(valid_srids) AND lat >= -90.0 AND lat <= 90.0 THEN @@ -196,7 +277,7 @@ CREATE OR REPLACE FUNCTION sys.STAsBinary(sys.GEOGRAPHY) AS $$ BEGIN -- Call the underlying function after preprocessing - -- Here we're flipping the coordinates since Geography Datatype stores the point from STGeomFromText and STPointFromText in Reverse Order i.e. (long, lat) + -- Here we are flipping the coordinates since Geography Datatype stores the point from STGeomFromText and STPointFromText in Reverse Order i.e. (long, lat) RETURN (SELECT sys.STAsBinary_helper(sys.Geography__STFlipCoordinates($1))); END; $$ LANGUAGE plpgsql IMMUTABLE STRICT PARALLEL SAFE; @@ -206,53 +287,55 @@ CREATE OR REPLACE FUNCTION sys.Geography__STPointFromText(text, integer) AS $$ DECLARE srid integer; - valid_srids integer[] := ARRAY[ - 4120, 4121, 4122, 4123, 4124, 4127, 4128, 4129, 4130, 4131, 4132, 4133, 4134, 4135, 4136, 4137, 4138, 4139, 4141, - 4142, 4143, 4144, 4145, 4146, 4147, 4148, 4149, 4150, 4151, 4152, 4153, 4154, 4155, 4156, 4157, 4158, 4159, 4160, - 4161, 4162, 4163, 4164, 4165, 4166, 4167, 4168, 4169, 4170, 4171, 4173, 4174, 4175, 4176, 4178, 4179, 4180, 4181, - 4182, 4183, 4184, 4188, 4189, 4190, 4191, 4192, 4193, 4194, 4195, 4196, 4197, 4198, 4199, 4200, 4201, 4202, 4203, - 4204, 4205, 4206, 4207, 4208, 4209, 4210, 4211, 4212, 4213, 4214, 4215, 4216, 4218, 4219, 4220, 4221, 4222, 4223, - 4224, 4225, 4227, 4229, 4230, 4231, 4232, 4236, 4237, 4238, 4239, 4240, 4241, 4242, 4243, 4244, 4245, 4246, 4247, - 4248, 4249, 4250, 4251, 4252, 4253, 4254, 4255, 4256, 4257, 4258, 4259, 4261, 4262, 4263, 4265, 4266, 4267, 4268, - 4269, 4270, 4271, 4272, 4273, 4274, 4275, 4276, 4277, 4278, 4279, 4280, 4281, 4282, 4283, 4284, 4285, 4286, 4288, - 4289, 4292, 4293, 4295, 4297, 4298, 4299, 4300, 4301, 4302, 4303, 4304, 4306, 4307, 4308, 4309, 4310, 4311, 4312, - 4313, 4314, 4315, 4316, 4317, 4318, 4319, 4322, 4324, 4326, 4600, 4601, 4602, 4603, 4604, 4605, 4606, 4607, 4608, - 4609, 4610, 4611, 4612, 4613, 4614, 4615, 4616, 4617, 4618, 4619, 4620, 4621, 4622, 4623, 4624, 4625, 4626, 4627, - 4628, 4629, 4630, 4632, 4633, 4636, 4637, 4638, 4639, 4640, 4641, 4642, 4643, 4644, 4646, 4657, 4658, 4659, 4660, - 4661, 4662, 4663, 4664, 4665, 4666, 4667, 4668, 4669, 4670, 4671, 4672, 4673, 4674, 4675, 4676, 4677, 4678, 4679, - 4680, 4682, 4683, 4684, 4686, 4687, 4688, 4689, 4690, 4691, 4692, 4693, 4694, 4695, 4696, 4697, 4698, 4699, 4700, - 4701, 4702, 4703, 4704, 4705, 4706, 4707, 4708, 4709, 4710, 4711, 4712, 4713, 4714, 4715, 4716, 4717, 4718, 4719, - 4720, 4721, 4722, 4723, 4724, 4725, 4726, 4727, 4728, 4729, 4730, 4732, 4733, 4734, 4735, 4736, 4737, 4738, 4739, - 4740, 4741, 4742, 4743, 4744, 4745, 4746, 4747, 4748, 4749, 4750, 4751, 4752, 4753, 4754, 4755, 4756, 4757, 4758, - 4801, 4802, 4803, 4804, 4805, 4806, 4807, 4808, 4809, 4810, 4811, 4813, 4814, 4815, 4816, 4817, 4818, 4820, 4821, - 4895, 4898, 4900, 4901, 4902, 4903, 4904, 4907, 4909, 4921, 4923, 4925, 4927, 4929, 4931, 4933, 4935, 4937, 4939, - 4941, 4943, 4945, 4947, 4949, 4951, 4953, 4955, 4957, 4959, 4961, 4963, 4965, 4967, 4971, 4973, 4975, 4977, 4979, - 4981, 4983, 4985, 4987, 4989, 4991, 4993, 4995, 4997, 4999, 7843, 7844, 104001 - ]; + Geomtype text; + geom sys.GEOGRAPHY; + valid_srids integer[]; lat float8; BEGIN + -- Call the function to retrieve the valid SRIDs + SELECT sys.get_valid_srids() INTO valid_srids; srid := $2; - -- Here we're flipping the coordinates since Geography Datatype stores the point from STGeomFromText and STPointFromText in Reverse Order i.e. (long, lat) - lat = (SELECT sys.lat(sys.Geography__STFlipCoordinates(sys.stgeogfromtext_helper($1, $2)))); - IF srid = ANY(valid_srids) AND lat >= -90.0 AND lat <= 90.0 THEN - -- Call the underlying function after preprocessing - -- Here we're flipping the coordinates since Geography Datatype stores the point from STGeomFromText and STPointFromText in Reverse Order i.e. (long, lat) - RETURN (SELECT sys.Geography__STFlipCoordinates(sys.stgeogfromtext_helper($1, $2))); - ELSEIF lat < -90.0 OR lat > 90.0 THEN - RAISE EXCEPTION 'Latitude values must be between -90 and 90 degrees'; + -- Here we are flipping the coordinates since Geography Datatype stores the point from STGeomFromText and STPointFromText in Reverse Order i.e. (long, lat) + geom = (SELECT sys.stgeogfromtext_helper($1, $2)); + Geomtype = (SELECT sys.ST_GeometryType(geom)); + IF Geomtype = 'ST_Point' THEN + lat = (SELECT sys.lat(sys.Geography__STFlipCoordinates(sys.stgeogfromtext_helper($1, $2)))); + IF srid = ANY(valid_srids) AND lat >= -90.0 AND lat <= 90.0 THEN + -- Call the underlying function after preprocessing + -- Here we are flipping the coordinates since Geography Datatype stores the point from STGeomFromText and STPointFromText in Reverse Order i.e. (long, lat) + IF (SELECT sys.ST_Zmflag(geom)) = 1 OR (SELECT sys.ST_Zmflag(geom)) = 2 OR (SELECT sys.ST_Zmflag(geom)) = 3 THEN + RAISE EXCEPTION 'Unsupported flags'; + ELSE + RETURN (SELECT sys.Geography__STFlipCoordinates(geom)); + END IF; + ELSEIF lat < -90.0 OR lat > 90.0 THEN + RAISE EXCEPTION 'Latitude values must be between -90 and 90 degrees'; + ELSE + RAISE EXCEPTION 'Inavalid SRID'; + END IF; ELSE - RAISE EXCEPTION 'Inavalid SRID'; + RAISE EXCEPTION '% is not supported', Geomtype; END IF; END; $$ LANGUAGE plpgsql IMMUTABLE STRICT PARALLEL SAFE; +CREATE OR REPLACE FUNCTION sys.ST_GeometryType(sys.GEOGRAPHY) + RETURNS text + AS '$libdir/postgis-3', 'geometry_geometrytype' + LANGUAGE 'c' IMMUTABLE STRICT PARALLEL SAFE; + +CREATE OR REPLACE FUNCTION sys.ST_zmflag(sys.GEOGRAPHY) + RETURNS smallint + AS '$libdir/postgis-3', 'LWGEOM_zmflag' + LANGUAGE 'c' IMMUTABLE STRICT PARALLEL SAFE; + -- Minimum distance CREATE OR REPLACE FUNCTION sys.STDistance(geog1 sys.GEOGRAPHY, geog2 sys.GEOGRAPHY) RETURNS float8 AS $$ BEGIN -- Call the underlying function after preprocessing - -- Here we're flipping the coordinates since Geography Datatype stores the point from STGeomFromText and STPointFromText in Reverse Order i.e. (long, lat) + -- Here we are flipping the coordinates since Geography Datatype stores the point from STGeomFromText and STPointFromText in Reverse Order i.e. (long, lat) RETURN (SELECT sys.STDistance_helper(sys.Geography__STFlipCoordinates($1), sys.Geography__STFlipCoordinates($2))); END; $$ LANGUAGE plpgsql IMMUTABLE STRICT PARALLEL SAFE; @@ -298,3 +381,8 @@ CREATE OR REPLACE FUNCTION sys.STDistance_helper(geog1 sys.GEOGRAPHY, geog2 sys. AS '$libdir/postgis-3', 'LWGEOM_distance_ellipsoid' LANGUAGE 'c' IMMUTABLE STRICT PARALLEL SAFE; +CREATE OR REPLACE FUNCTION sys.GEOGRAPHY_helper(bytea) + RETURNS sys.GEOGRAPHY + AS '$libdir/postgis-3','geography_from_binary' + LANGUAGE 'c' IMMUTABLE STRICT PARALLEL SAFE; + diff --git a/contrib/babelfishpg_common/sql/geometry.sql b/contrib/babelfishpg_common/sql/geometry.sql index 82c8e6e81a..1f7772b3ed 100644 --- a/contrib/babelfishpg_common/sql/geometry.sql +++ b/contrib/babelfishpg_common/sql/geometry.sql @@ -73,11 +73,23 @@ CREATE OR REPLACE FUNCTION sys.Geometry__stgeomfromtext(text, integer) AS $$ DECLARE srid integer; + Geomtype text; + geom sys.GEOMETRY; BEGIN srid := $2; IF srid >= 0 AND srid <= 999999 THEN -- Call the underlying function after preprocessing - RETURN (SELECT sys.stgeomfromtext_helper($1, $2)); + geom = (SELECT sys.stgeomfromtext_helper($1, $2)); + Geomtype = (SELECT sys.ST_GeometryType(geom)); + IF Geomtype = 'ST_Point' THEN + IF (SELECT sys.ST_Zmflag(geom)) = 1 OR (SELECT sys.ST_Zmflag(geom)) = 2 OR (SELECT sys.ST_Zmflag(geom)) = 3 THEN + RAISE EXCEPTION 'Unsupported flags'; + ELSE + RETURN geom; + END IF; + ELSE + RAISE EXCEPTION '% is not supported', Geomtype; + END IF; ELSE RAISE EXCEPTION 'SRID value should be between 0 and 999999'; END IF; @@ -96,15 +108,74 @@ CREATE OR REPLACE FUNCTION sys.text(sys.GEOMETRY) LANGUAGE 'c' IMMUTABLE STRICT PARALLEL SAFE; CREATE OR REPLACE FUNCTION sys.GEOMETRY(bytea) - RETURNS sys.GEOMETRY - AS '$libdir/postgis-3','LWGEOM_from_bytea' - LANGUAGE 'c' IMMUTABLE STRICT PARALLEL SAFE; + RETURNS sys.GEOMETRY + AS $$ + DECLARE + len integer; + varBin bytea; + geomType bytea; + srid integer; + byte_position integer := 6; + coord_NaN bytea := E'\\x000000000000f87f'; + input_coord bytea; + isNaN integer = 0; + newVarBin bytea; + BEGIN + varBin := $1; + len := LENGTH(varBin); + IF len >= 22 THEN + -- We are preprocessing it by removing 2 constant Geometry Type bytes -> 01 0c (for 2-D Point Type) + -- Then adding 5 Bytes -> 01 (little endianess) + 4 Bytes (Geometry Type) + srid := (get_byte(varBin, 3) << 24) | (get_byte(varBin, 2) << 16) | (get_byte(varBin, 1) << 8) | get_byte(varBin, 0); + WHILE byte_position < len LOOP + -- Get the coordinate to check if it is NaN + input_coord := substring(varBin from byte_position + 1 for 8); + IF encode(input_coord, 'hex') = encode(coord_NaN, 'hex') THEN + isNaN := 1; + END IF; + byte_position := byte_position + 8; + END LOOP; + geomType := substring(varBin from 5 for 2); + varBin := substring(varBin from 1 for 4) || substring(varBin from 7); + IF srid >= 0 AND srid <= 999999 AND isNaN = 0 THEN + IF encode(geomType, 'hex') = encode(E'\\x010c', 'hex') THEN + newVarBin := E'\\x0101000020' || varBin; + ELSE + RAISE EXCEPTION 'Unsupported geometry type'; + END IF; + ELSE + RAISE EXCEPTION 'Error converting data type varbinary to geometry.'; + END IF; + -- Call the underlying function after preprocessing + RETURN (SELECT sys.GEOMETRY_helper(newVarBin)); + ELSE + RAISE EXCEPTION 'Invalid Geometry'; + END IF; + END; + $$ LANGUAGE plpgsql IMMUTABLE STRICT PARALLEL SAFE; CREATE OR REPLACE FUNCTION sys.bytea(sys.GEOMETRY) RETURNS bytea AS '$libdir/postgis-3','LWGEOM_to_bytea' LANGUAGE 'c' IMMUTABLE STRICT PARALLEL SAFE; +CREATE OR REPLACE FUNCTION sys.GEOMETRY(sys.bbf_varbinary) + RETURNS sys.GEOMETRY + AS $$ + DECLARE + varBin bytea; + BEGIN + varBin := (SELECT CAST ($1 AS bytea)); + -- Call the underlying function after preprocessing + RETURN (SELECT CAST (varBin AS GEOMETRY)); + END; + $$ LANGUAGE plpgsql IMMUTABLE STRICT PARALLEL SAFE; + +CREATE OR REPLACE FUNCTION sys.bbf_varbinary(sys.GEOMETRY) + RETURNS sys.bbf_varbinary + AS '$libdir/postgis-3','LWGEOM_to_bytea' + LANGUAGE 'c' IMMUTABLE STRICT PARALLEL SAFE; + CREATE OR REPLACE FUNCTION sys.GEOMETRY(text) RETURNS sys.GEOMETRY AS '$libdir/postgis-3','parse_WKT_lwgeom' @@ -114,6 +185,8 @@ CREATE CAST (text AS sys.GEOMETRY) WITH FUNCTION sys.GEOMETRY(text) AS IMPLICIT; CREATE CAST (sys.GEOMETRY AS text) WITH FUNCTION sys.text(sys.GEOMETRY) AS IMPLICIT; CREATE CAST (bytea AS sys.GEOMETRY) WITH FUNCTION sys.GEOMETRY(bytea) AS IMPLICIT; CREATE CAST (sys.GEOMETRY AS bytea) WITH FUNCTION sys.bytea(sys.GEOMETRY) AS IMPLICIT; +CREATE CAST (sys.bbf_varbinary AS sys.GEOMETRY) WITH FUNCTION sys.GEOMETRY(sys.bbf_varbinary) AS IMPLICIT; +CREATE CAST (sys.GEOMETRY AS sys.bbf_varbinary) WITH FUNCTION sys.bbf_varbinary(sys.GEOMETRY) AS IMPLICIT; -- Availability: 3.2.0 current supported in APG CREATE OR REPLACE FUNCTION sys.Geometry__Point(float8, float8, srid integer) @@ -142,17 +215,39 @@ CREATE OR REPLACE FUNCTION sys.Geometry__STPointFromText(text, integer) AS $$ DECLARE srid integer; + Geomtype text; + geom sys.GEOMETRY; BEGIN srid := $2; IF srid >= 0 AND srid <= 999999 THEN -- Call the underlying function after preprocessing - RETURN (SELECT sys.stgeomfromtext_helper($1, $2)); + geom = (SELECT sys.stgeomfromtext_helper($1, $2)); + Geomtype = (SELECT sys.ST_GeometryType(geom)); + IF Geomtype = 'ST_Point' THEN + IF (SELECT sys.ST_Zmflag(geom)) = 1 OR (SELECT sys.ST_Zmflag(geom)) = 2 OR (SELECT sys.ST_Zmflag(geom)) = 3 THEN + RAISE EXCEPTION 'Unsupported flags'; + ELSE + RETURN geom; + END IF; + ELSE + RAISE EXCEPTION '% is not supported', Geomtype; + END IF; ELSE RAISE EXCEPTION 'SRID value should be between 0 and 999999'; END IF; END; $$ LANGUAGE plpgsql IMMUTABLE STRICT PARALLEL SAFE; +CREATE OR REPLACE FUNCTION sys.ST_GeometryType(sys.GEOMETRY) + RETURNS text + AS '$libdir/postgis-3', 'geometry_geometrytype' + LANGUAGE 'c' IMMUTABLE STRICT PARALLEL SAFE; + +CREATE OR REPLACE FUNCTION sys.ST_zmflag(sys.GEOMETRY) + RETURNS smallint + AS '$libdir/postgis-3', 'LWGEOM_zmflag' + LANGUAGE 'c' IMMUTABLE STRICT PARALLEL SAFE; + -- Minimum distance. 2D only. CREATE OR REPLACE FUNCTION sys.STDistance(geom1 sys.GEOMETRY, geom2 sys.GEOMETRY) RETURNS float8 @@ -180,3 +275,8 @@ CREATE OR REPLACE FUNCTION sys.GeomPoint_helper(float8, float8, srid integer) AS '$libdir/postgis-3', 'ST_Point' LANGUAGE 'c' IMMUTABLE STRICT PARALLEL SAFE; +CREATE OR REPLACE FUNCTION sys.GEOMETRY_helper(bytea) + RETURNS sys.GEOMETRY + AS '$libdir/postgis-3','LWGEOM_from_bytea' + LANGUAGE 'c' IMMUTABLE STRICT PARALLEL SAFE; + diff --git a/contrib/babelfishpg_common/sql/upgrades/spatial_types--3.2.0--3.3.0.sql b/contrib/babelfishpg_common/sql/upgrades/spatial_types--3.2.0--3.3.0.sql index 0e5755a0ad..d50f098ab9 100644 --- a/contrib/babelfishpg_common/sql/upgrades/spatial_types--3.2.0--3.3.0.sql +++ b/contrib/babelfishpg_common/sql/upgrades/spatial_types--3.2.0--3.3.0.sql @@ -77,11 +77,23 @@ CREATE OR REPLACE FUNCTION sys.Geometry__stgeomfromtext(text, integer) AS $$ DECLARE srid integer; + Geomtype text; + geom sys.GEOMETRY; BEGIN srid := $2; IF srid >= 0 AND srid <= 999999 THEN -- Call the underlying function after preprocessing - RETURN (SELECT sys.stgeomfromtext_helper($1, $2)); + geom = (SELECT sys.stgeomfromtext_helper($1, $2)); + Geomtype = (SELECT sys.ST_GeometryType(geom)); + IF Geomtype = 'ST_Point' THEN + IF (SELECT sys.ST_Zmflag(geom)) = 1 OR (SELECT sys.ST_Zmflag(geom)) = 2 OR (SELECT sys.ST_Zmflag(geom)) = 3 THEN + RAISE EXCEPTION 'Unsupported flags'; + ELSE + RETURN geom; + END IF; + ELSE + RAISE EXCEPTION '% is not supported', Geomtype; + END IF; ELSE RAISE EXCEPTION 'SRID value should be between 0 and 999999'; END IF; @@ -100,15 +112,74 @@ CREATE OR REPLACE FUNCTION sys.text(sys.GEOMETRY) LANGUAGE 'c' IMMUTABLE STRICT PARALLEL SAFE; CREATE OR REPLACE FUNCTION sys.GEOMETRY(bytea) - RETURNS sys.GEOMETRY - AS '$libdir/postgis-3','LWGEOM_from_bytea' - LANGUAGE 'c' IMMUTABLE STRICT PARALLEL SAFE; + RETURNS sys.GEOMETRY + AS $$ + DECLARE + len integer; + varBin bytea; + geomType bytea; + srid integer; + byte_position integer := 6; + coord_NaN bytea := E'\\x000000000000f87f'; + input_coord bytea; + isNaN integer = 0; + newVarBin bytea; + BEGIN + varBin := $1; + len := LENGTH(varBin); + IF len >= 22 THEN + -- We are preprocessing it by removing 2 constant Geometry Type bytes -> 01 0c (for 2-D Point Type) + -- Then adding 5 Bytes -> 01 (little endianess) + 4 Bytes (Geometry Type) + srid := (get_byte(varBin, 3) << 24) | (get_byte(varBin, 2) << 16) | (get_byte(varBin, 1) << 8) | get_byte(varBin, 0); + WHILE byte_position < len LOOP + -- Get the coordinate to check if it is NaN + input_coord := substring(varBin from byte_position + 1 for 8); + IF encode(input_coord, 'hex') = encode(coord_NaN, 'hex') THEN + isNaN := 1; + END IF; + byte_position := byte_position + 8; + END LOOP; + geomType := substring(varBin from 5 for 2); + varBin := substring(varBin from 1 for 4) || substring(varBin from 7); + IF srid >= 0 AND srid <= 999999 AND isNaN = 0 THEN + IF encode(geomType, 'hex') = encode(E'\\x010c', 'hex') THEN + newVarBin := E'\\x0101000020' || varBin; + ELSE + RAISE EXCEPTION 'Unsupported geometry type'; + END IF; + ELSE + RAISE EXCEPTION 'Error converting data type varbinary to geometry.'; + END IF; + -- Call the underlying function after preprocessing + RETURN (SELECT sys.GEOMETRY_helper(newVarBin)); + ELSE + RAISE EXCEPTION 'Invalid Geometry'; + END IF; + END; + $$ LANGUAGE plpgsql IMMUTABLE STRICT PARALLEL SAFE; CREATE OR REPLACE FUNCTION sys.bytea(sys.GEOMETRY) RETURNS bytea AS '$libdir/postgis-3','LWGEOM_to_bytea' LANGUAGE 'c' IMMUTABLE STRICT PARALLEL SAFE; +CREATE OR REPLACE FUNCTION sys.GEOMETRY(sys.bbf_varbinary) + RETURNS sys.GEOMETRY + AS $$ + DECLARE + varBin bytea; + BEGIN + varBin := (SELECT CAST ($1 AS bytea)); + -- Call the underlying function after preprocessing + RETURN (SELECT CAST (varBin AS GEOMETRY)); + END; + $$ LANGUAGE plpgsql IMMUTABLE STRICT PARALLEL SAFE; + +CREATE OR REPLACE FUNCTION sys.bbf_varbinary(sys.GEOMETRY) + RETURNS sys.bbf_varbinary + AS '$libdir/postgis-3','LWGEOM_to_bytea' + LANGUAGE 'c' IMMUTABLE STRICT PARALLEL SAFE; + CREATE OR REPLACE FUNCTION sys.GEOMETRY(text) RETURNS sys.GEOMETRY AS '$libdir/postgis-3','parse_WKT_lwgeom' @@ -118,6 +189,8 @@ CREATE CAST (text AS sys.GEOMETRY) WITH FUNCTION sys.GEOMETRY(text) AS IMPLICIT; CREATE CAST (sys.GEOMETRY AS text) WITH FUNCTION sys.text(sys.GEOMETRY) AS IMPLICIT; CREATE CAST (bytea AS sys.GEOMETRY) WITH FUNCTION sys.GEOMETRY(bytea) AS IMPLICIT; CREATE CAST (sys.GEOMETRY AS bytea) WITH FUNCTION sys.bytea(sys.GEOMETRY) AS IMPLICIT; +CREATE CAST (sys.bbf_varbinary AS sys.GEOMETRY) WITH FUNCTION sys.GEOMETRY(sys.bbf_varbinary) AS IMPLICIT; +CREATE CAST (sys.GEOMETRY AS sys.bbf_varbinary) WITH FUNCTION sys.bbf_varbinary(sys.GEOMETRY) AS IMPLICIT; -- Availability: 3.2.0 current supported in APG CREATE OR REPLACE FUNCTION sys.Geometry__Point(float8, float8, srid integer) @@ -146,17 +219,39 @@ CREATE OR REPLACE FUNCTION sys.Geometry__STPointFromText(text, integer) AS $$ DECLARE srid integer; + Geomtype text; + geom sys.GEOMETRY; BEGIN srid := $2; IF srid >= 0 AND srid <= 999999 THEN -- Call the underlying function after preprocessing - RETURN (SELECT sys.stgeomfromtext_helper($1, $2)); + geom = (SELECT sys.stgeomfromtext_helper($1, $2)); + Geomtype = (SELECT sys.ST_GeometryType(geom)); + IF Geomtype = 'ST_Point' THEN + IF (SELECT sys.ST_Zmflag(geom)) = 1 OR (SELECT sys.ST_Zmflag(geom)) = 2 OR (SELECT sys.ST_Zmflag(geom)) = 3 THEN + RAISE EXCEPTION 'Unsupported flags'; + ELSE + RETURN geom; + END IF; + ELSE + RAISE EXCEPTION '% is not supported', Geomtype; + END IF; ELSE RAISE EXCEPTION 'SRID value should be between 0 and 999999'; END IF; END; $$ LANGUAGE plpgsql IMMUTABLE STRICT PARALLEL SAFE; +CREATE OR REPLACE FUNCTION sys.ST_GeometryType(sys.GEOMETRY) + RETURNS text + AS '$libdir/postgis-3', 'geometry_geometrytype' + LANGUAGE 'c' IMMUTABLE STRICT PARALLEL SAFE; + +CREATE OR REPLACE FUNCTION sys.ST_zmflag(sys.GEOMETRY) + RETURNS smallint + AS '$libdir/postgis-3', 'LWGEOM_zmflag' + LANGUAGE 'c' IMMUTABLE STRICT PARALLEL SAFE; + -- Minimum distance. 2D only. CREATE OR REPLACE FUNCTION sys.STDistance(geom1 sys.GEOMETRY, geom2 sys.GEOMETRY) RETURNS float8 @@ -183,7 +278,12 @@ CREATE OR REPLACE FUNCTION sys.GeomPoint_helper(float8, float8, srid integer) RETURNS sys.GEOMETRY AS '$libdir/postgis-3', 'ST_Point' LANGUAGE 'c' IMMUTABLE STRICT PARALLEL SAFE; - + +CREATE OR REPLACE FUNCTION sys.GEOMETRY_helper(bytea) + RETURNS sys.GEOMETRY + AS '$libdir/postgis-3','LWGEOM_from_bytea' + LANGUAGE 'c' IMMUTABLE STRICT PARALLEL SAFE; + CREATE OR REPLACE FUNCTION sys.geographyin(cstring, oid, integer) RETURNS sys.GEOGRAPHY AS '$libdir/postgis-3','geography_in' @@ -241,18 +341,127 @@ CREATE OR REPLACE FUNCTION sys.GEOGRAPHY(sys.GEOGRAPHY, integer, boolean) CREATE CAST (sys.GEOGRAPHY AS sys.GEOGRAPHY) WITH FUNCTION sys.GEOGRAPHY(sys.GEOGRAPHY, integer, boolean) AS IMPLICIT; +CREATE OR REPLACE FUNCTION sys.get_valid_srids() + RETURNS integer[] + AS $$ + DECLARE + valid_srids integer[] := ARRAY[ + 4120, 4121, 4122, 4123, 4124, 4127, 4128, 4129, 4130, 4131, 4132, 4133, 4134, 4135, 4136, 4137, 4138, 4139, 4141, + 4142, 4143, 4144, 4145, 4146, 4147, 4148, 4149, 4150, 4151, 4152, 4153, 4154, 4155, 4156, 4157, 4158, 4159, 4160, + 4161, 4162, 4163, 4164, 4165, 4166, 4167, 4168, 4169, 4170, 4171, 4173, 4174, 4175, 4176, 4178, 4179, 4180, 4181, + 4182, 4183, 4184, 4188, 4189, 4190, 4191, 4192, 4193, 4194, 4195, 4196, 4197, 4198, 4199, 4200, 4201, 4202, 4203, + 4204, 4205, 4206, 4207, 4208, 4209, 4210, 4211, 4212, 4213, 4214, 4215, 4216, 4218, 4219, 4220, 4221, 4222, 4223, + 4224, 4225, 4227, 4229, 4230, 4231, 4232, 4236, 4237, 4238, 4239, 4240, 4241, 4242, 4243, 4244, 4245, 4246, 4247, + 4248, 4249, 4250, 4251, 4252, 4253, 4254, 4255, 4256, 4257, 4258, 4259, 4261, 4262, 4263, 4265, 4266, 4267, 4268, + 4269, 4270, 4271, 4272, 4273, 4274, 4275, 4276, 4277, 4278, 4279, 4280, 4281, 4282, 4283, 4284, 4285, 4286, 4288, + 4289, 4292, 4293, 4295, 4297, 4298, 4299, 4300, 4301, 4302, 4303, 4304, 4306, 4307, 4308, 4309, 4310, 4311, 4312, + 4313, 4314, 4315, 4316, 4317, 4318, 4319, 4322, 4324, 4326, 4600, 4601, 4602, 4603, 4604, 4605, 4606, 4607, 4608, + 4609, 4610, 4611, 4612, 4613, 4614, 4615, 4616, 4617, 4618, 4619, 4620, 4621, 4622, 4623, 4624, 4625, 4626, 4627, + 4628, 4629, 4630, 4632, 4633, 4636, 4637, 4638, 4639, 4640, 4641, 4642, 4643, 4644, 4646, 4657, 4658, 4659, 4660, + 4661, 4662, 4663, 4664, 4665, 4666, 4667, 4668, 4669, 4670, 4671, 4672, 4673, 4674, 4675, 4676, 4677, 4678, 4679, + 4680, 4682, 4683, 4684, 4686, 4687, 4688, 4689, 4690, 4691, 4692, 4693, 4694, 4695, 4696, 4697, 4698, 4699, 4700, + 4701, 4702, 4703, 4704, 4705, 4706, 4707, 4708, 4709, 4710, 4711, 4712, 4713, 4714, 4715, 4716, 4717, 4718, 4719, + 4720, 4721, 4722, 4723, 4724, 4725, 4726, 4727, 4728, 4729, 4730, 4732, 4733, 4734, 4735, 4736, 4737, 4738, 4739, + 4740, 4741, 4742, 4743, 4744, 4745, 4746, 4747, 4748, 4749, 4750, 4751, 4752, 4753, 4754, 4755, 4756, 4757, 4758, + 4801, 4802, 4803, 4804, 4805, 4806, 4807, 4808, 4809, 4810, 4811, 4813, 4814, 4815, 4816, 4817, 4818, 4820, 4821, + 4895, 4898, 4900, 4901, 4902, 4903, 4904, 4907, 4909, 4921, 4923, 4925, 4927, 4929, 4931, 4933, 4935, 4937, 4939, + 4941, 4943, 4945, 4947, 4949, 4951, 4953, 4955, 4957, 4959, 4961, 4963, 4965, 4967, 4971, 4973, 4975, 4977, 4979, + 4981, 4983, 4985, 4987, 4989, 4991, 4993, 4995, 4997, 4999, 7843, 7844, 104001 + ]; + BEGIN + RETURN valid_srids; + END; + $$ LANGUAGE plpgsql IMMUTABLE STRICT PARALLEL SAFE; + CREATE OR REPLACE FUNCTION sys.GEOGRAPHY(bytea) RETURNS sys.GEOGRAPHY - AS '$libdir/postgis-3','geography_from_binary' - LANGUAGE 'c' IMMUTABLE STRICT PARALLEL SAFE; + AS $$ + DECLARE + len integer; + varBin bytea; + geomType bytea; + srid integer; + newVarBin bytea; + lat float8; + byte_position integer := 6; + coord_NaN bytea := E'\\x000000000000f87f'; + input_coord bytea; + reversed_bytea bytea := E'\\x'; + i integer := 14; + isNaN integer = 0; + valid_srids integer[]; + BEGIN + -- Call the function to retrieve the valid SRIDs + SELECT sys.get_valid_srids() INTO valid_srids; + varBin := $1; + len := LENGTH(varBin); + IF len >= 22 THEN + -- General Logic: We are preprocessing it by removing 2 constant Geometry Type bytes -> 01 0c (for 2-D Point Type) Then adding 5 Bytes -> 01 (little endianess) + 4 Bytes (Geography Type). It is expected by the driver + -- Here we are calculating SRID which is initially in little endian order + srid := (get_byte(varBin, 3) << 24) | (get_byte(varBin, 2) << 16) | (get_byte(varBin, 1) << 8) | get_byte(varBin, 0); + -- Here we are calculating value of latitude which is initially in little endian order to check if it lies in the range [-90, 90] + WHILE i > 6 LOOP + reversed_bytea := reversed_bytea || substring(varBin from i for 1); + i = i - 1; + END LOOP; + lat := varbinaryfloat8(CAST (reversed_bytea AS bbf_varbinary)); + WHILE byte_position < len LOOP + -- Get the coordinate to check if it is NaN + input_coord := substring(varBin from byte_position + 1 for 8); + IF encode(input_coord, 'hex') = encode(coord_NaN, 'hex') THEN + isNaN := 1; + END IF; + byte_position := byte_position + 8; + END LOOP; + geomType := substring(varBin from 5 for 2); + varBin := substring(varBin from 1 for 4) || substring(varBin from 7); + IF srid = ANY(valid_srids) AND isNaN = 0 THEN + IF encode(geomType, 'hex') = encode(E'\\x010c', 'hex') THEN + IF lat >= -90.0 AND lat <= 90.0 THEN + newVarBin := E'\\x0101000020' || varBin; + ELSE + RAISE EXCEPTION 'Error converting data type varbinary to geography.'; + END IF; + ELSE + RAISE EXCEPTION 'Unsupported geometry type'; + END IF; + ELSE + RAISE EXCEPTION 'Error converting data type varbinary to geography.'; + END IF; + -- Call the underlying function after preprocessing + RETURN (SELECT sys.GEOGRAPHY_helper(newVarBin)); + ELSE + RAISE EXCEPTION 'Invalid Geography'; + END IF; + END; + $$ LANGUAGE plpgsql IMMUTABLE STRICT PARALLEL SAFE; CREATE OR REPLACE FUNCTION sys.bytea(sys.GEOGRAPHY) RETURNS bytea AS '$libdir/postgis-3','LWGEOM_to_bytea' LANGUAGE 'c' IMMUTABLE STRICT PARALLEL SAFE; +CREATE OR REPLACE FUNCTION sys.GEOGRAPHY(sys.bbf_varbinary) + RETURNS sys.GEOGRAPHY + AS $$ + DECLARE + varBin bytea; + BEGIN + varBin := (SELECT CAST ($1 AS bytea)); + -- Call the underlying function after preprocessing + RETURN (SELECT CAST (varBin AS GEOGRAPHY)); + END; + $$ LANGUAGE plpgsql IMMUTABLE STRICT PARALLEL SAFE; + +CREATE OR REPLACE FUNCTION sys.bbf_varbinary(sys.GEOGRAPHY) + RETURNS sys.bbf_varbinary + AS '$libdir/postgis-3','LWGEOM_to_bytea' + LANGUAGE 'c' IMMUTABLE STRICT PARALLEL SAFE; + CREATE CAST (bytea AS sys.GEOGRAPHY) WITH FUNCTION sys.GEOGRAPHY(bytea) AS IMPLICIT; CREATE CAST (sys.GEOGRAPHY AS bytea) WITH FUNCTION sys.bytea(sys.GEOGRAPHY) AS IMPLICIT; +CREATE CAST (sys.bbf_varbinary AS sys.GEOGRAPHY) WITH FUNCTION sys.GEOGRAPHY(sys.bbf_varbinary) AS IMPLICIT; +CREATE CAST (sys.GEOGRAPHY AS sys.bbf_varbinary) WITH FUNCTION sys.bbf_varbinary(sys.GEOGRAPHY) AS IMPLICIT; CREATE OR REPLACE FUNCTION sys.GEOGRAPHY(sys.GEOMETRY) RETURNS sys.GEOGRAPHY @@ -279,42 +488,34 @@ CREATE OR REPLACE FUNCTION sys.Geography__stgeomfromtext(text, integer) AS $$ DECLARE srid integer; - valid_srids integer[] := ARRAY[ - 4120, 4121, 4122, 4123, 4124, 4127, 4128, 4129, 4130, 4131, 4132, 4133, 4134, 4135, 4136, 4137, 4138, 4139, 4141, - 4142, 4143, 4144, 4145, 4146, 4147, 4148, 4149, 4150, 4151, 4152, 4153, 4154, 4155, 4156, 4157, 4158, 4159, 4160, - 4161, 4162, 4163, 4164, 4165, 4166, 4167, 4168, 4169, 4170, 4171, 4173, 4174, 4175, 4176, 4178, 4179, 4180, 4181, - 4182, 4183, 4184, 4188, 4189, 4190, 4191, 4192, 4193, 4194, 4195, 4196, 4197, 4198, 4199, 4200, 4201, 4202, 4203, - 4204, 4205, 4206, 4207, 4208, 4209, 4210, 4211, 4212, 4213, 4214, 4215, 4216, 4218, 4219, 4220, 4221, 4222, 4223, - 4224, 4225, 4227, 4229, 4230, 4231, 4232, 4236, 4237, 4238, 4239, 4240, 4241, 4242, 4243, 4244, 4245, 4246, 4247, - 4248, 4249, 4250, 4251, 4252, 4253, 4254, 4255, 4256, 4257, 4258, 4259, 4261, 4262, 4263, 4265, 4266, 4267, 4268, - 4269, 4270, 4271, 4272, 4273, 4274, 4275, 4276, 4277, 4278, 4279, 4280, 4281, 4282, 4283, 4284, 4285, 4286, 4288, - 4289, 4292, 4293, 4295, 4297, 4298, 4299, 4300, 4301, 4302, 4303, 4304, 4306, 4307, 4308, 4309, 4310, 4311, 4312, - 4313, 4314, 4315, 4316, 4317, 4318, 4319, 4322, 4324, 4326, 4600, 4601, 4602, 4603, 4604, 4605, 4606, 4607, 4608, - 4609, 4610, 4611, 4612, 4613, 4614, 4615, 4616, 4617, 4618, 4619, 4620, 4621, 4622, 4623, 4624, 4625, 4626, 4627, - 4628, 4629, 4630, 4632, 4633, 4636, 4637, 4638, 4639, 4640, 4641, 4642, 4643, 4644, 4646, 4657, 4658, 4659, 4660, - 4661, 4662, 4663, 4664, 4665, 4666, 4667, 4668, 4669, 4670, 4671, 4672, 4673, 4674, 4675, 4676, 4677, 4678, 4679, - 4680, 4682, 4683, 4684, 4686, 4687, 4688, 4689, 4690, 4691, 4692, 4693, 4694, 4695, 4696, 4697, 4698, 4699, 4700, - 4701, 4702, 4703, 4704, 4705, 4706, 4707, 4708, 4709, 4710, 4711, 4712, 4713, 4714, 4715, 4716, 4717, 4718, 4719, - 4720, 4721, 4722, 4723, 4724, 4725, 4726, 4727, 4728, 4729, 4730, 4732, 4733, 4734, 4735, 4736, 4737, 4738, 4739, - 4740, 4741, 4742, 4743, 4744, 4745, 4746, 4747, 4748, 4749, 4750, 4751, 4752, 4753, 4754, 4755, 4756, 4757, 4758, - 4801, 4802, 4803, 4804, 4805, 4806, 4807, 4808, 4809, 4810, 4811, 4813, 4814, 4815, 4816, 4817, 4818, 4820, 4821, - 4895, 4898, 4900, 4901, 4902, 4903, 4904, 4907, 4909, 4921, 4923, 4925, 4927, 4929, 4931, 4933, 4935, 4937, 4939, - 4941, 4943, 4945, 4947, 4949, 4951, 4953, 4955, 4957, 4959, 4961, 4963, 4965, 4967, 4971, 4973, 4975, 4977, 4979, - 4981, 4983, 4985, 4987, 4989, 4991, 4993, 4995, 4997, 4999, 7843, 7844, 104001 - ]; + Geomtype text; + geom sys.GEOGRAPHY; + valid_srids integer[]; lat float8; - BEGIN + BEGIN + -- Call the function to retrieve the valid SRIDs + SELECT sys.get_valid_srids() INTO valid_srids; srid := $2; - -- Here we flipping the coordinates since Geography Datatype stores the point from STGeomFromText and STPointFromText in Reverse Order i.e. (long, lat) - lat = (SELECT sys.lat(sys.Geography__STFlipCoordinates(sys.stgeogfromtext_helper($1, $2)))); - IF srid = ANY(valid_srids) AND lat >= -90.0 AND lat <= 90.0 THEN - -- Call the underlying function after preprocessing - -- Here we flipping the coordinates since Geography Datatype stores the point from STGeomFromText and STPointFromText in Reverse Order i.e. (long, lat) - RETURN (SELECT sys.Geography__STFlipCoordinates(sys.stgeogfromtext_helper($1, $2))); - ELSEIF lat < -90.0 OR lat > 90.0 THEN - RAISE EXCEPTION 'Latitude values must be between -90 and 90 degrees'; + -- Here we are flipping the coordinates since Geography Datatype stores the point from STGeomFromText and STPointFromText in Reverse Order i.e. (long, lat) + geom = (SELECT sys.stgeogfromtext_helper($1, $2)); + Geomtype = (SELECT sys.ST_GeometryType(geom)); + IF Geomtype = 'ST_Point' THEN + lat = (SELECT sys.lat(sys.Geography__STFlipCoordinates(sys.stgeogfromtext_helper($1, $2)))); + IF srid = ANY(valid_srids) AND lat >= -90.0 AND lat <= 90.0 THEN + -- Call the underlying function after preprocessing + -- Here we are flipping the coordinates since Geography Datatype stores the point from STGeomFromText and STPointFromText in Reverse Order i.e. (long, lat) + IF (SELECT sys.ST_Zmflag(geom)) = 1 OR (SELECT sys.ST_Zmflag(geom)) = 2 OR (SELECT sys.ST_Zmflag(geom)) = 3 THEN + RAISE EXCEPTION 'Unsupported flags'; + ELSE + RETURN (SELECT sys.Geography__STFlipCoordinates(geom)); + END IF; + ELSEIF lat < -90.0 OR lat > 90.0 THEN + RAISE EXCEPTION 'Latitude values must be between -90 and 90 degrees'; + ELSE + RAISE EXCEPTION 'Inavalid SRID'; + END IF; ELSE - RAISE EXCEPTION 'Inavalid SRID'; + RAISE EXCEPTION '% is not supported', Geomtype; END IF; END; $$ LANGUAGE plpgsql IMMUTABLE STRICT PARALLEL SAFE; @@ -324,7 +525,7 @@ CREATE OR REPLACE FUNCTION sys.STAsText(sys.GEOGRAPHY) AS $$ BEGIN -- Call the underlying function after preprocessing - -- Here we flipping the coordinates since Geography Datatype stores the point from STGeomFromText and STPointFromText in Reverse Order i.e. (long, lat) + -- Here we are flipping the coordinates since Geography Datatype stores the point from STGeomFromText and STPointFromText in Reverse Order i.e. (long, lat) RETURN (SELECT sys.STAsText_helper(sys.Geography__STFlipCoordinates($1))); END; $$ LANGUAGE plpgsql IMMUTABLE STRICT PARALLEL SAFE; @@ -340,30 +541,10 @@ CREATE OR REPLACE FUNCTION sys.Geography__Point(float8, float8, srid integer) DECLARE srid integer; lat float8; - valid_srids integer[] := ARRAY[ - 4120, 4121, 4122, 4123, 4124, 4127, 4128, 4129, 4130, 4131, 4132, 4133, 4134, 4135, 4136, 4137, 4138, 4139, 4141, - 4142, 4143, 4144, 4145, 4146, 4147, 4148, 4149, 4150, 4151, 4152, 4153, 4154, 4155, 4156, 4157, 4158, 4159, 4160, - 4161, 4162, 4163, 4164, 4165, 4166, 4167, 4168, 4169, 4170, 4171, 4173, 4174, 4175, 4176, 4178, 4179, 4180, 4181, - 4182, 4183, 4184, 4188, 4189, 4190, 4191, 4192, 4193, 4194, 4195, 4196, 4197, 4198, 4199, 4200, 4201, 4202, 4203, - 4204, 4205, 4206, 4207, 4208, 4209, 4210, 4211, 4212, 4213, 4214, 4215, 4216, 4218, 4219, 4220, 4221, 4222, 4223, - 4224, 4225, 4227, 4229, 4230, 4231, 4232, 4236, 4237, 4238, 4239, 4240, 4241, 4242, 4243, 4244, 4245, 4246, 4247, - 4248, 4249, 4250, 4251, 4252, 4253, 4254, 4255, 4256, 4257, 4258, 4259, 4261, 4262, 4263, 4265, 4266, 4267, 4268, - 4269, 4270, 4271, 4272, 4273, 4274, 4275, 4276, 4277, 4278, 4279, 4280, 4281, 4282, 4283, 4284, 4285, 4286, 4288, - 4289, 4292, 4293, 4295, 4297, 4298, 4299, 4300, 4301, 4302, 4303, 4304, 4306, 4307, 4308, 4309, 4310, 4311, 4312, - 4313, 4314, 4315, 4316, 4317, 4318, 4319, 4322, 4324, 4326, 4600, 4601, 4602, 4603, 4604, 4605, 4606, 4607, 4608, - 4609, 4610, 4611, 4612, 4613, 4614, 4615, 4616, 4617, 4618, 4619, 4620, 4621, 4622, 4623, 4624, 4625, 4626, 4627, - 4628, 4629, 4630, 4632, 4633, 4636, 4637, 4638, 4639, 4640, 4641, 4642, 4643, 4644, 4646, 4657, 4658, 4659, 4660, - 4661, 4662, 4663, 4664, 4665, 4666, 4667, 4668, 4669, 4670, 4671, 4672, 4673, 4674, 4675, 4676, 4677, 4678, 4679, - 4680, 4682, 4683, 4684, 4686, 4687, 4688, 4689, 4690, 4691, 4692, 4693, 4694, 4695, 4696, 4697, 4698, 4699, 4700, - 4701, 4702, 4703, 4704, 4705, 4706, 4707, 4708, 4709, 4710, 4711, 4712, 4713, 4714, 4715, 4716, 4717, 4718, 4719, - 4720, 4721, 4722, 4723, 4724, 4725, 4726, 4727, 4728, 4729, 4730, 4732, 4733, 4734, 4735, 4736, 4737, 4738, 4739, - 4740, 4741, 4742, 4743, 4744, 4745, 4746, 4747, 4748, 4749, 4750, 4751, 4752, 4753, 4754, 4755, 4756, 4757, 4758, - 4801, 4802, 4803, 4804, 4805, 4806, 4807, 4808, 4809, 4810, 4811, 4813, 4814, 4815, 4816, 4817, 4818, 4820, 4821, - 4895, 4898, 4900, 4901, 4902, 4903, 4904, 4907, 4909, 4921, 4923, 4925, 4927, 4929, 4931, 4933, 4935, 4937, 4939, - 4941, 4943, 4945, 4947, 4949, 4951, 4953, 4955, 4957, 4959, 4961, 4963, 4965, 4967, 4971, 4973, 4975, 4977, 4979, - 4981, 4983, 4985, 4987, 4989, 4991, 4993, 4995, 4997, 4999, 7843, 7844, 104001 - ]; + valid_srids integer[]; BEGIN + -- Call the function to retrieve the valid SRIDs + SELECT sys.get_valid_srids() INTO valid_srids; srid := $3; lat := $1; IF srid = ANY(valid_srids) AND lat >= -90.0 AND lat <= 90.0 THEN @@ -382,7 +563,7 @@ CREATE OR REPLACE FUNCTION sys.STAsBinary(sys.GEOGRAPHY) AS $$ BEGIN -- Call the underlying function after preprocessing - -- Here we flipping the coordinates since Geography Datatype stores the point from STGeomFromText and STPointFromText in Reverse Order i.e. (long, lat) + -- Here we are flipping the coordinates since Geography Datatype stores the point from STGeomFromText and STPointFromText in Reverse Order i.e. (long, lat) RETURN (SELECT sys.STAsBinary_helper(sys.Geography__STFlipCoordinates($1))); END; $$ LANGUAGE plpgsql IMMUTABLE STRICT PARALLEL SAFE; @@ -392,53 +573,55 @@ CREATE OR REPLACE FUNCTION sys.Geography__STPointFromText(text, integer) AS $$ DECLARE srid integer; - valid_srids integer[] := ARRAY[ - 4120, 4121, 4122, 4123, 4124, 4127, 4128, 4129, 4130, 4131, 4132, 4133, 4134, 4135, 4136, 4137, 4138, 4139, 4141, - 4142, 4143, 4144, 4145, 4146, 4147, 4148, 4149, 4150, 4151, 4152, 4153, 4154, 4155, 4156, 4157, 4158, 4159, 4160, - 4161, 4162, 4163, 4164, 4165, 4166, 4167, 4168, 4169, 4170, 4171, 4173, 4174, 4175, 4176, 4178, 4179, 4180, 4181, - 4182, 4183, 4184, 4188, 4189, 4190, 4191, 4192, 4193, 4194, 4195, 4196, 4197, 4198, 4199, 4200, 4201, 4202, 4203, - 4204, 4205, 4206, 4207, 4208, 4209, 4210, 4211, 4212, 4213, 4214, 4215, 4216, 4218, 4219, 4220, 4221, 4222, 4223, - 4224, 4225, 4227, 4229, 4230, 4231, 4232, 4236, 4237, 4238, 4239, 4240, 4241, 4242, 4243, 4244, 4245, 4246, 4247, - 4248, 4249, 4250, 4251, 4252, 4253, 4254, 4255, 4256, 4257, 4258, 4259, 4261, 4262, 4263, 4265, 4266, 4267, 4268, - 4269, 4270, 4271, 4272, 4273, 4274, 4275, 4276, 4277, 4278, 4279, 4280, 4281, 4282, 4283, 4284, 4285, 4286, 4288, - 4289, 4292, 4293, 4295, 4297, 4298, 4299, 4300, 4301, 4302, 4303, 4304, 4306, 4307, 4308, 4309, 4310, 4311, 4312, - 4313, 4314, 4315, 4316, 4317, 4318, 4319, 4322, 4324, 4326, 4600, 4601, 4602, 4603, 4604, 4605, 4606, 4607, 4608, - 4609, 4610, 4611, 4612, 4613, 4614, 4615, 4616, 4617, 4618, 4619, 4620, 4621, 4622, 4623, 4624, 4625, 4626, 4627, - 4628, 4629, 4630, 4632, 4633, 4636, 4637, 4638, 4639, 4640, 4641, 4642, 4643, 4644, 4646, 4657, 4658, 4659, 4660, - 4661, 4662, 4663, 4664, 4665, 4666, 4667, 4668, 4669, 4670, 4671, 4672, 4673, 4674, 4675, 4676, 4677, 4678, 4679, - 4680, 4682, 4683, 4684, 4686, 4687, 4688, 4689, 4690, 4691, 4692, 4693, 4694, 4695, 4696, 4697, 4698, 4699, 4700, - 4701, 4702, 4703, 4704, 4705, 4706, 4707, 4708, 4709, 4710, 4711, 4712, 4713, 4714, 4715, 4716, 4717, 4718, 4719, - 4720, 4721, 4722, 4723, 4724, 4725, 4726, 4727, 4728, 4729, 4730, 4732, 4733, 4734, 4735, 4736, 4737, 4738, 4739, - 4740, 4741, 4742, 4743, 4744, 4745, 4746, 4747, 4748, 4749, 4750, 4751, 4752, 4753, 4754, 4755, 4756, 4757, 4758, - 4801, 4802, 4803, 4804, 4805, 4806, 4807, 4808, 4809, 4810, 4811, 4813, 4814, 4815, 4816, 4817, 4818, 4820, 4821, - 4895, 4898, 4900, 4901, 4902, 4903, 4904, 4907, 4909, 4921, 4923, 4925, 4927, 4929, 4931, 4933, 4935, 4937, 4939, - 4941, 4943, 4945, 4947, 4949, 4951, 4953, 4955, 4957, 4959, 4961, 4963, 4965, 4967, 4971, 4973, 4975, 4977, 4979, - 4981, 4983, 4985, 4987, 4989, 4991, 4993, 4995, 4997, 4999, 7843, 7844, 104001 - ]; + Geomtype text; + geom sys.GEOGRAPHY; + valid_srids integer[]; lat float8; BEGIN + -- Call the function to retrieve the valid SRIDs + SELECT sys.get_valid_srids() INTO valid_srids; srid := $2; - -- Here we flipping the coordinates since Geography Datatype stores the point from STGeomFromText and STPointFromText in Reverse Order i.e. (long, lat) - lat = (SELECT sys.lat(sys.Geography__STFlipCoordinates(sys.stgeogfromtext_helper($1, $2)))); - IF srid = ANY(valid_srids) AND lat >= -90.0 AND lat <= 90.0 THEN - -- Call the underlying function after preprocessing - -- Here we flipping the coordinates since Geography Datatype stores the point from STGeomFromText and STPointFromText in Reverse Order i.e. (long, lat) - RETURN (SELECT sys.Geography__STFlipCoordinates(sys.stgeogfromtext_helper($1, $2))); - ELSEIF lat < -90.0 OR lat > 90.0 THEN - RAISE EXCEPTION 'Latitude values must be between -90 and 90 degrees'; + -- Here we are flipping the coordinates since Geography Datatype stores the point from STGeomFromText and STPointFromText in Reverse Order i.e. (long, lat) + geom = (SELECT sys.stgeogfromtext_helper($1, $2)); + Geomtype = (SELECT sys.ST_GeometryType(geom)); + IF Geomtype = 'ST_Point' THEN + lat = (SELECT sys.lat(sys.Geography__STFlipCoordinates(sys.stgeogfromtext_helper($1, $2)))); + IF srid = ANY(valid_srids) AND lat >= -90.0 AND lat <= 90.0 THEN + -- Call the underlying function after preprocessing + -- Here we are flipping the coordinates since Geography Datatype stores the point from STGeomFromText and STPointFromText in Reverse Order i.e. (long, lat) + IF (SELECT sys.ST_Zmflag(geom)) = 1 OR (SELECT sys.ST_Zmflag(geom)) = 2 OR (SELECT sys.ST_Zmflag(geom)) = 3 THEN + RAISE EXCEPTION 'Unsupported flags'; + ELSE + RETURN (SELECT sys.Geography__STFlipCoordinates(geom)); + END IF; + ELSEIF lat < -90.0 OR lat > 90.0 THEN + RAISE EXCEPTION 'Latitude values must be between -90 and 90 degrees'; + ELSE + RAISE EXCEPTION 'Inavalid SRID'; + END IF; ELSE - RAISE EXCEPTION 'Inavalid SRID'; + RAISE EXCEPTION '% is not supported', Geomtype; END IF; END; $$ LANGUAGE plpgsql IMMUTABLE STRICT PARALLEL SAFE; +CREATE OR REPLACE FUNCTION sys.ST_GeometryType(sys.GEOGRAPHY) + RETURNS text + AS '$libdir/postgis-3', 'geometry_geometrytype' + LANGUAGE 'c' IMMUTABLE STRICT PARALLEL SAFE; + +CREATE OR REPLACE FUNCTION sys.ST_zmflag(sys.GEOGRAPHY) + RETURNS smallint + AS '$libdir/postgis-3', 'LWGEOM_zmflag' + LANGUAGE 'c' IMMUTABLE STRICT PARALLEL SAFE; + -- Minimum distance CREATE OR REPLACE FUNCTION sys.STDistance(geog1 sys.GEOGRAPHY, geog2 sys.GEOGRAPHY) RETURNS float8 AS $$ BEGIN -- Call the underlying function after preprocessing - -- Here we flipping the coordinates since Geography Datatype stores the point from STGeomFromText and STPointFromText in Reverse Order i.e. (long, lat) + -- Here we are flipping the coordinates since Geography Datatype stores the point from STGeomFromText and STPointFromText in Reverse Order i.e. (long, lat) RETURN (SELECT sys.STDistance_helper(sys.Geography__STFlipCoordinates($1), sys.Geography__STFlipCoordinates($2))); END; $$ LANGUAGE plpgsql IMMUTABLE STRICT PARALLEL SAFE; @@ -484,3 +667,7 @@ CREATE OR REPLACE FUNCTION sys.STDistance_helper(geog1 sys.GEOGRAPHY, geog2 sys. AS '$libdir/postgis-3', 'LWGEOM_distance_ellipsoid' LANGUAGE 'c' IMMUTABLE STRICT PARALLEL SAFE; +CREATE OR REPLACE FUNCTION sys.GEOGRAPHY_helper(bytea) + RETURNS sys.GEOGRAPHY + AS '$libdir/postgis-3','geography_from_binary' + LANGUAGE 'c' IMMUTABLE STRICT PARALLEL SAFE; diff --git a/contrib/babelfishpg_tds/src/backend/tds/tds_data_map.c b/contrib/babelfishpg_tds/src/backend/tds/tds_data_map.c index 07698a0992..d5d9891345 100644 --- a/contrib/babelfishpg_tds/src/backend/tds/tds_data_map.c +++ b/contrib/babelfishpg_tds/src/backend/tds/tds_data_map.c @@ -182,8 +182,8 @@ TdsIoFunctionRawData TdsIoFunctionRawData_data[] = {"sys", "fixeddecimal", TDS_TYPE_MONEYN, 8, 1, TDS_SEND_MONEY, TDS_RECV_INVALID}, {"sys", "rowversion", TDS_TYPE_BINARY, 8, 2, TDS_SEND_BINARY, TDS_RECV_BINARY}, {"sys", "timestamp", TDS_TYPE_BINARY, 8, 2, TDS_SEND_BINARY, TDS_RECV_BINARY}, - {"sys", "geometry", TDS_TYPE_SPATIAL, -1, 2, TDS_SEND_GEOMETRY, TDS_RECV_GEOMETRY}, - {"sys", "geography", TDS_TYPE_SPATIAL, -1, 2, TDS_SEND_GEOGRAPHY, TDS_RECV_GEOGRAPHY}, + {"sys", "geometry", TDS_TYPE_GEOMETRY, -1, 2, TDS_SEND_GEOMETRY, TDS_RECV_GEOMETRY}, + {"sys", "geography", TDS_TYPE_GEOGRAPHY, -1, 2, TDS_SEND_GEOGRAPHY, TDS_RECV_GEOGRAPHY}, /* Mapping TDS listener sender to basic Postgres datatypes. */ {"pg_catalog", "oid", TDS_TYPE_INTEGER, 4, 1, TDS_SEND_INTEGER, TDS_RECV_INVALID}, diff --git a/contrib/babelfishpg_tds/src/backend/tds/tdsresponse.c b/contrib/babelfishpg_tds/src/backend/tds/tdsresponse.c index 24e4be415d..6baaaeb264 100644 --- a/contrib/babelfishpg_tds/src/backend/tds/tdsresponse.c +++ b/contrib/babelfishpg_tds/src/backend/tds/tdsresponse.c @@ -1923,10 +1923,10 @@ PrepareRowDescription(TupleDesc typeinfo, List *targetlist, int16 *formats, } break; case TDS_SEND_GEOMETRY: - SetColMetadataForGeometryType(col, TDS_TYPE_SPATIAL, TDS_MAXLEN_POINT, "", "geometry"); + SetColMetadataForGeometryType(col, TDS_TYPE_CLRUDT, TDS_MAXLEN_POINT, "", "geometry"); break; case TDS_SEND_GEOGRAPHY: - SetColMetadataForGeographyType(col, TDS_TYPE_SPATIAL, TDS_MAXLEN_POINT, "", "geography"); + SetColMetadataForGeographyType(col, TDS_TYPE_CLRUDT, TDS_MAXLEN_POINT, "", "geography"); break; default: diff --git a/contrib/babelfishpg_tds/src/backend/tds/tdsrpc.c b/contrib/babelfishpg_tds/src/backend/tds/tdsrpc.c index 123714d08f..64aeab3797 100644 --- a/contrib/babelfishpg_tds/src/backend/tds/tdsrpc.c +++ b/contrib/babelfishpg_tds/src/backend/tds/tdsrpc.c @@ -1787,6 +1787,53 @@ ReadParameters(TDSRequestSP request, uint64_t offset, StringInfo message, int *p CheckPLPStatusNotOK(temp, retStatus); } break; + case TDS_TYPE_CLRUDT: + { + uint16_t len; + uint8_t typenamelen; + StringInfoData typeName; + + initStringInfo(&typeName); + + memcpy(&len, &message->data[offset], sizeof(len)); + offset += sizeof(len); + + temp->maxLen = len; + + /* Read the type name for the given CLR-UDT */ + memcpy(&typenamelen, &message->data[offset], sizeof(typenamelen)); + offset += sizeof(typenamelen); + + TdsUTF16toUTF8StringInfo(&typeName, &(message->data[offset]), 2*typenamelen); + offset += 2*typenamelen; + + if (!(pg_strcasecmp(typeName.data, "geometry") == 0 || pg_strcasecmp(typeName.data, "geography") == 0)) + { + ereport(ERROR, + (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), + errmsg("The incoming tabular data stream (TDS) remote procedure call (RPC) protocol stream is incorrect. " + "UdtTypeName is incorrect."))); + } + + /* Set column metadata for given CLR-UDT type depending upon the underlying typename. */ + if (pg_strcasecmp(typeName.data, "geometry") == 0) + { + SetColMetadataForGeometryType(&temp->paramMeta, tdsType, TDS_MAXLEN_POINT, "", "geometry"); + temp->type = TDS_TYPE_GEOMETRY; + tdsType = TDS_TYPE_GEOMETRY; + } + else + { + SetColMetadataForGeographyType(&temp->paramMeta, tdsType, TDS_MAXLEN_POINT, "", "geography"); + temp->type = TDS_TYPE_GEOGRAPHY; + tdsType = TDS_TYPE_GEOGRAPHY; + } + + resetStringInfo(&typeName); + retStatus = ReadPlp(temp, message, &offset); + CheckPLPStatusNotOK(temp, retStatus); + } + break; default: ereport(ERROR, (errcode(ERRCODE_PROTOCOL_VIOLATION), diff --git a/contrib/babelfishpg_tds/src/backend/tds/tdstypeio.c b/contrib/babelfishpg_tds/src/backend/tds/tdstypeio.c index 38191c77fa..1fd7a98e32 100644 --- a/contrib/babelfishpg_tds/src/backend/tds/tdstypeio.c +++ b/contrib/babelfishpg_tds/src/backend/tds/tdstypeio.c @@ -51,6 +51,8 @@ #define TDS_RETURN_DATUM(x) return ((Datum) (x)) #define VARCHAR_MAX 2147483647 +/* TODO: need to add for other geometry types when introduced */ +#define POINTTYPE 1 #define GetPgOid(pgTypeOid, finfo) \ do { \ @@ -128,6 +130,7 @@ Datum TdsTypeSmallMoneyToDatum(StringInfo buf); Datum TdsTypeXMLToDatum(StringInfo buf); Datum TdsTypeUIDToDatum(StringInfo buf); Datum TdsTypeSqlVariantToDatum(StringInfo buf); +Datum TdsTypeSpatialToDatum(StringInfo buf); static void FetchTvpTypeOid(const ParameterToken token, char *tvpName); @@ -1448,6 +1451,59 @@ TdsTypeUIDToDatum(StringInfo buf) PG_RETURN_POINTER(uuid); } +/* Helper Function to convert Spatial Type values into Datum. */ +Datum +TdsTypeSpatialToDatum(StringInfo buf) +{ + bytea *result; + int32 geomType = 0; + int nbytes, + npoints; + StringInfo destBuf = makeStringInfo(); + + /* + * Here the incoming buf format is -> 4 Byte SRID + 2 Byte Geometry Type + (16 Bytes)*npoints + * But Driver expects -> 4 Byte SRID + 4 Byte Type + 4 Byte npoints + (16 Bytes)*npoints + */ + /* We are copying first 4 Byte SRID from buf */ + appendBinaryStringInfo(destBuf, buf->data + buf->cursor, 4); + + npoints = (buf->len - buf->cursor - 6)/16; + nbytes = buf->len - buf->cursor + 6; + result = (bytea *) palloc0(nbytes + VARHDRSZ); + SET_VARSIZE(result, nbytes + VARHDRSZ); + + /* Here we are handling the 8 bytes (4 Byte Type + 4 Byte npoints) which driver expects for 2-D point */ + if (buf->data[buf->cursor + 4] == 1 && buf->data[buf->cursor + 5] == 12) + { + geomType = (int32) POINTTYPE; + + enlargeStringInfo(destBuf, sizeof(uint32_t)); + memcpy(destBuf->data + destBuf->len, (char *) &geomType, sizeof(uint32_t)); + destBuf->len += sizeof(uint32_t); + destBuf->data[destBuf->len] = '\0'; + + enlargeStringInfo(destBuf, sizeof(uint32_t)); + memcpy(destBuf->data + destBuf->len, (char *) &npoints, sizeof(uint32_t)); + destBuf->len += sizeof(uint32_t); + destBuf->data[destBuf->len] = '\0'; + } + else + { + ereport(ERROR, + (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), + errmsg("Unsupported geometry type"))); + } + + /* We are copying the remaining bytes (16 Bytes)*npoints from buf */ + appendBinaryStringInfo(destBuf, buf->data + buf->cursor + 6, buf->len - 6); + + memcpy(VARDATA(result), &destBuf->data[0], nbytes); + buf->cursor += nbytes - 6; + + PG_RETURN_BYTEA_P(result); +} + StringInfo TdsGetPlpStringInfoBufferFromToken(const char *message, const ParameterToken token) { @@ -2007,24 +2063,15 @@ TdsRecvTypeDatetime2(const char *message, const ParameterToken token) * Geometry data type * -------------------------------- */ -/* - * It is a Placeholder Function for now - * TODO: Will need to address it in subsequent Code Changes -*/ Datum TdsRecvTypeGeometry(const char *message, const ParameterToken token) { - Datum result = 0; - - /* Decode binary and convert if needed */ - StringInfo buf = TdsGetStringInfoBufferFromToken(message, token); - - /* Return in Datum val */ + Datum result; + StringInfo buf = TdsGetPlpStringInfoBufferFromToken(message, token); - ereport(ERROR, - (errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE), - errmsg("Prepared Queries for Geometry DataType Currently not Supported in BabelFish"))); + result = TdsTypeSpatialToDatum(buf); + pfree(buf->data); pfree(buf); return result; } @@ -2033,25 +2080,16 @@ TdsRecvTypeGeometry(const char *message, const ParameterToken token) * TdsRecvTypeGeography - converts external binary format to * Geography data type * -------------------------------- - */ -/* - * It is a Placeholder Function for now - * TODO: Will need to address it in subsequent Code Changes -*/ + */ Datum TdsRecvTypeGeography(const char *message, const ParameterToken token) { - Datum result = 0; - - /* Decode binary and convert if needed */ - StringInfo buf = TdsGetStringInfoBufferFromToken(message, token); - - /* Return in Datum val */ + Datum result; + StringInfo buf = TdsGetPlpStringInfoBufferFromToken(message, token); - ereport(ERROR, - (errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE), - errmsg("Prepared Queries for Geography DataType Currently not Supported in BabelFish"))); + result = TdsTypeSpatialToDatum(buf); + pfree(buf->data); pfree(buf); return result; } @@ -2426,8 +2464,9 @@ TdsRecvTypeTable(const char *message, const ParameterToken token) case TDS_TYPE_SQLVARIANT: values[i] = TdsTypeSqlVariantToDatum(temp); break; - case TDS_TYPE_SPATIAL: - break; + case TDS_TYPE_CLRUDT: + values[i] = TdsTypeSpatialToDatum(temp); + break; } /* Build a string for bind parameters. */ if (colMetaData[currentColumn].columnTdsType != TDS_TYPE_NVARCHAR || row->isNull[currentColumn] == 'n') @@ -4187,7 +4226,7 @@ TdsSendSpatialHelper(FmgrInfo *finfo, Datum value, void *vMetaData, int TdsInstr * Row chunck length expected by the driver is: * 16 * (No. of Points) + 6 * 16 -> 2 8-Byte float coordinates (TODO: Need to change when Z and M flags are defined for N-dimension Points) - * 6 -> 4 Byte SRID + 2 Byte (01 0C) + * 6 -> 4 Byte SRID + 2 Byte Geometry Type (01 0C -> for Point Type) */ len = npoints*16 + 6; buf = (char *) palloc0(len); @@ -4198,12 +4237,19 @@ TdsSendSpatialHelper(FmgrInfo *finfo, Datum value, void *vMetaData, int TdsInstr *((int32_t*)buf) = srid; itr = buf + 4; - /* Driver Expects 01 0C as 2 constant Bytes */ - /* TODO: Will need to verify for Different Geometry Data Types */ - *itr = 1; - itr++; - *itr = 12; - itr++; + /* Driver Expects 01 0C for 2-D Point Type as 2 constant Bytes to identify the Geometry Type */ + /* TODO: Will need to introduce for Different Geometry Data Types */ + switch (*((uint32_t*)gser->data)) + { + case POINTTYPE: + *itr = 1; + itr++; + *itr = 12; + itr++; + break; + default: + elog(ERROR, "Unsupported geometry type"); + } /* Data part of the Row has length 16 * (No. of Points) */ /* diff --git a/contrib/babelfishpg_tds/src/include/tds_iofuncmap.h b/contrib/babelfishpg_tds/src/include/tds_iofuncmap.h index 0bb5305a3e..5726cddc60 100644 --- a/contrib/babelfishpg_tds/src/include/tds_iofuncmap.h +++ b/contrib/babelfishpg_tds/src/include/tds_iofuncmap.h @@ -117,7 +117,9 @@ #define TDS_TYPE_SQLVARIANT 98 /* 0x62 */ #define TDS_TYPE_DATETIMEOFFSET 43 /* 0x2B */ #define TDS_TYPE_SMALLDATETIME 58 /* 0x3A */ -#define TDS_TYPE_SPATIAL 240 /* 0xF0 */ +#define TDS_TYPE_CLRUDT 240 /* 0xF0 */ +#define TDS_TYPE_GEOMETRY 254 /* 0xFE */ +#define TDS_TYPE_GEOGRAPHY 255 /* 0xFF */ /* * macros for supporting sqlvariant datatype on TDS side diff --git a/contrib/babelfishpg_tds/src/include/tds_request.h b/contrib/babelfishpg_tds/src/include/tds_request.h index 3b508e05bc..e76a18034d 100644 --- a/contrib/babelfishpg_tds/src/include/tds_request.h +++ b/contrib/babelfishpg_tds/src/include/tds_request.h @@ -333,7 +333,7 @@ SetTvpRowData(ParameterToken temp, const StringInfo message, uint64_t *offset) *offset += rowData->columnValues[i].len; } break; - case TDS_TYPE_SPATIAL: + case TDS_TYPE_CLRUDT: { retStatus = ReadPlp(temp, message, offset); CheckPLPStatusNotOKForTVP(temp, retStatus); @@ -651,7 +651,7 @@ SetColMetadataForTvp(ParameterToken temp, const StringInfo message, uint64_t *of memcpy(&colmetadata[i].maxLen, &messageData[*offset], sizeof(uint32_t)); *offset += sizeof(uint32_t); break; - case TDS_TYPE_SPATIAL: + case TDS_TYPE_CLRUDT: colmetadata[i].maxLen = messageData[(*offset)++]; break; default: diff --git a/test/JDBC/expected/TestSpatialPoint-vu-cleanup.out b/test/JDBC/expected/TestSpatialPoint-vu-cleanup.out index d2f24215ac..5ad69e2c46 100644 --- a/test/JDBC/expected/TestSpatialPoint-vu-cleanup.out +++ b/test/JDBC/expected/TestSpatialPoint-vu-cleanup.out @@ -1,41 +1,27 @@ DROP VIEW IF EXISTS TextFromGeom -GO DROP VIEW IF EXISTS BinaryFromGeom -GO DROP VIEW IF EXISTS CoordsFromGeom -GO DROP VIEW IF EXISTS point_distances_geom -GO DROP VIEW IF EXISTS TextFromGeog -GO DROP VIEW IF EXISTS BinaryFromGeog -GO DROP VIEW IF EXISTS CoordsFromGeog -GO DROP VIEW IF EXISTS TransformFromGeog -GO DROP VIEW IF EXISTS point_distances_geog -GO DROP TABLE IF EXISTS SPATIALPOINTGEOM_dt -GO DROP TABLE IF EXISTS TypeTable -GO DROP TYPE IF EXISTS geom -GO DROP TABLE IF EXISTS SPATIALPOINTGEOG_dt -GO DROP TABLE IF EXISTS SPATIALPOINT_dt -GO diff --git a/test/JDBC/expected/TestSpatialPoint-vu-prepare.out b/test/JDBC/expected/TestSpatialPoint-vu-prepare.out index bc11ee4221..d3c1cda6a0 100644 --- a/test/JDBC/expected/TestSpatialPoint-vu-prepare.out +++ b/test/JDBC/expected/TestSpatialPoint-vu-prepare.out @@ -1,334 +1,378 @@ CREATE TABLE SPATIALPOINTGEOM_dt (location geometry) -GO +#Geometry Test Cases --- Geometry Test Cases --- Positive Test for STGeomFromText with SRID 4326 -INSERT INTO SPATIALPOINTGEOM_dt (location) -VALUES ( geometry::STGeomFromText('Point(47.65100 -22.34900)', 4326) ) -GO +#Positive Test for STGeomFromText with SRID 4326 +INSERT INTO SPATIALPOINTGEOM_dt (location) VALUES ( geometry::STGeomFromText('Point(47.65100 -22.34900)', 4326) ) ~~ROW COUNT: 1~~ -INSERT INTO SPATIALPOINTGEOM_dt (location) -VALUES ( geometry::STGeomFromText('Point(1.0 2.0)', 4326) ) -GO + +INSERT INTO SPATIALPOINTGEOM_dt (location) VALUES ( geometry::STGeomFromText('Point(1.0 2.0)', 4326) ) ~~ROW COUNT: 1~~ --- Positive Test for STGeomFromText with SRID 0 -INSERT INTO SPATIALPOINTGEOM_dt (location) -VALUES ( geometry::STGeomFromText('Point(47.65100 -22.34900)', 0) ) -GO +#Positive Test for STGeomFromText with SRID 0 +INSERT INTO SPATIALPOINTGEOM_dt (location) VALUES ( geometry::STGeomFromText('Point(47.65100 -22.34900)', 0) ) ~~ROW COUNT: 1~~ --- Negative Test for STGeomFromText when SRID is not provided -INSERT INTO SPATIALPOINTGEOM_dt (location) -VALUES ( geometry::STGeomFromText('Point(47.65100 -22.34900)') ) -GO +#Negative Test for STGeomFromText when SRID is not provided +INSERT INTO SPATIALPOINTGEOM_dt (location) VALUES ( geometry::STGeomFromText('Point(47.65100 -22.34900)') ) ~~ERROR (Code: 8146)~~ ~~ERROR (Message: function geometry__stgeomfromtext has no parameters and arguments were supplied.)~~ --- Negative Test for STGeomFromText when SRID >= 10^6 --- SRID should be between 0 to 999999 -INSERT INTO SPATIALPOINTGEOM_dt (location) -VALUES ( geometry::STGeomFromText('Point(47.65100 -22.34900)', 1000000000 ) ) -GO +#Negative Test for STGeomFromText when SRID >= 10^6 +#SRID should be between 0 to 999999 +INSERT INTO SPATIALPOINTGEOM_dt (location) VALUES ( geometry::STGeomFromText('Point(47.65100 -22.34900)', 1000000000 ) ) ~~ERROR (Code: 33557097)~~ ~~ERROR (Message: SRID value should be between 0 and 999999)~~ --- Negative Test for STGeomFromText with SRID < 0 --- SRID should be between 0 to 999999 -INSERT INTO SPATIALPOINTGEOM_dt (location) -VALUES ( geometry::STGeomFromText('Point(47.65100 -22.34900)', -1) ) -GO +#Negative Test for STGeomFromText with SRID < 0 +#SRID should be between 0 to 999999 +INSERT INTO SPATIALPOINTGEOM_dt (location) VALUES ( geometry::STGeomFromText('Point(47.65100 -22.34900)', -1) ) ~~ERROR (Code: 33557097)~~ ~~ERROR (Message: SRID value should be between 0 and 999999)~~ --- Negative Test for STGeomFromText when a coordinate is missing -INSERT INTO SPATIALPOINTGEOM_dt (location) -VALUES ( geometry::STGeomFromText('Point(1.0 )', 4326) ) -GO +#Negative Test for STGeomFromText when a coordinate is missing +INSERT INTO SPATIALPOINTGEOM_dt (location) VALUES ( geometry::STGeomFromText('Point(1.0 )', 4326) ) ~~ERROR (Code: 33557097)~~ ~~ERROR (Message: parse error - invalid geometry)~~ --- Negative Test for STGeomFromText when invalid type is provided -INSERT INTO SPATIALPOINTGEOM_dt (location) -VALUES ( geometry::STGeomFromText('Pnt', 4326) ) -GO +#Negative Test for STGeomFromText when invalid type is provided +INSERT INTO SPATIALPOINTGEOM_dt (location) VALUES ( geometry::STGeomFromText('Pnt', 4326) ) ~~ERROR (Code: 33557097)~~ ~~ERROR (Message: parse error - invalid geometry)~~ --- Test for STGeomFromText when null Point is Given -> Returns NBCRow -INSERT INTO SPATIALPOINTGEOM_dt (location) -VALUES ( geometry::STGeomFromText(null, 4326) ) -GO +#Test for STGeomFromText when null Point is Given -> Returns NBCRow +INSERT INTO SPATIALPOINTGEOM_dt (location) VALUES ( geometry::STGeomFromText(null, 4326) ) ~~ROW COUNT: 1~~ +#Negative Test for STGeomFromText when Incorrect cast is provided +#INSERT INTO SPATIALPOINTGEOM_dt (location) VALUES ( geography::STGeomFromText('Point(47.65100 -22.34900)', 4326) ) --- -- Negative Test for STGeomFromText when Incorrect cast is provided --- INSERT INTO SPATIALPOINTGEOM_dt (location) --- VALUES ( geography::STGeomFromText('Point(47.65100 -22.34900)', 4326) ) --- GO --- Positive Test for STPointFromText with SRID 4326. Rest are same as STGeomFromText -INSERT INTO SPATIALPOINTGEOM_dt (location) -VALUES ( geometry::STPointFromText('Point(47.65100 -22.34900)', 4326) ) -GO +#Positive Test for STPointFromText with SRID 4326. Rest are same as STGeomFromText +INSERT INTO SPATIALPOINTGEOM_dt (location) VALUES ( geometry::STPointFromText('Point(47.65100 -22.34900)', 4326) ) ~~ROW COUNT: 1~~ -INSERT INTO SPATIALPOINTGEOM_dt (location) -VALUES ( geometry::STPointFromText('Point(1.0 2.0)', 4326) ) -GO + +INSERT INTO SPATIALPOINTGEOM_dt (location) VALUES ( geometry::STPointFromText('Point(1.0 2.0)', 4326) ) ~~ROW COUNT: 1~~ --- Positive Test for Point with SRID 4326 -INSERT INTO SPATIALPOINTGEOM_dt (location) -VALUES ( geometry::Point(47.65100, -22.34900, 4326) ) -GO + +#Positive Test for Point with SRID 4326 +INSERT INTO SPATIALPOINTGEOM_dt (location) VALUES ( geometry::Point(47.65100, -22.34900, 4326) ) ~~ROW COUNT: 1~~ -CREATE VIEW TextFromGeom AS -SELECT STAsText(location) AS TextRepresentation -FROM SPATIALPOINTGEOM_dt; -GO - -CREATE VIEW BinaryFromGeom AS -SELECT STAsBinary(location) AS BinaryRepresentation -FROM SPATIALPOINTGEOM_dt; -GO - -CREATE VIEW CoordsFromGeom AS -SELECT STX(location), STY(location) AS Coordinates -FROM SPATIALPOINTGEOM_dt; -GO - -CREATE VIEW point_distances_geom AS -SELECT - p1.location AS point1, - p2.location AS point2, - STDistance( p1.location, p2.location ) AS distance -FROM - SPATIALPOINTGEOM_dt p1 -CROSS JOIN - SPATIALPOINTGEOM_dt p2 -WHERE - p1.location <> p2.location; -GO +#Tests for Geometry type Prepared Statements +prepst#!#INSERT INTO SPATIALPOINTGEOM_dt(location) values(?) #!#GEOMETRY|-|location|-|Point(47.65100 -22.34900):4326 +~~ROW COUNT: 1~~ + +prepst#!#exec#!#GEOMETRY|-|location|-|Point(1.0 2.0):4326 +~~ROW COUNT: 1~~ + +prepst#!#exec#!#GEOMETRY|-|location|-|Point(47.65100 -22.34900):0 +~~ROW COUNT: 1~~ + +#Negative Test for STGeomFromText when SRID >= 10^6 +prepst#!#exec#!#GEOMETRY|-|location|-|Point(47.65100 -22.34900):1000000000 +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Error converting data type varbinary to geometry.)~~ + +#Negative Test for STGeomFromText with SRID < 0 +prepst#!#exec#!#GEOMETRY|-|location|-|Point(47.65100 -22.34900):-1 +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Error converting data type varbinary to geometry.)~~ + +#Negative Test for STGeomFromText when SRID is NULL +prepst#!#exec#!#GEOMETRY|-|location|-|Point(47.65100 -22.34900): +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Error converting data type varbinary to geometry.)~~ + +#Negative Test for STGeomFromText when a coordinate is missing +prepst#!#exec#!#GEOMETRY|-|location|-|Point(1.0 ):4326 +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Error converting data type varbinary to geometry.)~~ + +#Negative Test when an unsupported feature in queried +prepst#!#exec#!#GEOMETRY|-|location|-|Point(1.0 2.0 3.0 4.0):4326 +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Unsupported geometry type)~~ + +prepst#!#exec#!#GEOMETRY|-|location|-|LINESTRING(1 2, 3 4):4326 +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Unsupported geometry type)~~ + +#Negative Test for STGeomFromText when invalid type is provided +prepst#!#exec#!#GEOMETRY|-|location|-|Pnt:4326 +~~ERROR (Code: 0)~~ + +~~ERROR (Message: Illegal character in Well-Known text at position 3.)~~ + +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Unsupported geometry type)~~ + +#Negative Test for STGeomFromText when Null geometry is provided +prepst#!#exec#!#GEOMETRY|-|location|-|:4326 +~~ERROR (Code: 0)~~ + +~~ERROR (Message: Illegal character in Well-Known text at position 0.)~~ + +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Unsupported geometry type)~~ + + +CREATE VIEW TextFromGeom AS SELECT STAsText(location) AS TextRepresentation FROM SPATIALPOINTGEOM_dt; + +CREATE VIEW BinaryFromGeom AS SELECT STAsBinary(location) AS BinaryRepresentation FROM SPATIALPOINTGEOM_dt; + +CREATE VIEW CoordsFromGeom AS SELECT STX(location), STY(location) AS Coordinates FROM SPATIALPOINTGEOM_dt; + +CREATE VIEW point_distances_geom AS SELECT p1.location AS point1, p2.location AS point2, STDistance( p1.location, p2.location ) AS distance FROM SPATIALPOINTGEOM_dt p1 CROSS JOIN SPATIALPOINTGEOM_dt p2 WHERE p1.location <> p2.location; CREATE TABLE SPATIALPOINTGEOG_dt (location geography) -GO --- Create Type Test Case currently Babelfish supports it but TSQL doesn't for spatial Types, Although it doesn't break anything --- TODO: Make it similar to T-SQL -CREATE TYPE geom -FROM geometry NOT NULL ; -GO +#Create Type Test Case currently Babelfish supports it but TSQL doesn't for spatial Types, Although it doesn't break anything +#TODO: Make it similar to T-SQL +CREATE TYPE geom FROM geometry NOT NULL ; CREATE TABLE TypeTable(ID INT PRIMARY KEY, Shape geom) -GO -INSERT INTO TypeTable(ID, Shape) -VALUES(1, geometry::Point(1, 2, 4326)); -GO +INSERT INTO TypeTable(ID, Shape) VALUES(1, geometry::Point(1, 2, 4326)); ~~ROW COUNT: 1~~ +#Geography Test Cases --- Geography Test Cases --- Positive Test for STGeomFromText with SRID 4326 -INSERT INTO SPATIALPOINTGEOG_dt (location) -VALUES ( geography::STGeomFromText('Point(47.65100 -22.34900)', 4326) ) -GO +#Positive Test for STGeomFromText with SRID 4326 +INSERT INTO SPATIALPOINTGEOG_dt (location) VALUES ( geography::STGeomFromText('Point(47.65100 -22.34900)', 4326) ) ~~ROW COUNT: 1~~ -INSERT INTO SPATIALPOINTGEOG_dt (location) -VALUES ( geography::STGeomFromText('Point(1.0 2.0)', 4326) ) -GO + +INSERT INTO SPATIALPOINTGEOG_dt (location) VALUES ( geography::STGeomFromText('Point(1.0 2.0)', 4326) ) ~~ROW COUNT: 1~~ --- Negative Test for STGeomFromText for Geography with SRID 0 -INSERT INTO SPATIALPOINTGEOG_dt (location) -VALUES ( geography::STGeomFromText('Point(47.65100 -22.34900)', 0) ) -GO +#Negative Test for STGeomFromText for Geography with SRID 0 +INSERT INTO SPATIALPOINTGEOG_dt (location) VALUES ( geography::STGeomFromText('Point(47.65100 -22.34900)', 0) ) ~~ERROR (Code: 33557097)~~ ~~ERROR (Message: Inavalid SRID)~~ --- Negative Test for STGeomFromText for Geography when lat > 90 or < -90 -INSERT INTO SPATIALPOINTGEOG_dt (location) -VALUES ( geography::STGeomFromText('Point(47.65100 -122.34900)', 4326) ) -GO +#Negative Test for STGeomFromText for Geography when lat > 90 or < -90 +INSERT INTO SPATIALPOINTGEOG_dt (location) VALUES ( geography::STGeomFromText('Point(47.65100 -122.34900)', 4326) ) ~~ERROR (Code: 33557097)~~ ~~ERROR (Message: Latitude values must be between -90 and 90 degrees)~~ --- Negative Test for STGeomFromText when SRID is not provided -INSERT INTO SPATIALPOINTGEOG_dt (location) -VALUES ( geography::STGeomFromText('Point(47.65100 -22.34900)') ) -GO +#Negative Test for STGeomFromText when SRID is not provided +INSERT INTO SPATIALPOINTGEOG_dt (location) VALUES ( geography::STGeomFromText('Point(47.65100 -22.34900)') ) ~~ERROR (Code: 8146)~~ ~~ERROR (Message: function geography__stgeomfromtext has no parameters and arguments were supplied.)~~ --- Negative Test for STGeomFromText when cast is not provided -INSERT INTO SPATIALPOINTGEOG_dt (location) -VALUES ( STGeomFromText('Point(47.65100 -22.34900)', 4326) ) -GO +#Negative Test for STGeomFromText when cast is not provided +INSERT INTO SPATIALPOINTGEOG_dt (location) VALUES ( STGeomFromText('Point(47.65100 -22.34900)', 4326) ) ~~ERROR (Code: 33557097)~~ ~~ERROR (Message: function stgeomfromtext(unknown, integer) does not exist)~~ +#Negative Test for STGeomFromText when incorrect cast is provided +#INSERT INTO SPATIALPOINTGEOG_dt (location) VALUES ( geometry::STGeomFromText('Point(47.65100 -22.34900)', 4326) ) --- -- Negative Test for STGeomFromText when incorrect cast is provided --- INSERT INTO SPATIALPOINTGEOG_dt (location) --- VALUES ( geometry::STGeomFromText('Point(47.65100 -22.34900)', 4326) ) --- GO --- Negative Test for STGeomFromText when SRID >= 10^6 -INSERT INTO SPATIALPOINTGEOG_dt (location) -VALUES ( geography::STGeomFromText('Point(47.65100 -22.34900)', 1000000000 ) ) -GO +#Negative Test for STGeomFromText when SRID >= 10^6 +INSERT INTO SPATIALPOINTGEOG_dt (location) VALUES ( geography::STGeomFromText('Point(47.65100 -22.34900)', 1000000000 ) ) ~~ERROR (Code: 33557097)~~ ~~ERROR (Message: Inavalid SRID)~~ --- Negative Test for STGeomFromText with SRID < 0 -INSERT INTO SPATIALPOINTGEOG_dt (location) -VALUES ( geography::STGeomFromText('Point(47.65100 -22.34900)', -1) ) -GO +#Negative Test for STGeomFromText with SRID < 0 +INSERT INTO SPATIALPOINTGEOG_dt (location) VALUES ( geography::STGeomFromText('Point(47.65100 -22.34900)', -1) ) ~~ERROR (Code: 33557097)~~ ~~ERROR (Message: Inavalid SRID)~~ --- Negative Test for STGeomFromText when a coordinate is missing -INSERT INTO SPATIALPOINTGEOG_dt (location) -VALUES ( geography::STGeomFromText('Point(1.0 )', 4326) ) -GO +#Negative Test for STGeomFromText when a coordinate is missing +INSERT INTO SPATIALPOINTGEOG_dt (location) VALUES ( geography::STGeomFromText('Point(1.0 )', 4326) ) ~~ERROR (Code: 33557097)~~ ~~ERROR (Message: parse error - invalid geometry)~~ --- Negative Test for STGeomFromText when invalid type is provided -INSERT INTO SPATIALPOINTGEOG_dt (location) -VALUES ( geography::STGeomFromText('Pnt', 4326) ) -GO +#Negative Test for STGeomFromText when invalid type is provided +INSERT INTO SPATIALPOINTGEOG_dt (location) VALUES ( geography::STGeomFromText('Pnt', 4326) ) ~~ERROR (Code: 33557097)~~ ~~ERROR (Message: parse error - invalid geometry)~~ --- Test for STGeomFromText when null Point is Given -> Returns NBCRow -INSERT INTO SPATIALPOINTGEOG_dt (location) -VALUES ( geography::STGeomFromText(null, 4326) ) -GO +#Test for STGeomFromText when null Point is Given -> Returns NBCRow +INSERT INTO SPATIALPOINTGEOG_dt (location) VALUES ( geography::STGeomFromText(null, 4326) ) ~~ROW COUNT: 1~~ --- Positive Test for STPointFromText with SRID 4326. Rest are same as STGeomFromText -INSERT INTO SPATIALPOINTGEOG_dt (location) -VALUES ( geography::STPointFromText('Point(47.65100 -22.34900)', 4326) ) -GO +#Positive Test for STPointFromText with SRID 4326. Rest are same as STGeomFromText +INSERT INTO SPATIALPOINTGEOG_dt (location) VALUES ( geography::STPointFromText('Point(47.65100 -22.34900)', 4326) ) ~~ROW COUNT: 1~~ -INSERT INTO SPATIALPOINTGEOG_dt (location) -VALUES ( geography::STPointFromText('Point(1.0 2.0)', 4326) ) -GO + +INSERT INTO SPATIALPOINTGEOG_dt (location) VALUES ( geography::STPointFromText('Point(1.0 2.0)', 4326) ) ~~ROW COUNT: 1~~ --- Negative Test for STPointFromText for Geography when lat > 90 or < -90 -INSERT INTO SPATIALPOINTGEOG_dt (location) -VALUES ( geography::STPointFromText('Point(47.65100 122.34900)', 4326) ) -GO +#Negative Test for STPointFromText for Geography when lat > 90 or < -90 +INSERT INTO SPATIALPOINTGEOG_dt (location) VALUES ( geography::STPointFromText('Point(47.65100 122.34900)', 4326) ) ~~ERROR (Code: 33557097)~~ ~~ERROR (Message: Latitude values must be between -90 and 90 degrees)~~ --- Positive Test for Point with SRID 4326 -INSERT INTO SPATIALPOINTGEOG_dt (location) -VALUES ( geography::Point(47.65100, -22.34900, 4326) ) -GO +#Positive Test for Point with SRID 4326 +INSERT INTO SPATIALPOINTGEOG_dt (location) VALUES ( geography::Point(47.65100, -22.34900, 4326) ) ~~ROW COUNT: 1~~ --- Negative Test for Point for Geography when lat > 90 or < -90 -INSERT INTO SPATIALPOINTGEOG_dt (location) -VALUES ( geography::Point(147.65100, -22.34900, 4326) ) -GO +#Negative Test for Point for Geography when lat > 90 or < -90 +INSERT INTO SPATIALPOINTGEOG_dt (location) VALUES ( geography::Point(147.65100, -22.34900, 4326) ) ~~ERROR (Code: 33557097)~~ ~~ERROR (Message: Latitude values must be between -90 and 90 degrees)~~ -CREATE VIEW TextFromGeog AS -SELECT STAsText(location) AS TextRepresentation -FROM SPATIALPOINTGEOG_dt; -GO - -CREATE VIEW BinaryFromGeog AS -SELECT STAsBinary(location) AS BinaryRepresentation -FROM SPATIALPOINTGEOG_dt; -GO - -CREATE VIEW CoordsFromGeog AS -SELECT long(location), lat(location) AS Coordinates -FROM SPATIALPOINTGEOG_dt; -GO - - -CREATE VIEW TransformFromGeog AS -SELECT ST_Transform(location, 4326) AS Modified_points -FROM SPATIALPOINTGEOG_dt; -GO - -CREATE VIEW point_distances_geog AS -SELECT - p1.location AS point1, - p2.location AS point2, - STDistance( p1.location, p2.location ) AS distance -FROM - SPATIALPOINTGEOG_dt p1 -CROSS JOIN - SPATIALPOINTGEOG_dt p2 -WHERE - p1.location <> p2.location; -GO - -CREATE TABLE SPATIALPOINT_dt (GeomColumn geometry, GeogColumn geography) -GO -INSERT INTO SPATIALPOINT_dt (GeomColumn) -VALUES ( geometry::STGeomFromText('Point(47.65100 -22.34900)', 4326) ) -GO +#Tests for Geography type Prepared Statements +prepst#!#INSERT INTO SPATIALPOINTGEOG_dt(location) values(?) #!#GEOGRAPHY|-|location|-|Point(47.65100 -22.34900):4326 +~~ROW COUNT: 1~~ + +prepst#!#exec#!#GEOGRAPHY|-|location|-|Point(1.0 2.0):4326 +~~ROW COUNT: 1~~ + +#Negative Test for STGeomFromText for Geography with SRID 0 +prepst#!#exec#!#GEOGRAPHY|-|location|-|Point(47.65100 -22.34900):0 +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Error converting data type varbinary to geography.)~~ + +#Negative Test for STGeomFromText for Geography when lat > 90 or < -90 +prepst#!#exec#!#GEOGRAPHY|-|location|-|Point(47.65100 -122.34900):4326 +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Error converting data type varbinary to geography.)~~ + +#Negative Test for STGeomFromText when SRID >= 10^6 +prepst#!#exec#!#GEOGRAPHY|-|location|-|Point(47.65100 -22.34900):1000000000 +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Error converting data type varbinary to geography.)~~ + +#Negative Test for STGeomFromText with SRID < 0 +prepst#!#exec#!#GEOGRAPHY|-|location|-|Point(47.65100 -22.34900):-1 +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Error converting data type varbinary to geography.)~~ + +#Negative Test for STGeomFromText with SRID is NULL +prepst#!#exec#!#GEOGRAPHY|-|location|-|Point(47.65100 -22.34900): +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Error converting data type varbinary to geography.)~~ + +#Negative Test for STGeomFromText when a coordinate is missing +prepst#!#exec#!#GEOGRAPHY|-|location|-|Point(1.0 ):4326 +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Error converting data type varbinary to geography.)~~ + +#Negative Test when an unsupported feature in queried +prepst#!#exec#!#GEOGRAPHY|-|location|-|Point(1.0 2.0 3.0 4.0):4326 +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Unsupported geometry type)~~ + +prepst#!#exec#!#GEOGRAPHY|-|location|-|LINESTRING(1 2, 3 4):4326 +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Unsupported geometry type)~~ + +#Negative Test for STGeomFromText when invalid type is provided +prepst#!#exec#!#GEOGRAPHY|-|location|-|Pnt:4326 +~~ERROR (Code: 0)~~ + +~~ERROR (Message: Illegal character in Well-Known text at position 3.)~~ + +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Unsupported geometry type)~~ + +#Negative Test for STGeomFromText when Null geography is provided +prepst#!#exec#!#GEOGRAPHY|-|location|-|:4326 +~~ERROR (Code: 0)~~ + +~~ERROR (Message: Illegal character in Well-Known text at position 0.)~~ + +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Unsupported geometry type)~~ + + +CREATE VIEW TextFromGeog AS SELECT STAsText(location) AS TextRepresentation FROM SPATIALPOINTGEOG_dt; + +CREATE VIEW BinaryFromGeog AS SELECT STAsBinary(location) AS BinaryRepresentation FROM SPATIALPOINTGEOG_dt; + +CREATE VIEW CoordsFromGeog AS SELECT long(location), lat(location) AS Coordinates FROM SPATIALPOINTGEOG_dt; + + +CREATE VIEW TransformFromGeog AS SELECT ST_Transform(location, 4326) AS Modified_points FROM SPATIALPOINTGEOG_dt; + +CREATE VIEW point_distances_geog AS SELECT p1.location AS point1, p2.location AS point2, STDistance( p1.location, p2.location ) AS distance FROM SPATIALPOINTGEOG_dt p1 CROSS JOIN SPATIALPOINTGEOG_dt p2 WHERE p1.location <> p2.location; + +CREATE TABLE SPATIALPOINT_dt (PrimaryKey int, GeomColumn geometry, GeogColumn geography) + +INSERT INTO SPATIALPOINT_dt (PrimaryKey, GeomColumn) VALUES ( 1, geometry::STGeomFromText('Point(47.65100 -22.34900)', 4326) ) +~~ROW COUNT: 1~~ + + +INSERT INTO SPATIALPOINT_dt (PrimaryKey, GeogColumn) VALUES ( 2, geography::STGeomFromText('Point(47.65100 -22.34900)', 4326) ) +~~ROW COUNT: 1~~ + + +INSERT INTO SPATIALPOINT_dt (PrimaryKey, GeomColumn, GeogColumn) VALUES ( 3, geometry::STGeomFromText('Point(1.0 2.0)', 4326), geography::STGeomFromText('Point(1.0 2.0)', 4326) ) +~~ROW COUNT: 1~~ + + + +#Tests for Spatial type Prepared Statements +prepst#!#INSERT INTO SPATIALPOINT_dt(PrimaryKey, GeomColumn) values(?, ?) #!#int|-|PrimaryKey|-|4#!#GEOMETRY|-|GeomColumn|-|Point(47.65100 -22.34900):4326 ~~ROW COUNT: 1~~ -INSERT INTO SPATIALPOINT_dt (GeogColumn) -VALUES ( geography::STGeomFromText('Point(47.65100 -22.34900)', 4326) ) -GO +prepst#!#INSERT INTO SPATIALPOINT_dt(PrimaryKey, GeogColumn) values(?, ?) #!#int|-|PrimaryKey|-|5#!#GEOGRAPHY|-|GeogColumn|-|Point(47.65100 -22.34900):4326 ~~ROW COUNT: 1~~ -INSERT INTO SPATIALPOINT_dt (GeomColumn, GeogColumn) -VALUES ( geometry::STGeomFromText('Point(1.0 2.0)', 4326), geography::STGeomFromText('Point(1.0 2.0)', 4326) ) -GO +prepst#!#INSERT INTO SPATIALPOINT_dt(PrimaryKey, GeomColumn, GeogColumn) values(?, ?, ?) #!#int|-|PrimaryKey|-|6#!#GEOMETRY|-|GeomColumn|-|Point(1.0 2.0):4326#!#GEOGRAPHY|-|GeogColumn|-|Point(1.0 2.0):4326 ~~ROW COUNT: 1~~ diff --git a/test/JDBC/expected/TestSpatialPoint-vu-verify.out b/test/JDBC/expected/TestSpatialPoint-vu-verify.out index 0217f0f9ca..effe3902e8 100644 --- a/test/JDBC/expected/TestSpatialPoint-vu-verify.out +++ b/test/JDBC/expected/TestSpatialPoint-vu-verify.out @@ -72,6 +72,9 @@ POINT(47.651 -22.349) POINT(47.651 -22.349) POINT(1 2) POINT(47.651 -22.349) +POINT(47.651 -22.349) +POINT(1 2) +POINT(47.651 -22.349) ~~END~~ @@ -86,6 +89,9 @@ varbinary 010100000017D9CEF753D34740D34D6210585936C0 0101000000000000000000F03F0000000000000040 010100000017D9CEF753D34740D34D6210585936C0 +010100000017D9CEF753D34740D34D6210585936C0 +0101000000000000000000F03F0000000000000040 +010100000017D9CEF753D34740D34D6210585936C0 ~~END~~ @@ -100,6 +106,9 @@ float#!#float 47.651#!#-22.349 1.0#!#2.0 47.651#!#-22.349 +47.651#!#-22.349 +1.0#!#2.0 +47.651#!#-22.349 ~~END~~ @@ -124,6 +133,9 @@ E6100000010C000000000000F03F0000000000000040 E6100000010C17D9CEF753D34740D34D6210585936C0 E6100000010C000000000000F03F0000000000000040 E6100000010C17D9CEF753D34740D34D6210585936C0 +E6100000010C17D9CEF753D34740D34D6210585936C0 +E6100000010C000000000000F03F0000000000000040 +00000000010C17D9CEF753D34740D34D6210585936C0 ~~END~~ @@ -210,6 +222,8 @@ POINT(1 2) POINT(47.651 -22.349) POINT(1 2) POINT(-22.349 47.651) +POINT(47.651 -22.349) +POINT(1 2) ~~END~~ @@ -223,6 +237,8 @@ varbinary 010100000017D9CEF753D34740D34D6210585936C0 0101000000000000000000F03F0000000000000040 0101000000D34D6210585936C017D9CEF753D34740 +010100000017D9CEF753D34740D34D6210585936C0 +0101000000000000000000F03F0000000000000040 ~~END~~ @@ -236,6 +252,8 @@ float#!#float 47.651#!#-22.349 1.0#!#2.0 -22.349#!#47.651 +47.651#!#-22.349 +1.0#!#2.0 ~~END~~ @@ -249,6 +267,8 @@ E6100000010C0000000000000040000000000000F03F E6100000010CD34D6210585936C017D9CEF753D34740 E6100000010C0000000000000040000000000000F03F E6100000010C17D9CEF753D34740D34D6210585936C0 +E6100000010CD34D6210585936C017D9CEF753D34740 +E6100000010C0000000000000040000000000000F03F ~~END~~ @@ -259,19 +279,33 @@ geography#!#geography#!#float E6100000010CD34D6210585936C017D9CEF753D34740#!#E6100000010C0000000000000040000000000000F03F#!#5736178.674863189 E6100000010CD34D6210585936C017D9CEF753D34740#!#E6100000010C0000000000000040000000000000F03F#!#5736178.674863189 E6100000010CD34D6210585936C017D9CEF753D34740#!#E6100000010C17D9CEF753D34740D34D6210585936C0#!#1.0424362254827898E7 +E6100000010CD34D6210585936C017D9CEF753D34740#!#E6100000010C0000000000000040000000000000F03F#!#5736178.674863189 E6100000010C0000000000000040000000000000F03F#!#E6100000010CD34D6210585936C017D9CEF753D34740#!#5736178.674863189 E6100000010C0000000000000040000000000000F03F#!#E6100000010CD34D6210585936C017D9CEF753D34740#!#5736178.674863189 E6100000010C0000000000000040000000000000F03F#!#E6100000010C17D9CEF753D34740D34D6210585936C0#!#5535965.307328846 +E6100000010C0000000000000040000000000000F03F#!#E6100000010CD34D6210585936C017D9CEF753D34740#!#5736178.674863189 E6100000010CD34D6210585936C017D9CEF753D34740#!#E6100000010C0000000000000040000000000000F03F#!#5736178.674863189 E6100000010CD34D6210585936C017D9CEF753D34740#!#E6100000010C0000000000000040000000000000F03F#!#5736178.674863189 E6100000010CD34D6210585936C017D9CEF753D34740#!#E6100000010C17D9CEF753D34740D34D6210585936C0#!#1.0424362254827898E7 +E6100000010CD34D6210585936C017D9CEF753D34740#!#E6100000010C0000000000000040000000000000F03F#!#5736178.674863189 E6100000010C0000000000000040000000000000F03F#!#E6100000010CD34D6210585936C017D9CEF753D34740#!#5736178.674863189 E6100000010C0000000000000040000000000000F03F#!#E6100000010CD34D6210585936C017D9CEF753D34740#!#5736178.674863189 E6100000010C0000000000000040000000000000F03F#!#E6100000010C17D9CEF753D34740D34D6210585936C0#!#5535965.307328846 +E6100000010C0000000000000040000000000000F03F#!#E6100000010CD34D6210585936C017D9CEF753D34740#!#5736178.674863189 +E6100000010C17D9CEF753D34740D34D6210585936C0#!#E6100000010CD34D6210585936C017D9CEF753D34740#!#1.0424362254827898E7 +E6100000010C17D9CEF753D34740D34D6210585936C0#!#E6100000010C0000000000000040000000000000F03F#!#5535965.307328846 E6100000010C17D9CEF753D34740D34D6210585936C0#!#E6100000010CD34D6210585936C017D9CEF753D34740#!#1.0424362254827898E7 E6100000010C17D9CEF753D34740D34D6210585936C0#!#E6100000010C0000000000000040000000000000F03F#!#5535965.307328846 E6100000010C17D9CEF753D34740D34D6210585936C0#!#E6100000010CD34D6210585936C017D9CEF753D34740#!#1.0424362254827898E7 E6100000010C17D9CEF753D34740D34D6210585936C0#!#E6100000010C0000000000000040000000000000F03F#!#5535965.307328846 +E6100000010CD34D6210585936C017D9CEF753D34740#!#E6100000010C0000000000000040000000000000F03F#!#5736178.674863189 +E6100000010CD34D6210585936C017D9CEF753D34740#!#E6100000010C0000000000000040000000000000F03F#!#5736178.674863189 +E6100000010CD34D6210585936C017D9CEF753D34740#!#E6100000010C17D9CEF753D34740D34D6210585936C0#!#1.0424362254827898E7 +E6100000010CD34D6210585936C017D9CEF753D34740#!#E6100000010C0000000000000040000000000000F03F#!#5736178.674863189 +E6100000010C0000000000000040000000000000F03F#!#E6100000010CD34D6210585936C017D9CEF753D34740#!#5736178.674863189 +E6100000010C0000000000000040000000000000F03F#!#E6100000010CD34D6210585936C017D9CEF753D34740#!#5736178.674863189 +E6100000010C0000000000000040000000000000F03F#!#E6100000010C17D9CEF753D34740D34D6210585936C0#!#5535965.307328846 +E6100000010C0000000000000040000000000000F03F#!#E6100000010CD34D6210585936C017D9CEF753D34740#!#5736178.674863189 ~~END~~ @@ -285,15 +319,20 @@ E6100000010C0000000000000040000000000000F03F E6100000010CD34D6210585936C017D9CEF753D34740 E6100000010C0000000000000040000000000000F03F E6100000010C17D9CEF753D34740D34D6210585936C0 +E6100000010CD34D6210585936C017D9CEF753D34740 +E6100000010C0000000000000040000000000000F03F ~~END~~ SELECT * FROM SPATIALPOINT_dt; GO ~~START~~ -geometry#!#geography -E6100000010C17D9CEF753D34740D34D6210585936C0#!# -#!#E6100000010CD34D6210585936C017D9CEF753D34740 -E6100000010C000000000000F03F0000000000000040#!#E6100000010C0000000000000040000000000000F03F +int#!#geometry#!#geography +1#!#E6100000010C17D9CEF753D34740D34D6210585936C0#!# +2#!##!#E6100000010CD34D6210585936C017D9CEF753D34740 +3#!#E6100000010C000000000000F03F0000000000000040#!#E6100000010C0000000000000040000000000000F03F +4#!#E6100000010C17D9CEF753D34740D34D6210585936C0#!# +5#!##!#E6100000010CD34D6210585936C017D9CEF753D34740 +6#!#E6100000010C000000000000F03F0000000000000040#!#E6100000010C0000000000000040000000000000F03F ~~END~~ diff --git a/test/JDBC/input/datatypes/TestSpatialPoint-vu-cleanup.sql b/test/JDBC/input/datatypes/TestSpatialPoint-vu-cleanup.txt similarity index 92% rename from test/JDBC/input/datatypes/TestSpatialPoint-vu-cleanup.sql rename to test/JDBC/input/datatypes/TestSpatialPoint-vu-cleanup.txt index d2f24215ac..5ad69e2c46 100644 --- a/test/JDBC/input/datatypes/TestSpatialPoint-vu-cleanup.sql +++ b/test/JDBC/input/datatypes/TestSpatialPoint-vu-cleanup.txt @@ -1,41 +1,27 @@ DROP VIEW IF EXISTS TextFromGeom -GO DROP VIEW IF EXISTS BinaryFromGeom -GO DROP VIEW IF EXISTS CoordsFromGeom -GO DROP VIEW IF EXISTS point_distances_geom -GO DROP VIEW IF EXISTS TextFromGeog -GO DROP VIEW IF EXISTS BinaryFromGeog -GO DROP VIEW IF EXISTS CoordsFromGeog -GO DROP VIEW IF EXISTS TransformFromGeog -GO DROP VIEW IF EXISTS point_distances_geog -GO DROP TABLE IF EXISTS SPATIALPOINTGEOM_dt -GO DROP TABLE IF EXISTS TypeTable -GO DROP TYPE IF EXISTS geom -GO DROP TABLE IF EXISTS SPATIALPOINTGEOG_dt -GO DROP TABLE IF EXISTS SPATIALPOINT_dt -GO diff --git a/test/JDBC/input/datatypes/TestSpatialPoint-vu-prepare.sql b/test/JDBC/input/datatypes/TestSpatialPoint-vu-prepare.sql deleted file mode 100644 index 99096829d1..0000000000 --- a/test/JDBC/input/datatypes/TestSpatialPoint-vu-prepare.sql +++ /dev/null @@ -1,240 +0,0 @@ -CREATE TABLE SPATIALPOINTGEOM_dt (location geometry) -GO - --- Geometry Test Cases - --- Positive Test for STGeomFromText with SRID 4326 -INSERT INTO SPATIALPOINTGEOM_dt (location) -VALUES ( geometry::STGeomFromText('Point(47.65100 -22.34900)', 4326) ) -GO -INSERT INTO SPATIALPOINTGEOM_dt (location) -VALUES ( geometry::STGeomFromText('Point(1.0 2.0)', 4326) ) -GO - --- Positive Test for STGeomFromText with SRID 0 -INSERT INTO SPATIALPOINTGEOM_dt (location) -VALUES ( geometry::STGeomFromText('Point(47.65100 -22.34900)', 0) ) -GO - --- Negative Test for STGeomFromText when SRID is not provided -INSERT INTO SPATIALPOINTGEOM_dt (location) -VALUES ( geometry::STGeomFromText('Point(47.65100 -22.34900)') ) -GO - --- Negative Test for STGeomFromText when SRID >= 10^6 --- SRID should be between 0 to 999999 -INSERT INTO SPATIALPOINTGEOM_dt (location) -VALUES ( geometry::STGeomFromText('Point(47.65100 -22.34900)', 1000000000 ) ) -GO - --- Negative Test for STGeomFromText with SRID < 0 --- SRID should be between 0 to 999999 -INSERT INTO SPATIALPOINTGEOM_dt (location) -VALUES ( geometry::STGeomFromText('Point(47.65100 -22.34900)', -1) ) -GO - --- Negative Test for STGeomFromText when a coordinate is missing -INSERT INTO SPATIALPOINTGEOM_dt (location) -VALUES ( geometry::STGeomFromText('Point(1.0 )', 4326) ) -GO - --- Negative Test for STGeomFromText when invalid type is provided -INSERT INTO SPATIALPOINTGEOM_dt (location) -VALUES ( geometry::STGeomFromText('Pnt', 4326) ) -GO - --- Test for STGeomFromText when null Point is Given -> Returns NBCRow -INSERT INTO SPATIALPOINTGEOM_dt (location) -VALUES ( geometry::STGeomFromText(null, 4326) ) -GO - --- -- Negative Test for STGeomFromText when Incorrect cast is provided --- INSERT INTO SPATIALPOINTGEOM_dt (location) --- VALUES ( geography::STGeomFromText('Point(47.65100 -22.34900)', 4326) ) --- GO - --- Positive Test for STPointFromText with SRID 4326. Rest are same as STGeomFromText -INSERT INTO SPATIALPOINTGEOM_dt (location) -VALUES ( geometry::STPointFromText('Point(47.65100 -22.34900)', 4326) ) -GO -INSERT INTO SPATIALPOINTGEOM_dt (location) -VALUES ( geometry::STPointFromText('Point(1.0 2.0)', 4326) ) -GO - --- Positive Test for Point with SRID 4326 -INSERT INTO SPATIALPOINTGEOM_dt (location) -VALUES ( geometry::Point(47.65100, -22.34900, 4326) ) -GO - -CREATE VIEW TextFromGeom AS -SELECT STAsText(location) AS TextRepresentation -FROM SPATIALPOINTGEOM_dt; -GO - -CREATE VIEW BinaryFromGeom AS -SELECT STAsBinary(location) AS BinaryRepresentation -FROM SPATIALPOINTGEOM_dt; -GO - -CREATE VIEW CoordsFromGeom AS -SELECT STX(location), STY(location) AS Coordinates -FROM SPATIALPOINTGEOM_dt; -GO - -CREATE VIEW point_distances_geom AS -SELECT - p1.location AS point1, - p2.location AS point2, - STDistance( p1.location, p2.location ) AS distance -FROM - SPATIALPOINTGEOM_dt p1 -CROSS JOIN - SPATIALPOINTGEOM_dt p2 -WHERE - p1.location <> p2.location; -GO - -CREATE TABLE SPATIALPOINTGEOG_dt (location geography) -GO - --- Create Type Test Case currently Babelfish supports it but TSQL doesn't for spatial Types, Although it doesn't break anything --- TODO: Make it similar to T-SQL -CREATE TYPE geom -FROM geometry NOT NULL ; -GO - -CREATE TABLE TypeTable(ID INT PRIMARY KEY, Shape geom) -GO - -INSERT INTO TypeTable(ID, Shape) -VALUES(1, geometry::Point(1, 2, 4326)); -GO - --- Geography Test Cases - --- Positive Test for STGeomFromText with SRID 4326 -INSERT INTO SPATIALPOINTGEOG_dt (location) -VALUES ( geography::STGeomFromText('Point(47.65100 -22.34900)', 4326) ) -GO -INSERT INTO SPATIALPOINTGEOG_dt (location) -VALUES ( geography::STGeomFromText('Point(1.0 2.0)', 4326) ) -GO - --- Negative Test for STGeomFromText for Geography with SRID 0 -INSERT INTO SPATIALPOINTGEOG_dt (location) -VALUES ( geography::STGeomFromText('Point(47.65100 -22.34900)', 0) ) -GO - --- Negative Test for STGeomFromText for Geography when lat > 90 or < -90 -INSERT INTO SPATIALPOINTGEOG_dt (location) -VALUES ( geography::STGeomFromText('Point(47.65100 -122.34900)', 4326) ) -GO - --- Negative Test for STGeomFromText when SRID is not provided -INSERT INTO SPATIALPOINTGEOG_dt (location) -VALUES ( geography::STGeomFromText('Point(47.65100 -22.34900)') ) -GO - --- Negative Test for STGeomFromText when cast is not provided -INSERT INTO SPATIALPOINTGEOG_dt (location) -VALUES ( STGeomFromText('Point(47.65100 -22.34900)', 4326) ) -GO - --- -- Negative Test for STGeomFromText when incorrect cast is provided --- INSERT INTO SPATIALPOINTGEOG_dt (location) --- VALUES ( geometry::STGeomFromText('Point(47.65100 -22.34900)', 4326) ) --- GO - --- Negative Test for STGeomFromText when SRID >= 10^6 -INSERT INTO SPATIALPOINTGEOG_dt (location) -VALUES ( geography::STGeomFromText('Point(47.65100 -22.34900)', 1000000000 ) ) -GO - --- Negative Test for STGeomFromText with SRID < 0 -INSERT INTO SPATIALPOINTGEOG_dt (location) -VALUES ( geography::STGeomFromText('Point(47.65100 -22.34900)', -1) ) -GO - --- Negative Test for STGeomFromText when a coordinate is missing -INSERT INTO SPATIALPOINTGEOG_dt (location) -VALUES ( geography::STGeomFromText('Point(1.0 )', 4326) ) -GO - --- Negative Test for STGeomFromText when invalid type is provided -INSERT INTO SPATIALPOINTGEOG_dt (location) -VALUES ( geography::STGeomFromText('Pnt', 4326) ) -GO - --- Test for STGeomFromText when null Point is Given -> Returns NBCRow -INSERT INTO SPATIALPOINTGEOG_dt (location) -VALUES ( geography::STGeomFromText(null, 4326) ) -GO - --- Positive Test for STPointFromText with SRID 4326. Rest are same as STGeomFromText -INSERT INTO SPATIALPOINTGEOG_dt (location) -VALUES ( geography::STPointFromText('Point(47.65100 -22.34900)', 4326) ) -GO -INSERT INTO SPATIALPOINTGEOG_dt (location) -VALUES ( geography::STPointFromText('Point(1.0 2.0)', 4326) ) -GO - --- Negative Test for STPointFromText for Geography when lat > 90 or < -90 -INSERT INTO SPATIALPOINTGEOG_dt (location) -VALUES ( geography::STPointFromText('Point(47.65100 122.34900)', 4326) ) -GO - --- Positive Test for Point with SRID 4326 -INSERT INTO SPATIALPOINTGEOG_dt (location) -VALUES ( geography::Point(47.65100, -22.34900, 4326) ) -GO - --- Negative Test for Point for Geography when lat > 90 or < -90 -INSERT INTO SPATIALPOINTGEOG_dt (location) -VALUES ( geography::Point(147.65100, -22.34900, 4326) ) -GO - -CREATE VIEW TextFromGeog AS -SELECT STAsText(location) AS TextRepresentation -FROM SPATIALPOINTGEOG_dt; -GO - -CREATE VIEW BinaryFromGeog AS -SELECT STAsBinary(location) AS BinaryRepresentation -FROM SPATIALPOINTGEOG_dt; -GO - -CREATE VIEW CoordsFromGeog AS -SELECT long(location), lat(location) AS Coordinates -FROM SPATIALPOINTGEOG_dt; -GO - - -CREATE VIEW TransformFromGeog AS -SELECT ST_Transform(location, 4326) AS Modified_points -FROM SPATIALPOINTGEOG_dt; -GO - -CREATE VIEW point_distances_geog AS -SELECT - p1.location AS point1, - p2.location AS point2, - STDistance( p1.location, p2.location ) AS distance -FROM - SPATIALPOINTGEOG_dt p1 -CROSS JOIN - SPATIALPOINTGEOG_dt p2 -WHERE - p1.location <> p2.location; -GO - -CREATE TABLE SPATIALPOINT_dt (GeomColumn geometry, GeogColumn geography) -GO -INSERT INTO SPATIALPOINT_dt (GeomColumn) -VALUES ( geometry::STGeomFromText('Point(47.65100 -22.34900)', 4326) ) -GO -INSERT INTO SPATIALPOINT_dt (GeogColumn) -VALUES ( geography::STGeomFromText('Point(47.65100 -22.34900)', 4326) ) -GO -INSERT INTO SPATIALPOINT_dt (GeomColumn, GeogColumn) -VALUES ( geometry::STGeomFromText('Point(1.0 2.0)', 4326), geography::STGeomFromText('Point(1.0 2.0)', 4326) ) -GO diff --git a/test/JDBC/input/datatypes/TestSpatialPoint-vu-prepare.txt b/test/JDBC/input/datatypes/TestSpatialPoint-vu-prepare.txt new file mode 100644 index 0000000000..2f21076b80 --- /dev/null +++ b/test/JDBC/input/datatypes/TestSpatialPoint-vu-prepare.txt @@ -0,0 +1,180 @@ +CREATE TABLE SPATIALPOINTGEOM_dt (location geometry) + +#Geometry Test Cases + +#Positive Test for STGeomFromText with SRID 4326 +INSERT INTO SPATIALPOINTGEOM_dt (location) VALUES ( geometry::STGeomFromText('Point(47.65100 -22.34900)', 4326) ) + +INSERT INTO SPATIALPOINTGEOM_dt (location) VALUES ( geometry::STGeomFromText('Point(1.0 2.0)', 4326) ) + +#Positive Test for STGeomFromText with SRID 0 +INSERT INTO SPATIALPOINTGEOM_dt (location) VALUES ( geometry::STGeomFromText('Point(47.65100 -22.34900)', 0) ) + +#Negative Test for STGeomFromText when SRID is not provided +INSERT INTO SPATIALPOINTGEOM_dt (location) VALUES ( geometry::STGeomFromText('Point(47.65100 -22.34900)') ) + +#Negative Test for STGeomFromText when SRID >= 10^6 +#SRID should be between 0 to 999999 +INSERT INTO SPATIALPOINTGEOM_dt (location) VALUES ( geometry::STGeomFromText('Point(47.65100 -22.34900)', 1000000000 ) ) + +#Negative Test for STGeomFromText with SRID < 0 +#SRID should be between 0 to 999999 +INSERT INTO SPATIALPOINTGEOM_dt (location) VALUES ( geometry::STGeomFromText('Point(47.65100 -22.34900)', -1) ) + +#Negative Test for STGeomFromText when a coordinate is missing +INSERT INTO SPATIALPOINTGEOM_dt (location) VALUES ( geometry::STGeomFromText('Point(1.0 )', 4326) ) + +#Negative Test for STGeomFromText when invalid type is provided +INSERT INTO SPATIALPOINTGEOM_dt (location) VALUES ( geometry::STGeomFromText('Pnt', 4326) ) + +#Test for STGeomFromText when null Point is Given -> Returns NBCRow +INSERT INTO SPATIALPOINTGEOM_dt (location) VALUES ( geometry::STGeomFromText(null, 4326) ) + +#Negative Test for STGeomFromText when Incorrect cast is provided +#INSERT INTO SPATIALPOINTGEOM_dt (location) VALUES ( geography::STGeomFromText('Point(47.65100 -22.34900)', 4326) ) + +#Positive Test for STPointFromText with SRID 4326. Rest are same as STGeomFromText +INSERT INTO SPATIALPOINTGEOM_dt (location) VALUES ( geometry::STPointFromText('Point(47.65100 -22.34900)', 4326) ) + +INSERT INTO SPATIALPOINTGEOM_dt (location) VALUES ( geometry::STPointFromText('Point(1.0 2.0)', 4326) ) + + +#Positive Test for Point with SRID 4326 +INSERT INTO SPATIALPOINTGEOM_dt (location) VALUES ( geometry::Point(47.65100, -22.34900, 4326) ) + +#Tests for Geometry type Prepared Statements +prepst#!#INSERT INTO SPATIALPOINTGEOM_dt(location) values(@location) #!#GEOMETRY|-|location|-|Point(47.65100 -22.34900):4326 +prepst#!#exec#!#GEOMETRY|-|location|-|Point(1.0 2.0):4326 +prepst#!#exec#!#GEOMETRY|-|location|-|Point(47.65100 -22.34900):0 +#Negative Test for STGeomFromText when SRID >= 10^6 +prepst#!#exec#!#GEOMETRY|-|location|-|Point(47.65100 -22.34900):1000000000 +#Negative Test for STGeomFromText with SRID < 0 +prepst#!#exec#!#GEOMETRY|-|location|-|Point(47.65100 -22.34900):-1 +#Negative Test for STGeomFromText when SRID is NULL +prepst#!#exec#!#GEOMETRY|-|location|-|Point(47.65100 -22.34900): +#Negative Test for STGeomFromText when a coordinate is missing +prepst#!#exec#!#GEOMETRY|-|location|-|Point(1.0 ):4326 +#Negative Test when an unsupported feature in queried +prepst#!#exec#!#GEOMETRY|-|location|-|Point(1.0 2.0 3.0 4.0):4326 +prepst#!#exec#!#GEOMETRY|-|location|-|LINESTRING(1 2, 3 4):4326 +#Negative Test for STGeomFromText when invalid type is provided +prepst#!#exec#!#GEOMETRY|-|location|-|Pnt:4326 +#Negative Test for STGeomFromText when Null geometry is provided +prepst#!#exec#!#GEOMETRY|-|location|-|:4326 + +CREATE VIEW TextFromGeom AS SELECT STAsText(location) AS TextRepresentation FROM SPATIALPOINTGEOM_dt; + +CREATE VIEW BinaryFromGeom AS SELECT STAsBinary(location) AS BinaryRepresentation FROM SPATIALPOINTGEOM_dt; + +CREATE VIEW CoordsFromGeom AS SELECT STX(location), STY(location) AS Coordinates FROM SPATIALPOINTGEOM_dt; + +CREATE VIEW point_distances_geom AS SELECT p1.location AS point1, p2.location AS point2, STDistance( p1.location, p2.location ) AS distance FROM SPATIALPOINTGEOM_dt p1 CROSS JOIN SPATIALPOINTGEOM_dt p2 WHERE p1.location <> p2.location; + +CREATE TABLE SPATIALPOINTGEOG_dt (location geography) + +#Create Type Test Case currently Babelfish supports it but TSQL doesn't for spatial Types, Although it doesn't break anything +#TODO: Make it similar to T-SQL +CREATE TYPE geom FROM geometry NOT NULL ; + +CREATE TABLE TypeTable(ID INT PRIMARY KEY, Shape geom) + +INSERT INTO TypeTable(ID, Shape) VALUES(1, geometry::Point(1, 2, 4326)); + +#Geography Test Cases + +#Positive Test for STGeomFromText with SRID 4326 +INSERT INTO SPATIALPOINTGEOG_dt (location) VALUES ( geography::STGeomFromText('Point(47.65100 -22.34900)', 4326) ) + +INSERT INTO SPATIALPOINTGEOG_dt (location) VALUES ( geography::STGeomFromText('Point(1.0 2.0)', 4326) ) + +#Negative Test for STGeomFromText for Geography with SRID 0 +INSERT INTO SPATIALPOINTGEOG_dt (location) VALUES ( geography::STGeomFromText('Point(47.65100 -22.34900)', 0) ) + +#Negative Test for STGeomFromText for Geography when lat > 90 or < -90 +INSERT INTO SPATIALPOINTGEOG_dt (location) VALUES ( geography::STGeomFromText('Point(47.65100 -122.34900)', 4326) ) + +#Negative Test for STGeomFromText when SRID is not provided +INSERT INTO SPATIALPOINTGEOG_dt (location) VALUES ( geography::STGeomFromText('Point(47.65100 -22.34900)') ) + +#Negative Test for STGeomFromText when cast is not provided +INSERT INTO SPATIALPOINTGEOG_dt (location) VALUES ( STGeomFromText('Point(47.65100 -22.34900)', 4326) ) + +#Negative Test for STGeomFromText when incorrect cast is provided +#INSERT INTO SPATIALPOINTGEOG_dt (location) VALUES ( geometry::STGeomFromText('Point(47.65100 -22.34900)', 4326) ) + +#Negative Test for STGeomFromText when SRID >= 10^6 +INSERT INTO SPATIALPOINTGEOG_dt (location) VALUES ( geography::STGeomFromText('Point(47.65100 -22.34900)', 1000000000 ) ) + +#Negative Test for STGeomFromText with SRID < 0 +INSERT INTO SPATIALPOINTGEOG_dt (location) VALUES ( geography::STGeomFromText('Point(47.65100 -22.34900)', -1) ) + +#Negative Test for STGeomFromText when a coordinate is missing +INSERT INTO SPATIALPOINTGEOG_dt (location) VALUES ( geography::STGeomFromText('Point(1.0 )', 4326) ) + +#Negative Test for STGeomFromText when invalid type is provided +INSERT INTO SPATIALPOINTGEOG_dt (location) VALUES ( geography::STGeomFromText('Pnt', 4326) ) + +#Test for STGeomFromText when null Point is Given -> Returns NBCRow +INSERT INTO SPATIALPOINTGEOG_dt (location) VALUES ( geography::STGeomFromText(null, 4326) ) + +#Positive Test for STPointFromText with SRID 4326. Rest are same as STGeomFromText +INSERT INTO SPATIALPOINTGEOG_dt (location) VALUES ( geography::STPointFromText('Point(47.65100 -22.34900)', 4326) ) + +INSERT INTO SPATIALPOINTGEOG_dt (location) VALUES ( geography::STPointFromText('Point(1.0 2.0)', 4326) ) + +#Negative Test for STPointFromText for Geography when lat > 90 or < -90 +INSERT INTO SPATIALPOINTGEOG_dt (location) VALUES ( geography::STPointFromText('Point(47.65100 122.34900)', 4326) ) + +#Positive Test for Point with SRID 4326 +INSERT INTO SPATIALPOINTGEOG_dt (location) VALUES ( geography::Point(47.65100, -22.34900, 4326) ) + +#Negative Test for Point for Geography when lat > 90 or < -90 +INSERT INTO SPATIALPOINTGEOG_dt (location) VALUES ( geography::Point(147.65100, -22.34900, 4326) ) + +#Tests for Geography type Prepared Statements +prepst#!#INSERT INTO SPATIALPOINTGEOG_dt(location) values(@location) #!#GEOGRAPHY|-|location|-|Point(47.65100 -22.34900):4326 +prepst#!#exec#!#GEOGRAPHY|-|location|-|Point(1.0 2.0):4326 +#Negative Test for STGeomFromText for Geography with SRID 0 +prepst#!#exec#!#GEOGRAPHY|-|location|-|Point(47.65100 -22.34900):0 +#Negative Test for STGeomFromText for Geography when lat > 90 or < -90 +prepst#!#exec#!#GEOGRAPHY|-|location|-|Point(47.65100 -122.34900):4326 +#Negative Test for STGeomFromText when SRID >= 10^6 +prepst#!#exec#!#GEOGRAPHY|-|location|-|Point(47.65100 -22.34900):1000000000 +#Negative Test for STGeomFromText with SRID < 0 +prepst#!#exec#!#GEOGRAPHY|-|location|-|Point(47.65100 -22.34900):-1 +#Negative Test for STGeomFromText with SRID is NULL +prepst#!#exec#!#GEOGRAPHY|-|location|-|Point(47.65100 -22.34900): +#Negative Test for STGeomFromText when a coordinate is missing +prepst#!#exec#!#GEOGRAPHY|-|location|-|Point(1.0 ):4326 +#Negative Test when an unsupported feature in queried +prepst#!#exec#!#GEOGRAPHY|-|location|-|Point(1.0 2.0 3.0 4.0):4326 +prepst#!#exec#!#GEOGRAPHY|-|location|-|LINESTRING(1 2, 3 4):4326 +#Negative Test for STGeomFromText when invalid type is provided +prepst#!#exec#!#GEOGRAPHY|-|location|-|Pnt:4326 +#Negative Test for STGeomFromText when Null geography is provided +prepst#!#exec#!#GEOGRAPHY|-|location|-|:4326 + +CREATE VIEW TextFromGeog AS SELECT STAsText(location) AS TextRepresentation FROM SPATIALPOINTGEOG_dt; + +CREATE VIEW BinaryFromGeog AS SELECT STAsBinary(location) AS BinaryRepresentation FROM SPATIALPOINTGEOG_dt; + +CREATE VIEW CoordsFromGeog AS SELECT long(location), lat(location) AS Coordinates FROM SPATIALPOINTGEOG_dt; + + +CREATE VIEW TransformFromGeog AS SELECT ST_Transform(location, 4326) AS Modified_points FROM SPATIALPOINTGEOG_dt; + +CREATE VIEW point_distances_geog AS SELECT p1.location AS point1, p2.location AS point2, STDistance( p1.location, p2.location ) AS distance FROM SPATIALPOINTGEOG_dt p1 CROSS JOIN SPATIALPOINTGEOG_dt p2 WHERE p1.location <> p2.location; + +CREATE TABLE SPATIALPOINT_dt (PrimaryKey int, GeomColumn geometry, GeogColumn geography) + +INSERT INTO SPATIALPOINT_dt (PrimaryKey, GeomColumn) VALUES ( 1, geometry::STGeomFromText('Point(47.65100 -22.34900)', 4326) ) + +INSERT INTO SPATIALPOINT_dt (PrimaryKey, GeogColumn) VALUES ( 2, geography::STGeomFromText('Point(47.65100 -22.34900)', 4326) ) + +INSERT INTO SPATIALPOINT_dt (PrimaryKey, GeomColumn, GeogColumn) VALUES ( 3, geometry::STGeomFromText('Point(1.0 2.0)', 4326), geography::STGeomFromText('Point(1.0 2.0)', 4326) ) + + +#Tests for Spatial type Prepared Statements +prepst#!#INSERT INTO SPATIALPOINT_dt(PrimaryKey, GeomColumn) values(@PrimaryKey, @GeomColumn) #!#int|-|PrimaryKey|-|4#!#GEOMETRY|-|GeomColumn|-|Point(47.65100 -22.34900):4326 +prepst#!#INSERT INTO SPATIALPOINT_dt(PrimaryKey, GeogColumn) values(@PrimaryKey, @GeogColumn) #!#int|-|PrimaryKey|-|5#!#GEOGRAPHY|-|GeogColumn|-|Point(47.65100 -22.34900):4326 +prepst#!#INSERT INTO SPATIALPOINT_dt(PrimaryKey, GeomColumn, GeogColumn) values(@PrimaryKey, @GeomColumn, @GeogColumn) #!#int|-|PrimaryKey|-|6#!#GEOMETRY|-|GeomColumn|-|Point(1.0 2.0):4326#!#GEOGRAPHY|-|GeogColumn|-|Point(1.0 2.0):4326 diff --git a/test/JDBC/src/main/java/com/sqlsamples/JDBCPreparedStatement.java b/test/JDBC/src/main/java/com/sqlsamples/JDBCPreparedStatement.java index 12a88c348f..a64c2d405e 100644 --- a/test/JDBC/src/main/java/com/sqlsamples/JDBCPreparedStatement.java +++ b/test/JDBC/src/main/java/com/sqlsamples/JDBCPreparedStatement.java @@ -2,6 +2,8 @@ import com.microsoft.sqlserver.jdbc.SQLServerDataTable; import com.microsoft.sqlserver.jdbc.SQLServerPreparedStatement; +import com.microsoft.sqlserver.jdbc.Geometry; +import com.microsoft.sqlserver.jdbc.Geography; import microsoft.sql.DateTimeOffset; import org.apache.logging.log4j.Logger; @@ -185,6 +187,30 @@ static void set_bind_values(String[] result, PreparedStatement pstmt, BufferedWr SQLServerPreparedStatement ssPstmt = (SQLServerPreparedStatement) pstmt; ssPstmt.setStructured(j - 1, parameter[1], sourceDataTable); pstmt = ssPstmt; + } else if (parameter[0].equalsIgnoreCase("geometry")) { + String[] arguments = parameter[2].split(":", 2); + String geoWKT = arguments[0]; + int srid = -1; + try{ + srid = Integer.parseInt(arguments[1]); + } finally { + Geometry geomWKT = Geometry.STGeomFromText(geoWKT, srid); + SQLServerPreparedStatement ssPstmt = (SQLServerPreparedStatement) pstmt; + ssPstmt.setGeometry(j - 1, geomWKT); + pstmt = ssPstmt; + } + } else if (parameter[0].equalsIgnoreCase("geography")) { + String[] arguments = parameter[2].split(":", 2); + String geoWKT = arguments[0]; + int srid = -1; + try{ + srid = Integer.parseInt(arguments[1]); + } finally { + Geography geogWKT = Geography.STGeomFromText(geoWKT, srid); + SQLServerPreparedStatement ssPstmt = (SQLServerPreparedStatement) pstmt; + ssPstmt.setGeography(j - 1, geogWKT); + pstmt = ssPstmt; + } } } catch (SQLException se) { handleSQLExceptionWithFile(se, bw, logger); @@ -194,6 +220,8 @@ static void set_bind_values(String[] result, PreparedStatement pstmt, BufferedWr logger.error("IO Exception: " + e.getMessage(), e); } catch (ParseException e) { logger.error("Parse Exception: " + e.getMessage(), e); + } catch (NumberFormatException e) { + logger.error("Number Format Exception: " + e.getMessage(), e); } } } diff --git a/test/dotnet/ExpectedOutput/TestPoint.out b/test/dotnet/ExpectedOutput/TestPoint.out new file mode 100644 index 0000000000..402c335bfc --- /dev/null +++ b/test/dotnet/ExpectedOutput/TestPoint.out @@ -0,0 +1,50 @@ +#Q#CREATE TABLE POINTGEOM_dt(location GEOMETRY); +#Q#INSERT INTO POINTGEOM_dt(location) values(@location) +#Q#INSERT INTO POINTGEOM_dt(location) values(@location) +#Q#INSERT INTO POINTGEOM_dt(location) values(@location) +#Q#INSERT INTO POINTGEOM_dt(location) values(@location) +#E#Unsupported geometry type +#Q#INSERT INTO POINTGEOM_dt(location) values(@location) +#E#Unsupported geometry type +#Q#CREATE TABLE POINTGEOG_dt(location GEOGRAPHY); +#Q#INSERT INTO POINTGEOG_dt(location) values(@location) +#Q#INSERT INTO POINTGEOG_dt(location) values(@location) +#Q#INSERT INTO POINTGEOG_dt(location) values(@location) +#E#Unsupported geometry type +#Q#INSERT INTO POINTGEOG_dt(location) values(@location) +#E#Unsupported geometry type +#Q#CREATE TABLE POINT_dt(geom GEOMETRY, geog GEOGRAPHY); +#Q#INSERT INTO POINT_dt(geom) values(@geom) +#Q#INSERT INTO POINT_dt(geog) values(@geog) +#Q#INSERT INTO POINT_dt(geom, geog) values(@geom, @geog) +#Q#INSERT INTO POINTGEOM_dt(location) values(geometry::STGeomFromText('Point(47.65100 -22.34900)', 4326)) +#Q#INSERT INTO POINTGEOM_dt(location) values(geometry::STGeomFromText('Point(47.65100 -22.34900)', 0)) +#Q#INSERT INTO POINTGEOM_dt(location) values(geometry::STPointFromText('Point(47.65100 -22.34900)', 4326)) +#Q#INSERT INTO POINTGEOM_dt(location) values(geometry::Point(47.65100, -22.34900, 4326)) +#Q#INSERT INTO POINTGEOG_dt(location) values(geography::STGeomFromText('Point(47.65100 -22.34900)', 4326)) +#Q#INSERT INTO POINTGEOG_dt(location) values(geography::STPointFromText('Point(47.65100 -22.34900)', 4326)) +#Q#INSERT INTO POINTGEOG_dt(location) values(geography::Point(47.65100, -22.34900, 4326)) +#Q#SELECT STAsText(location) FROM POINTGEOM_dt; +#D#text +POINT(47.651 -22.349) +POINT(1 2) +POINT(47.651 -22.349) +POINT(47.651 -22.349) +POINT(47.651 -22.349) +POINT(47.651 -22.349) +POINT(47.651 -22.349) +#Q#SELECT STAsText(location) FROM POINTGEOG_dt; +#D#text +POINT(47.651 -22.349) +POINT(1 2) +POINT(47.651 -22.349) +POINT(47.651 -22.349) +POINT(-22.349 47.651) +#Q#SELECT STAsText(geom), STAsText(geog) FROM POINT_dt; +#D#text#!#text +POINT(47.651 -22.349)#!# +#!#POINT(47.651 -22.349) +POINT(1 2)#!#POINT(1 2) +#Q#DROP TABLE IF EXISTS POINTGEOM_dt; +#Q#DROP TABLE IF EXISTS POINTGEOG_dt; +#Q#DROP TABLE IF EXISTS POINT_dt; diff --git a/test/dotnet/dotnet.csproj b/test/dotnet/dotnet.csproj index bb2a7c168f..c5e9aed6b8 100644 --- a/test/dotnet/dotnet.csproj +++ b/test/dotnet/dotnet.csproj @@ -11,6 +11,7 @@ + all diff --git a/test/dotnet/input/Datatypes/TestPoint.txt b/test/dotnet/input/Datatypes/TestPoint.txt new file mode 100644 index 0000000000..78d9906534 --- /dev/null +++ b/test/dotnet/input/Datatypes/TestPoint.txt @@ -0,0 +1,49 @@ +CREATE TABLE POINTGEOM_dt(location GEOMETRY); +prepst#!#INSERT INTO POINTGEOM_dt(location) values(@location) #!#GEOMETRY|-|location|-|Point(47.65100 -22.34900):4326 +prepst#!#exec#!#GEOMETRY|-|location|-|Point(1.0 2.0):4326 +prepst#!#exec#!#GEOMETRY|-|location|-|Point(47.65100 -22.34900):0 +prepst#!#exec#!#GEOMETRY|-|location|-|Point(1.0 2.0 3.0 4.0):4326 +prepst#!#exec#!#GEOMETRY|-|location|-|LINESTRING(1 2, 3 4):4326 +#next six lines are not allowed +#prepst#!#exec#!#GEOMETRY|-|location|-|Point(47.65100 -22.34900):1000000000 +#prepst#!#exec#!#GEOMETRY|-|location|-|Point(47.65100 -22.34900):-1 +#prepst#!#exec#!#GEOMETRY|-|location|-|Point(47.65100 -22.34900): +#prepst#!#exec#!#GEOMETRY|-|location|-|Point(1.0 ):4326 +#prepst#!#exec#!#GEOMETRY|-|location|-|Pnt:4326 +#prepst#!#exec#!#GEOMETRY|-|location|-|:4326 +CREATE TABLE POINTGEOG_dt(location GEOGRAPHY); +prepst#!#INSERT INTO POINTGEOG_dt(location) values(@location) #!#GEOGRAPHY|-|location|-|Point(47.65100 -22.34900):4326 +prepst#!#exec#!#GEOGRAPHY|-|location|-|Point(1.0 2.0):4326 +prepst#!#exec#!#GEOGRAPHY|-|location|-|Point(1.0 2.0 3.0 4.0):4326 +prepst#!#exec#!#GEOGRAPHY|-|location|-|LINESTRING(1 2, 3 4):4326 +#next eight lines are not allowed +#prepst#!#exec#!#GEOGRAPHY|-|location|-|Point(47.65100 -22.34900):0 +#prepst#!#exec#!#GEOGRAPHY|-|location|-|Point(47.65100 -122.34900):4326 +#prepst#!#exec#!#GEOGRAPHY|-|location|-|Point(47.65100 -22.34900):1000000000 +#prepst#!#exec#!#GEOGRAPHY|-|location|-|Point(47.65100 -22.34900):-1 +#prepst#!#exec#!#GEOGRAPHY|-|location|-|Point(47.65100 -22.34900): +#prepst#!#exec#!#GEOGRAPHY|-|location|-|Point(1.0 ):4326 +#prepst#!#exec#!#GEOGRAPHY|-|location|-|Pnt:4326 +#prepst#!#exec#!#GEOGRAPHY|-|location|-|:4326 +CREATE TABLE POINT_dt(geom GEOMETRY, geog GEOGRAPHY); +prepst#!#INSERT INTO POINT_dt(geom) values(@geom) #!#GEOMETRY|-|geom|-|Point(47.65100 -22.34900):4326 +prepst#!#INSERT INTO POINT_dt(geog) values(@geog) #!#GEOGRAPHY|-|geog|-|Point(47.65100 -22.34900):4326 +prepst#!#INSERT INTO POINT_dt(geom, geog) values(@geom, @geog) #!#GEOMETRY|-|geom|-|Point(1.0 2.0):4326#!#GEOGRAPHY|-|geog|-|Point(1.0 2.0):4326 + + +INSERT INTO POINTGEOM_dt(location) values(geometry::STGeomFromText('Point(47.65100 -22.34900)', 4326)) +INSERT INTO POINTGEOM_dt(location) values(geometry::STGeomFromText('Point(47.65100 -22.34900)', 0)) +INSERT INTO POINTGEOM_dt(location) values(geometry::STPointFromText('Point(47.65100 -22.34900)', 4326)) +INSERT INTO POINTGEOM_dt(location) values(geometry::Point(47.65100, -22.34900, 4326)) + +INSERT INTO POINTGEOG_dt(location) values(geography::STGeomFromText('Point(47.65100 -22.34900)', 4326)) +INSERT INTO POINTGEOG_dt(location) values(geography::STPointFromText('Point(47.65100 -22.34900)', 4326)) +INSERT INTO POINTGEOG_dt(location) values(geography::Point(47.65100, -22.34900, 4326)) + +SELECT STAsText(location) FROM POINTGEOM_dt; +SELECT STAsText(location) FROM POINTGEOG_dt; +SELECT STAsText(geom), STAsText(geog) FROM POINT_dt; + +DROP TABLE IF EXISTS POINTGEOM_dt; +DROP TABLE IF EXISTS POINTGEOG_dt; +DROP TABLE IF EXISTS POINT_dt; diff --git a/test/dotnet/src/PrepareExecBinding.cs b/test/dotnet/src/PrepareExecBinding.cs index 058f6652a4..642f206252 100644 --- a/test/dotnet/src/PrepareExecBinding.cs +++ b/test/dotnet/src/PrepareExecBinding.cs @@ -5,6 +5,7 @@ using System.Data.OleDb; using System.Data.SqlClient; using System.Data.SqlTypes; +using Microsoft.SqlServer.Types; using System.IO; using System.Text; @@ -114,6 +115,42 @@ public static DbCommand SetBindParams(string[] result, sqlCmd.Parameters[param[1].Trim()].Size = 1000; } break; + case "geometry": + { + if (ConfigSetup.Database.Equals("oledb", StringComparison.InvariantCulture)) + { + testUtils.PrintToLogsOrConsole("GEOMETRY NOT SUPPORTED BY OLEDB", logger, "error"); + break; + } + string[] arguments = param[2].Split(':', 2); + string geoWKT = arguments[0]; + int srid = (int)GetSqlDbValue("int", arguments[1]); + + ((SqlParameter)sqlCmd.Parameters[param[1].Trim()]).SqlDbType = SqlDbType.Udt; + ((SqlParameter) sqlCmd.Parameters[param[1].Trim()]).UdtTypeName = "Geometry"; + + sqlCmd.Parameters[param[1].Trim()].Value = SqlGeometry.STGeomFromText(new SqlChars(new SqlString(geoWKT)), srid); + sqlCmd.Parameters[param[1].Trim()].Size = 65535; + } + break; + case "geography": + { + if (ConfigSetup.Database.Equals("oledb", StringComparison.InvariantCulture)) + { + testUtils.PrintToLogsOrConsole("GEOGRAPHY NOT SUPPORTED BY OLEDB", logger, "error"); + break; + } + string[] arguments = param[2].Split(':', 2); + string geoWKT = arguments[0]; + int srid = (int)GetSqlDbValue("int", arguments[1]); + + ((SqlParameter)sqlCmd.Parameters[param[1].Trim()]).SqlDbType = SqlDbType.Udt; + ((SqlParameter)sqlCmd.Parameters[param[1].Trim()]).UdtTypeName = "Geography"; + + sqlCmd.Parameters[param[1].Trim()].Value = SqlGeography.STGeomFromText(new SqlChars(new SqlString(geoWKT)), srid); + sqlCmd.Parameters[param[1].Trim()].Size = 65535; + } + break; default: throw new Exception("DATATYPE NOT SUPPORTED:- " + param[0]); } @@ -233,6 +270,42 @@ public static DbCommand SetBindParams(string[] result, parameter.Size = 1000; } break; + case "geometry": + { + if (ConfigSetup.Database.Equals("oledb", StringComparison.InvariantCulture)) + { + testUtils.PrintToLogsOrConsole("GEOMETRY NOT SUPPORTED BY OLEDB", logger, "error"); + break; + } + string[] arguments = param[2].Split(':', 2); + string geoWKT = arguments[0]; + int srid = (int)GetSqlDbValue("int", arguments[1]);; + + ((SqlParameter)parameter).SqlDbType = SqlDbType.Udt; + ((SqlParameter)parameter).UdtTypeName = "Geometry"; + + parameter.Value = SqlGeometry.STGeomFromText(new SqlChars(new SqlString(geoWKT)), srid); + parameter.Size = 65535; + } + break; + case "geography": + { + if (ConfigSetup.Database.Equals("oledb", StringComparison.InvariantCulture)) + { + testUtils.PrintToLogsOrConsole("GEOGRAPHY NOT SUPPORTED BY OLEDB", logger, "error"); + break; + } + string[] arguments = param[2].Split(':', 2); + string geoWKT = arguments[0]; + int srid = (int)GetSqlDbValue("int", arguments[1]); + + ((SqlParameter)parameter).SqlDbType = SqlDbType.Udt; + ((SqlParameter)parameter).UdtTypeName = "Geography"; + + parameter.Value = SqlGeography.STGeomFromText(new SqlChars(new SqlString(geoWKT)), srid); + parameter.Size = 65535; + } + break; default: throw new Exception("DATATYPE NOT SUPPORTED:- " + param[0]); } @@ -377,6 +450,10 @@ public static SqlDbType GetSqlDbType(string type) return SqlDbType.Structured; case "udt": return SqlDbType.Udt; + case "geometry": + return SqlDbType.Udt; + case "geography": + return SqlDbType.Udt; default: throw new Exception("DATA TYPE NOT SUPPORTED " + type); } diff --git a/test/odbc/mssqlodbc/test_data_types.cpp b/test/odbc/mssqlodbc/test_data_types.cpp index cf4f184f71..cce92a31c3 100644 --- a/test/odbc/mssqlodbc/test_data_types.cpp +++ b/test/odbc/mssqlodbc/test_data_types.cpp @@ -448,3 +448,93 @@ TEST_F(MSSQL_Data_Types, Varchar) { DataTypesTestCommon(TEST_TABLE, TABLE_COLUMNS, INSERTED_VALUES, EXPECTED_VALUES); } + +// Test retrieval of type Geometry +// This test differs from others in the following: +// 1. the way the INSERTED_VALUES are defined - they already contain the 'order of insertion' values +// 2. the way the INSERTED_VALUES are inserted - loop through the 'literal' inserted values since they 'hard code' the 'order of insertions' values +// The reason it was done this way is because in SQL Server you have to call function to convert wkt to geometry type so it contains additional '()' which causes error while processing parameters +// For example, if I had to insert Point(1.0 2.0) it will be done using geometry::STGeomFromText('Point(1.0 2.0)', 4326), which causes error in processInsertedValuesString. +TEST_F(MSSQL_Data_Types, Geometry) { + OdbcHandler odbcHandler(Drivers::GetDriver(ServerType::MSSQL)); + + const string TEST_TABLE = "POINTGEOM_dt"; + const string ORDER_BY_COLS = "OrderOfInsertion"; + const vector> TABLE_COLUMNS = { + {"location", "GEOMETRY"}, + {ORDER_BY_COLS, "INT"} + }; + + const vector INSERTED_VALUES = { + "(geometry::STGeomFromText('Point(47.65100 -22.34900)', 4326), 1)", "(geometry::STGeomFromText('Point(1.0 2.0)', 4326), 2)", + "(geometry::STGeomFromText('Point(47.65100 -22.34900)', 0), 3)", "(geometry::STGeomFromText(NULL, 4326), 4)", + "(geometry::STPointFromText('Point(47.65100 -22.34900)', 4326), 5)", "(geometry::Point(47.65100, -22.34900, 4326), 6)" + }; + + vector> expectedValues = { + {"E6100000010C17D9CEF753D34740D34D6210585936C0", "E6100000010C000000000000F03F0000000000000040", "00000000010C17D9CEF753D34740D34D6210585936C0", + NULL_STR, "E6100000010C17D9CEF753D34740D34D6210585936C0", "E6100000010C17D9CEF753D34740D34D6210585936C0"} + }; + + DatabaseObjects dbObjects(Drivers::GetDriver(ServerType::MSSQL)); + ASSERT_NO_FATAL_FAILURE(dbObjects.CreateTable(TEST_TABLE, TABLE_COLUMNS)); + + ASSERT_NO_FATAL_FAILURE(odbcHandler.Connect(true)); + + for (short i = 0; i < INSERTED_VALUES.size(); i++) { + ASSERT_NO_FATAL_FAILURE(odbcHandler.ExecQuery(InsertStatement(TEST_TABLE, INSERTED_VALUES[i]))); + + } + ASSERT_NO_FATAL_FAILURE(odbcHandler.ExecQuery(SelectStatement(TEST_TABLE, { "*" }, { ORDER_BY_COLS }))); + + SQLSMALLINT sNumResults; + SQLNumResultCols(odbcHandler.GetStatementHandle(), &sNumResults); + ASSERT_EQ(sNumResults, TABLE_COLUMNS.size()); + + fetchAndCompare(odbcHandler, expectedValues); +} + +// Test retrieval of type Geography +// This test differs from others in the following: +// 1. the way the INSERTED_VALUES are defined - they already contain the 'order of insertion' values +// 2. the way the INSERTED_VALUES are inserted - loop through the 'literal' inserted values since they 'hard code' the 'order of insertions' values +// The reason it was done this way is because in SQL Server you have to call function to convert wkt to geography type so it contains additional '()' which causes error while processing parameters +// For example, if I had to insert Point(1.0 2.0) it will be done using geography::STGeomFromText('Point(1.0 2.0)', 4326), which causes error in processInsertedValuesString. +TEST_F(MSSQL_Data_Types, Geography) { + OdbcHandler odbcHandler(Drivers::GetDriver(ServerType::MSSQL)); + + const string TEST_TABLE = "POINTGEOG_dt"; + const string ORDER_BY_COLS = "OrderOfInsertion"; + const vector> TABLE_COLUMNS = { + {"location", "GEOGRAPHY"}, + {ORDER_BY_COLS, "INT"} + }; + + const vector INSERTED_VALUES = { + "(geography::STGeomFromText('Point(47.65100 -22.34900)', 4326), 1)", "(geography::STGeomFromText('Point(1.0 2.0)', 4326), 2)", + "(geography::STGeomFromText(NULL, 4326), 3)", "(geography::STPointFromText('Point(1.0 2.0)', 4326), 4)", + "(geography::STPointFromText('Point(47.65100 -22.34900)', 4326), 5)", "(geography::Point(47.65100, -22.34900, 4326), 6)" + }; + + vector> expectedValues = { + {"E6100000010CD34D6210585936C017D9CEF753D34740", "E6100000010C0000000000000040000000000000F03F", NULL_STR, "E6100000010C0000000000000040000000000000F03F", + "E6100000010CD34D6210585936C017D9CEF753D34740", "E6100000010C17D9CEF753D34740D34D6210585936C0"} + }; + + DatabaseObjects dbObjects(Drivers::GetDriver(ServerType::MSSQL)); + ASSERT_NO_FATAL_FAILURE(dbObjects.CreateTable(TEST_TABLE, TABLE_COLUMNS)); + + ASSERT_NO_FATAL_FAILURE(odbcHandler.Connect(true)); + + for (short i = 0; i < INSERTED_VALUES.size(); i++) { + ASSERT_NO_FATAL_FAILURE(odbcHandler.ExecQuery(InsertStatement(TEST_TABLE, INSERTED_VALUES[i]))); + + } + ASSERT_NO_FATAL_FAILURE(odbcHandler.ExecQuery(SelectStatement(TEST_TABLE, { "*" }, { ORDER_BY_COLS }))); + + SQLSMALLINT sNumResults; + SQLNumResultCols(odbcHandler.GetStatementHandle(), &sNumResults); + ASSERT_EQ(sNumResults, TABLE_COLUMNS.size()); + + fetchAndCompare(odbcHandler, expectedValues); +} diff --git a/test/odbc/psqlodbc/test/geography.cpp b/test/odbc/psqlodbc/test/geography.cpp new file mode 100644 index 0000000000..79a952454b --- /dev/null +++ b/test/odbc/psqlodbc/test/geography.cpp @@ -0,0 +1,127 @@ +#include "../conversion_functions_common.h" +#include "../psqlodbc_tests_common.h" + +const string TABLE_NAME = "master.dbo.geography_table_odbc_test"; +const string COL1_NAME = "pk"; +const string COL2_NAME = "data"; +const string DATATYPE_NAME = "sys.geography"; +const string VIEW_NAME = "geography_view_odbc_test"; +const vector> TABLE_COLUMNS = { + {COL1_NAME, "INT PRIMARY KEY"}, + {COL2_NAME, DATATYPE_NAME} +}; + +class PSQL_DataTypes_Geography : public testing::Test { + void SetUp() override { + if (!Drivers::DriverExists(ServerType::MSSQL)) { + GTEST_SKIP() << "MSSQL Driver not present: skipping all tests for this fixture."; + } + + OdbcHandler test_setup(Drivers::GetDriver(ServerType::MSSQL)); + test_setup.ConnectAndExecQuery(DropObjectStatement("TABLE", TABLE_NAME)); + } + + void TearDown() override { + if (!Drivers::DriverExists(ServerType::MSSQL)) { + GTEST_SKIP() << "MSSQL Driver not present: skipping all tests for this fixture."; + } + + OdbcHandler test_teardown(Drivers::GetDriver(ServerType::MSSQL)); + test_teardown.ConnectAndExecQuery(DropObjectStatement("VIEW", VIEW_NAME)); + test_teardown.CloseStmt(); + test_teardown.ExecQuery(DropObjectStatement("TABLE", TABLE_NAME)); + } +}; + +TEST_F(PSQL_DataTypes_Geography, Table_Creation) { + const vector LENGTH_EXPECTED = {10, 0}; + const vector PRECISION_EXPECTED = {10, 0}; + const vector SCALE_EXPECTED = {0, 0}; + const vector NAME_EXPECTED = {"int", "udt"}; + + createTable(ServerType::MSSQL, TABLE_NAME, TABLE_COLUMNS); + testCommonColumnAttributes(ServerType::MSSQL, TABLE_NAME, TABLE_COLUMNS.size(), COL1_NAME, LENGTH_EXPECTED, + PRECISION_EXPECTED, SCALE_EXPECTED, NAME_EXPECTED); + dropObject(ServerType::MSSQL, "TABLE", TABLE_NAME); +} + +TEST_F(PSQL_DataTypes_Geography, Insertion_Success) { + const vector INSERTED_VALUES = { + "(geography::STGeomFromText('Point(47.65100 -22.34900)', 4326))", + "(geography::STGeomFromText('Point(1.0 2.0)', 4326))", + "(geography::STPointFromText('Point(47.65100 -22.34900)', 4326))", + "(geography::STPointFromText('Point(1.0 2.0)', 4326))", + "(geography::Point(47.65100, -22.34900, 4326))" + }; + const vector EXPECTED_VALUES = { + "E6100000010CD34D6210585936C017D9CEF753D34740", + "E6100000010C0000000000000040000000000000F03F", + "E6100000010CD34D6210585936C017D9CEF753D34740", + "E6100000010C0000000000000040000000000000F03F", + "E6100000010C17D9CEF753D34740D34D6210585936C0" + }; + const int NUM_OF_INSERTS = INSERTED_VALUES.size(); + + createTable(ServerType::MSSQL, TABLE_NAME, TABLE_COLUMNS); + testInsertionSuccess(ServerType::MSSQL, TABLE_NAME, COL1_NAME, + INSERTED_VALUES, EXPECTED_VALUES, 0, false, true); + dropObject(ServerType::MSSQL, "TABLE", TABLE_NAME); +} + +TEST_F(PSQL_DataTypes_Geography, Update_Success) { + const vector INSERTED_VALUES = { + "(geography::STGeomFromText('Point(47.65100 -22.34900)', 4326))" + }; + const vector EXPECTED_VALUES = { + "E6100000010CD34D6210585936C017D9CEF753D34740" + }; + + const vector UPDATED_VALUES = { + "(geography::STGeomFromText('Point(1.0 2.0)', 4326))", + "(geography::STPointFromText('Point(47.65100 -22.34900)', 4326))", + "(geography::STPointFromText('Point(1.0 2.0)', 4326))", + "(geography::Point(47.65100, -22.34900, 4326))" + }; + const vector EXPECTED_UPDATED_VALUES = { + "E6100000010C0000000000000040000000000000F03F", + "E6100000010CD34D6210585936C017D9CEF753D34740", + "E6100000010C0000000000000040000000000000F03F", + "E6100000010C17D9CEF753D34740D34D6210585936C0" + }; + + createTable(ServerType::MSSQL, TABLE_NAME, TABLE_COLUMNS); + testInsertionSuccess(ServerType::MSSQL, TABLE_NAME, COL1_NAME, + INSERTED_VALUES, EXPECTED_VALUES, 0, false, true); + testUpdateSuccess(ServerType::MSSQL, TABLE_NAME, COL1_NAME, COL2_NAME, + UPDATED_VALUES, EXPECTED_UPDATED_VALUES, false, true); + dropObject(ServerType::MSSQL, "TABLE", TABLE_NAME); +} + +TEST_F(PSQL_DataTypes_Geography, View_creation) { + const vector INSERTED_VALUES = { + "(geography::STGeomFromText('Point(47.65100 -22.34900)', 4326))", + "(geography::STGeomFromText('Point(1.0 2.0)', 4326))", + "(geography::STPointFromText('Point(47.65100 -22.34900)', 4326))", + "(geography::STPointFromText('Point(1.0 2.0)', 4326))", + "(geography::Point(47.65100, -22.34900, 4326))" + }; + + const vector EXPECTED_VALUES = { + "E6100000010CD34D6210585936C017D9CEF753D34740", + "E6100000010C0000000000000040000000000000F03F", + "E6100000010CD34D6210585936C017D9CEF753D34740", + "E6100000010C0000000000000040000000000000F03F", + "E6100000010C17D9CEF753D34740D34D6210585936C0" + }; + + const string VIEW_QUERY = "SELECT * FROM " + TABLE_NAME; + + createTable(ServerType::MSSQL, TABLE_NAME, TABLE_COLUMNS); + testInsertionSuccess(ServerType::MSSQL, TABLE_NAME, COL1_NAME, INSERTED_VALUES, EXPECTED_VALUES, 0, false, true); + + createView(ServerType::MSSQL, VIEW_NAME, VIEW_QUERY); + verifyValuesInObject(ServerType::MSSQL, VIEW_NAME, COL1_NAME, INSERTED_VALUES, EXPECTED_VALUES); + + dropObject(ServerType::MSSQL, "VIEW", VIEW_NAME); + dropObject(ServerType::MSSQL, "TABLE", TABLE_NAME); +} diff --git a/test/odbc/psqlodbc/test/geometry.cpp b/test/odbc/psqlodbc/test/geometry.cpp new file mode 100644 index 0000000000..0f7bf73ae0 --- /dev/null +++ b/test/odbc/psqlodbc/test/geometry.cpp @@ -0,0 +1,127 @@ +#include "../conversion_functions_common.h" +#include "../psqlodbc_tests_common.h" + +const string TABLE_NAME = "master.dbo.geometry_table_odbc_test"; +const string COL1_NAME = "pk"; +const string COL2_NAME = "data"; +const string DATATYPE_NAME = "sys.geometry"; +const string VIEW_NAME = "geometry_view_odbc_test"; +const vector> TABLE_COLUMNS = { + {COL1_NAME, "INT PRIMARY KEY"}, + {COL2_NAME, DATATYPE_NAME} +}; + +class PSQL_DataTypes_Geometry : public testing::Test { + void SetUp() override { + if (!Drivers::DriverExists(ServerType::MSSQL)) { + GTEST_SKIP() << "MSSQL Driver not present: skipping all tests for this fixture."; + } + + OdbcHandler test_setup(Drivers::GetDriver(ServerType::MSSQL)); + test_setup.ConnectAndExecQuery(DropObjectStatement("TABLE", TABLE_NAME)); + } + + void TearDown() override { + if (!Drivers::DriverExists(ServerType::MSSQL)) { + GTEST_SKIP() << "MSSQL Driver not present: skipping all tests for this fixture."; + } + + OdbcHandler test_teardown(Drivers::GetDriver(ServerType::MSSQL)); + test_teardown.ConnectAndExecQuery(DropObjectStatement("VIEW", VIEW_NAME)); + test_teardown.CloseStmt(); + test_teardown.ExecQuery(DropObjectStatement("TABLE", TABLE_NAME)); + } +}; + +TEST_F(PSQL_DataTypes_Geometry, Table_Creation) { + const vector LENGTH_EXPECTED = {10, 0}; + const vector PRECISION_EXPECTED = {10, 0}; + const vector SCALE_EXPECTED = {0, 0}; + const vector NAME_EXPECTED = {"int", "udt"}; + + createTable(ServerType::MSSQL, TABLE_NAME, TABLE_COLUMNS); + testCommonColumnAttributes(ServerType::MSSQL, TABLE_NAME, TABLE_COLUMNS.size(), COL1_NAME, LENGTH_EXPECTED, + PRECISION_EXPECTED, SCALE_EXPECTED, NAME_EXPECTED); + dropObject(ServerType::MSSQL, "TABLE", TABLE_NAME); +} + +TEST_F(PSQL_DataTypes_Geometry, Insertion_Success) { + const vector INSERTED_VALUES = { + "(geometry::STGeomFromText('Point(47.65100 -22.34900)', 4326))", + "(geometry::STGeomFromText('Point(1.0 2.0)', 4326))", + "(geometry::STGeomFromText('Point(47.65100 -22.34900)', 0))", + "(geometry::STPointFromText('Point(47.65100 -22.34900)', 4326))", + "(geometry::Point(47.65100, -22.34900, 4326))" + }; + const vector EXPECTED_VALUES = { + "E6100000010C17D9CEF753D34740D34D6210585936C0", + "E6100000010C000000000000F03F0000000000000040", + "00000000010C17D9CEF753D34740D34D6210585936C0", + "E6100000010C17D9CEF753D34740D34D6210585936C0", + "E6100000010C17D9CEF753D34740D34D6210585936C0" + }; + const int NUM_OF_INSERTS = INSERTED_VALUES.size(); + + createTable(ServerType::MSSQL, TABLE_NAME, TABLE_COLUMNS); + testInsertionSuccess(ServerType::MSSQL, TABLE_NAME, COL1_NAME, + INSERTED_VALUES, EXPECTED_VALUES, 0, false, true); + dropObject(ServerType::MSSQL, "TABLE", TABLE_NAME); +} + +TEST_F(PSQL_DataTypes_Geometry, Update_Success) { + const vector INSERTED_VALUES = { + "(geometry::STGeomFromText('Point(47.65100 -22.34900)', 4326))" + }; + const vector EXPECTED_VALUES = { + "E6100000010C17D9CEF753D34740D34D6210585936C0" + }; + + const vector UPDATED_VALUES = { + "(geometry::STGeomFromText('Point(1.0 2.0)', 4326))", + "(geometry::STGeomFromText('Point(47.65100 -22.34900)', 0))", + "(geometry::STPointFromText('Point(47.65100 -22.34900)', 4326))", + "(geometry::Point(47.65100, -22.34900, 4326))" + }; + const vector EXPECTED_UPDATED_VALUES = { + "E6100000010C000000000000F03F0000000000000040", + "00000000010C17D9CEF753D34740D34D6210585936C0", + "E6100000010C17D9CEF753D34740D34D6210585936C0", + "E6100000010C17D9CEF753D34740D34D6210585936C0" + }; + + createTable(ServerType::MSSQL, TABLE_NAME, TABLE_COLUMNS); + testInsertionSuccess(ServerType::MSSQL, TABLE_NAME, COL1_NAME, + INSERTED_VALUES, EXPECTED_VALUES, 0, false, true); + testUpdateSuccess(ServerType::MSSQL, TABLE_NAME, COL1_NAME, COL2_NAME, + UPDATED_VALUES, EXPECTED_UPDATED_VALUES, false, true); + dropObject(ServerType::MSSQL, "TABLE", TABLE_NAME); +} + +TEST_F(PSQL_DataTypes_Geometry, View_creation) { + const vector INSERTED_VALUES = { + "(geometry::STGeomFromText('Point(47.65100 -22.34900)', 4326))", + "(geometry::STGeomFromText('Point(1.0 2.0)', 4326))", + "(geometry::STGeomFromText('Point(47.65100 -22.34900)', 0))", + "(geometry::STPointFromText('Point(47.65100 -22.34900)', 4326))", + "(geometry::Point(47.65100, -22.34900, 4326))" + }; + + const vector EXPECTED_VALUES = { + "E6100000010C17D9CEF753D34740D34D6210585936C0", + "E6100000010C000000000000F03F0000000000000040", + "00000000010C17D9CEF753D34740D34D6210585936C0", + "E6100000010C17D9CEF753D34740D34D6210585936C0", + "E6100000010C17D9CEF753D34740D34D6210585936C0" + }; + + const string VIEW_QUERY = "SELECT * FROM " + TABLE_NAME; + + createTable(ServerType::MSSQL, TABLE_NAME, TABLE_COLUMNS); + testInsertionSuccess(ServerType::MSSQL, TABLE_NAME, COL1_NAME, INSERTED_VALUES, EXPECTED_VALUES, 0, false, true); + + createView(ServerType::MSSQL, VIEW_NAME, VIEW_QUERY); + verifyValuesInObject(ServerType::MSSQL, VIEW_NAME, COL1_NAME, INSERTED_VALUES, EXPECTED_VALUES); + + dropObject(ServerType::MSSQL, "VIEW", VIEW_NAME); + dropObject(ServerType::MSSQL, "TABLE", TABLE_NAME); +} diff --git a/test/python/expected/upgrade_validation/expected_dependency.out b/test/python/expected/upgrade_validation/expected_dependency.out index 385115fae4..e9cd5b635f 100644 --- a/test/python/expected/upgrade_validation/expected_dependency.out +++ b/test/python/expected/upgrade_validation/expected_dependency.out @@ -221,6 +221,7 @@ Function sys.bbf_binary_varbinary_cmp(sys.bbf_binary,sys.bbf_varbinary) Function sys.bbf_get_context_info() Function sys.bbf_get_current_physical_schema_name(text) Function sys.bbf_is_shared_schema(text) +Function sys.bbf_varbinary(sys.geometry) Function sys.bbf_varbinary_binary_cmp(sys.bbf_varbinary,sys.bbf_binary) Function sys.bbf_varbinary_cmp(sys.bbf_varbinary,sys.bbf_varbinary) Function sys.bbfbinary_sqlvariant(sys.bbf_binary) @@ -265,6 +266,7 @@ Function sys.bpcharrowversion(character,integer,boolean) Function sys.bpcharrowversion(sys.bpchar,integer,boolean) Function sys.bpcharvarbinary(character,integer,boolean) Function sys.bpcharvarbinary(sys.bpchar,integer,boolean) +Function sys.bytea(sys.geography) Function sys.bytea(sys.geometry) Function sys.byteavarbinary(bytea,integer,boolean) Function sys.ceiling(bigint) @@ -419,23 +421,28 @@ Function sys.ftrunci8(real) Function sys.fulltextserviceproperty(text) Function sys.geogpoint_helper(double precision,double precision,integer) Function sys.geography(bytea) +Function sys.geography(sys.bbf_varbinary) Function sys.geography(sys.geography,integer,boolean) Function sys.geography(sys.geometry) Function sys.geography__point(double precision,double precision,integer) Function sys.geography__stflipcoordinates(sys.geography) Function sys.geography__stgeomfromtext(text,integer) Function sys.geography__stpointfromtext(text,integer) +Function sys.geography_helper(bytea) Function sys.geometry(bytea) Function sys.geometry(point) +Function sys.geometry(sys.bbf_varbinary) Function sys.geometry(sys.geography) Function sys.geometry(sys.geometry,integer,boolean) Function sys.geometry(text) Function sys.geometry__point(double precision,double precision,integer) Function sys.geometry__stgeomfromtext(text,integer) Function sys.geometry__stpointfromtext(text,integer) +Function sys.geometry_helper(bytea) Function sys.geompoint_helper(double precision,double precision,integer) Function sys.get_current_full_xact_id() Function sys.get_host_os() +Function sys.get_valid_srids() Function sys.getdate() Function sys.getutcdate() Function sys.has_dbaccess(sys.sysname) @@ -620,6 +627,10 @@ Function sys.sqlvariant_tinyint(sys.sql_variant) Function sys.sqlvariant_uniqueidentifier(sys.sql_variant) Function sys.sqlvariant_varchar(sys.sql_variant) Function sys.square(double precision) +Function sys.st_geometrytype(sys.geography) +Function sys.st_geometrytype(sys.geometry) +Function sys.st_zmflag(sys.geography) +Function sys.st_zmflag(sys.geometry) Function sys.stasbinary_helper(sys.geography) Function sys.stastext_helper(sys.geography) Function sys.stdistance_helper(sys.geography,sys.geography) @@ -870,7 +881,6 @@ Operator sys.<>(smallint,sys.fixeddecimal) Operator sys.<>(sys."bit",integer) Operator sys.<>(sys."bit",sys."bit") Operator sys.<>(sys.bbf_binary,sys.bbf_binary) -Operator sys.<>(sys.bbf_varbinary,sys.bbf_varbinary) Operator sys.<>(sys.datetime,sys.datetime) Operator sys.<>(sys.datetime2,sys.datetime2) Operator sys.<>(sys.datetimeoffset,sys.datetimeoffset)