This is an automated email from the ASF dual-hosted git repository.
wenchen pushed a commit to branch branch-4.1
in repository https://gitbox.apache.org/repos/asf/spark.git
The following commit(s) were added to refs/heads/branch-4.1 by this push:
new 77d034d71e92 [SPARK-54160][GEO][SQL] Implement the ST_SetSrid
expression in SQL
77d034d71e92 is described below
commit 77d034d71e92b6810118ec06c0f3f2334c58a1c7
Author: Uros Bojanic <[email protected]>
AuthorDate: Wed Nov 5 13:00:06 2025 -0800
[SPARK-54160][GEO][SQL] Implement the ST_SetSrid expression in SQL
### What changes were proposed in this pull request?
Implement the `ST_SetSrid` expression in Catalyst, and add the
corresponding `st_setsrid` SQL function.
#### Description
Returns a new `GEOGRAPHY` or `GEOMETRY` value whose `SRID` is the specified
SRID value.
#### Syntax
```
st_setsrid(geo, srid)
```
#### Arguments
- `geo`: A `GEOGRAPHY` or `GEOMETRY` value.
- `srid`: An `INTEGER` value.
#### Returns
- A value of type `GEOGRAPHY` or `GEOMETRY`.
#### Notes
- The function returns `NULL` if the input is `NULL`.
- The function returns an `ST_INVALID_SRID_VALUE` error if the provided
`srid` is not valid.
#### Examples
```
> SELECT
st_srid(st_setsrid(ST_GeogFromWKB(X'0101000000000000000000F03F0000000000000040'),
4326));
4326
```
```
> SELECT
st_srid(st_setsrid(ST_GeomFromWKB(X'0101000000000000000000F03F0000000000000040'),
3857));
3857
```
### Why are the changes needed?
### Does this PR introduce _any_ user-facing change?
Yes, a new SQL function is added: `st_setsrid`.
### How was this patch tested?
New unit tests in Java/Scala suites:
- `STExpressionsSuite.scala`
- `StUtilsSuite.java`
New end-to-end SQL tests:
- `st-functions.sql`
Finally, manually testing using Spark shell.
### Was this patch authored or co-authored using generative AI tooling?
No.
Closes #52858 from uros-db/geo-ST_SetSrid.
Authored-by: Uros Bojanic <[email protected]>
Signed-off-by: Wenchen Fan <[email protected]>
---
.../org/apache/spark/sql/types/GeographyType.scala | 2 +-
.../org/apache/spark/sql/types/GeometryType.scala | 2 +-
.../org/apache/spark/sql/catalyst/util/Geo.java | 3 +
.../apache/spark/sql/catalyst/util/Geography.java | 15 ++-
.../apache/spark/sql/catalyst/util/Geometry.java | 15 ++-
.../apache/spark/sql/catalyst/util/STUtils.java | 26 +++++
.../sql/catalyst/analysis/FunctionRegistry.scala | 1 +
.../expressions/st/STExpressionUtils.scala | 46 ++++++++
.../catalyst/expressions/st/stExpressions.scala | 53 +++++++++
.../spark/sql/errors/QueryExecutionErrors.scala | 11 ++
.../spark/sql/catalyst/util/StUtilsSuite.java | 46 ++++++++
.../sql-functions/sql-expression-schema.md | 1 +
.../analyzer-results/nonansi/st-functions.sql.out | 84 ++++++++++++++
.../analyzer-results/st-functions.sql.out | 84 ++++++++++++++
.../resources/sql-tests/inputs/st-functions.sql | 18 +++
.../sql-tests/results/nonansi/st-functions.sql.out | 92 +++++++++++++++
.../sql-tests/results/st-functions.sql.out | 92 +++++++++++++++
.../org/apache/spark/sql/STExpressionsSuite.scala | 128 +++++++++++++++++++++
18 files changed, 715 insertions(+), 4 deletions(-)
diff --git
a/sql/api/src/main/scala/org/apache/spark/sql/types/GeographyType.scala
b/sql/api/src/main/scala/org/apache/spark/sql/types/GeographyType.scala
index d72e5987abeb..4d6ab7e9c8e5 100644
--- a/sql/api/src/main/scala/org/apache/spark/sql/types/GeographyType.scala
+++ b/sql/api/src/main/scala/org/apache/spark/sql/types/GeographyType.scala
@@ -179,7 +179,7 @@ object GeographyType extends SpatialType {
GeographyType(MIXED_CRS, GEOGRAPHY_DEFAULT_ALGORITHM)
/** Returns whether the given SRID is supported. */
- private[types] def isSridSupported(srid: Int): Boolean = {
+ def isSridSupported(srid: Int): Boolean = {
GeographicSpatialReferenceSystemMapper.getStringId(srid) != null
}
diff --git
a/sql/api/src/main/scala/org/apache/spark/sql/types/GeometryType.scala
b/sql/api/src/main/scala/org/apache/spark/sql/types/GeometryType.scala
index f5bbbcba6706..ff4a72011840 100644
--- a/sql/api/src/main/scala/org/apache/spark/sql/types/GeometryType.scala
+++ b/sql/api/src/main/scala/org/apache/spark/sql/types/GeometryType.scala
@@ -171,7 +171,7 @@ object GeometryType extends SpatialType {
GeometryType(MIXED_CRS)
/** Returns whether the given SRID is supported. */
- private[types] def isSridSupported(srid: Int): Boolean = {
+ def isSridSupported(srid: Int): Boolean = {
CartesianSpatialReferenceSystemMapper.getStringId(srid) != null
}
diff --git
a/sql/catalyst/src/main/java/org/apache/spark/sql/catalyst/util/Geo.java
b/sql/catalyst/src/main/java/org/apache/spark/sql/catalyst/util/Geo.java
index 2299f3598863..bf723a8efef9 100644
--- a/sql/catalyst/src/main/java/org/apache/spark/sql/catalyst/util/Geo.java
+++ b/sql/catalyst/src/main/java/org/apache/spark/sql/catalyst/util/Geo.java
@@ -78,4 +78,7 @@ interface Geo {
// Returns the Spatial Reference Identifier (SRID) value of the geo object.
int srid();
+ // Sets the Spatial Reference Identifier (SRID) value of the geo object.
+ void setSrid(int srid);
+
}
diff --git
a/sql/catalyst/src/main/java/org/apache/spark/sql/catalyst/util/Geography.java
b/sql/catalyst/src/main/java/org/apache/spark/sql/catalyst/util/Geography.java
index c46c2368832f..da513d399f8b 100644
---
a/sql/catalyst/src/main/java/org/apache/spark/sql/catalyst/util/Geography.java
+++
b/sql/catalyst/src/main/java/org/apache/spark/sql/catalyst/util/Geography.java
@@ -162,7 +162,20 @@ public final class Geography implements Geo {
@Override
public int srid() {
// This method gets the SRID value from the in-memory Geography
representation header.
- return
ByteBuffer.wrap(getBytes()).order(DEFAULT_ENDIANNESS).getInt(SRID_OFFSET);
+ return getWrapper().getInt(SRID_OFFSET);
+ }
+
+ @Override
+ public void setSrid(int srid) {
+ // This method sets the SRID value in the in-memory Geography
representation header.
+ getWrapper().putInt(SRID_OFFSET, srid);
+ }
+
+ /** Other private helper/utility methods used for implementation. */
+
+ // Returns a byte buffer wrapper over the byte buffer of this geography
value.
+ private ByteBuffer getWrapper() {
+ return ByteBuffer.wrap(getBytes()).order(DEFAULT_ENDIANNESS);
}
}
diff --git
a/sql/catalyst/src/main/java/org/apache/spark/sql/catalyst/util/Geometry.java
b/sql/catalyst/src/main/java/org/apache/spark/sql/catalyst/util/Geometry.java
index c4b6e5d0e4bd..36fffef2abbd 100644
---
a/sql/catalyst/src/main/java/org/apache/spark/sql/catalyst/util/Geometry.java
+++
b/sql/catalyst/src/main/java/org/apache/spark/sql/catalyst/util/Geometry.java
@@ -162,7 +162,20 @@ public final class Geometry implements Geo {
@Override
public int srid() {
// This method gets the SRID value from the in-memory Geometry
representation header.
- return
ByteBuffer.wrap(getBytes()).order(DEFAULT_ENDIANNESS).getInt(SRID_OFFSET);
+ return getWrapper().getInt(SRID_OFFSET);
+ }
+
+ @Override
+ public void setSrid(int srid) {
+ // This method sets the SRID value in the in-memory Geometry
representation header.
+ getWrapper().putInt(SRID_OFFSET, srid);
+ }
+
+ /** Other private helper/utility methods used for implementation. */
+
+ // Returns a byte buffer wrapper over the byte buffer of this geometry value.
+ private ByteBuffer getWrapper() {
+ return ByteBuffer.wrap(getBytes()).order(DEFAULT_ENDIANNESS);
}
}
diff --git
a/sql/catalyst/src/main/java/org/apache/spark/sql/catalyst/util/STUtils.java
b/sql/catalyst/src/main/java/org/apache/spark/sql/catalyst/util/STUtils.java
index 9aed051e0639..3cf4b84ac033 100644
--- a/sql/catalyst/src/main/java/org/apache/spark/sql/catalyst/util/STUtils.java
+++ b/sql/catalyst/src/main/java/org/apache/spark/sql/catalyst/util/STUtils.java
@@ -16,6 +16,7 @@
*/
package org.apache.spark.sql.catalyst.util;
+import org.apache.spark.sql.errors.QueryExecutionErrors;
import org.apache.spark.sql.types.GeographyType;
import org.apache.spark.sql.types.GeometryType;
import org.apache.spark.unsafe.types.GeographyVal;
@@ -110,6 +111,31 @@ public final class STUtils {
return toPhysVal(Geometry.fromWkb(wkb));
}
+ // ST_SetSrid
+ public static GeographyVal stSetSrid(GeographyVal geo, int srid) {
+ // We only allow setting the SRID to geographic values.
+ if(!GeographyType.isSridSupported(srid)) {
+ throw QueryExecutionErrors.stInvalidSridValueError(srid);
+ }
+ // Create a copy of the input geography.
+ Geography copy = fromPhysVal(geo).copy();
+ // Set the SRID of the copy to the specified value.
+ copy.setSrid(srid);
+ return toPhysVal(copy);
+ }
+
+ public static GeometryVal stSetSrid(GeometryVal geo, int srid) {
+ // We only allow setting the SRID to valid values.
+ if(!GeometryType.isSridSupported(srid)) {
+ throw QueryExecutionErrors.stInvalidSridValueError(srid);
+ }
+ // Create a copy of the input geometry.
+ Geometry copy = fromPhysVal(geo).copy();
+ // Set the SRID of the copy to the specified value.
+ copy.setSrid(srid);
+ return toPhysVal(copy);
+ }
+
// ST_Srid
public static int stSrid(GeographyVal geog) {
return fromPhysVal(geog).srid();
diff --git
a/sql/catalyst/src/main/scala/org/apache/spark/sql/catalyst/analysis/FunctionRegistry.scala
b/sql/catalyst/src/main/scala/org/apache/spark/sql/catalyst/analysis/FunctionRegistry.scala
index 3098832774d1..8ded5873f14a 100644
---
a/sql/catalyst/src/main/scala/org/apache/spark/sql/catalyst/analysis/FunctionRegistry.scala
+++
b/sql/catalyst/src/main/scala/org/apache/spark/sql/catalyst/analysis/FunctionRegistry.scala
@@ -879,6 +879,7 @@ object FunctionRegistry {
expression[ST_GeogFromWKB]("st_geogfromwkb"),
expression[ST_GeomFromWKB]("st_geomfromwkb"),
expression[ST_Srid]("st_srid"),
+ expression[ST_SetSrid]("st_setsrid"),
// cast
expression[Cast]("cast"),
diff --git
a/sql/catalyst/src/main/scala/org/apache/spark/sql/catalyst/expressions/st/STExpressionUtils.scala
b/sql/catalyst/src/main/scala/org/apache/spark/sql/catalyst/expressions/st/STExpressionUtils.scala
index 055173ec39ad..7b0345d277bc 100755
---
a/sql/catalyst/src/main/scala/org/apache/spark/sql/catalyst/expressions/st/STExpressionUtils.scala
+++
b/sql/catalyst/src/main/scala/org/apache/spark/sql/catalyst/expressions/st/STExpressionUtils.scala
@@ -17,6 +17,7 @@
package org.apache.spark.sql.catalyst.expressions.st
+import org.apache.spark.sql.catalyst.expressions._
import org.apache.spark.sql.types._
private[sql] object STExpressionUtils {
@@ -29,4 +30,49 @@ private[sql] object STExpressionUtils {
case _ => false
}
+ /**
+ * Returns the input GEOMETRY or GEOGRAPHY value with the specified SRID.
Only geospatial types
+ * are allowed as the source type, and calls are delegated to the
corresponding helper methods.
+ */
+ def geospatialTypeWithSrid(sourceType: DataType, srid: Expression): DataType
= {
+ sourceType match {
+ case _: GeometryType =>
+ geometryTypeWithSrid(srid)
+ case _: GeographyType =>
+ geographyTypeWithSrid(srid)
+ case _ =>
+ throw new IllegalArgumentException(s"Unexpected data type:
$sourceType.")
+ }
+ }
+
+ /**
+ * Returns the input GEOMETRY value with the specified SRID. If the SRID
expression is a literal,
+ * the SRID value can be directly extracted. Otherwise, only the mixed SRID
value can be used.
+ */
+ private def geometryTypeWithSrid(srid: Expression): GeometryType = {
+ srid match {
+ case Literal(sridValue: Int, IntegerType) =>
+ // If the SRID expression is a literal, the SRID value can be directly
extracted.
+ GeometryType(sridValue)
+ case _ =>
+ // Otherwise, only the mixed SRID value can be used for the output
GEOMETRY value.
+ GeometryType("ANY")
+ }
+ }
+
+ /**
+ * Returns the input GEOGRAPHY value with the specified SRID. If the SRID
expression is a literal,
+ * the SRID value can be directly extracted. Otherwise, only the mixed SRID
value can be used.
+ */
+ private def geographyTypeWithSrid(srid: Expression): GeographyType = {
+ srid match {
+ case Literal(sridValue: Int, IntegerType) =>
+ // If the SRID expression is a literal, the SRID value can be directly
extracted.
+ GeographyType(sridValue)
+ case _ =>
+ // Otherwise, only the mixed SRID value can be used for the output
GEOMETRY value.
+ GeographyType("ANY")
+ }
+ }
+
}
diff --git
a/sql/catalyst/src/main/scala/org/apache/spark/sql/catalyst/expressions/st/stExpressions.scala
b/sql/catalyst/src/main/scala/org/apache/spark/sql/catalyst/expressions/st/stExpressions.scala
index 135a7f7d61f2..4cdfbeead875 100755
---
a/sql/catalyst/src/main/scala/org/apache/spark/sql/catalyst/expressions/st/stExpressions.scala
+++
b/sql/catalyst/src/main/scala/org/apache/spark/sql/catalyst/expressions/st/stExpressions.scala
@@ -223,3 +223,56 @@ case class ST_Srid(geo: Expression)
override protected def withNewChildInternal(newChild: Expression): ST_Srid =
copy(geo = newChild)
}
+
+/** ST modifier expressions. */
+
+/**
+ * Returns a new GEOGRAPHY or GEOMETRY value whose SRID is the specified SRID
value.
+ */
+@ExpressionDescription(
+ usage = "_FUNC_(geo, srid) - Returns a new GEOGRAPHY or GEOMETRY value whose
SRID is " +
+ "the specified SRID value.",
+ arguments = """
+ Arguments:
+ * geo - A GEOGRAPHY or GEOMETRY value.
+ * srid - The new SRID value of the geography or geometry.
+ """,
+ examples = """
+ Examples:
+ > SELECT
st_srid(_FUNC_(ST_GeogFromWKB(X'0101000000000000000000F03F0000000000000040'),
4326));
+ 4326
+ > SELECT
st_srid(_FUNC_(ST_GeomFromWKB(X'0101000000000000000000F03F0000000000000040'),
3857));
+ 3857
+ """,
+ since = "4.1.0",
+ group = "st_funcs"
+)
+case class ST_SetSrid(geo: Expression, srid: Expression)
+ extends RuntimeReplaceable
+ with ImplicitCastInputTypes
+ with BinaryLike[Expression] {
+
+ override def inputTypes: Seq[AbstractDataType] =
+ Seq(
+ TypeCollection(GeographyType, GeometryType),
+ IntegerType
+ )
+
+ override lazy val replacement: Expression = StaticInvoke(
+ classOf[STUtils],
+ STExpressionUtils.geospatialTypeWithSrid(geo.dataType, srid),
+ "stSetSrid",
+ Seq(geo, srid),
+ returnNullable = false
+ )
+
+ override def prettyName: String = "st_setsrid"
+
+ override def left: Expression = geo
+
+ override def right: Expression = srid
+
+ override protected def withNewChildrenInternal(
+ newLeft: Expression,
+ newRight: Expression): ST_SetSrid = copy(geo = newLeft, srid = newRight)
+}
diff --git
a/sql/catalyst/src/main/scala/org/apache/spark/sql/errors/QueryExecutionErrors.scala
b/sql/catalyst/src/main/scala/org/apache/spark/sql/errors/QueryExecutionErrors.scala
index 55dcea57ff32..a12aa53d1f6f 100644
---
a/sql/catalyst/src/main/scala/org/apache/spark/sql/errors/QueryExecutionErrors.scala
+++
b/sql/catalyst/src/main/scala/org/apache/spark/sql/errors/QueryExecutionErrors.scala
@@ -665,6 +665,17 @@ private[sql] object QueryExecutionErrors extends
QueryErrorsBase with ExecutionE
summary = "")
}
+ def stInvalidSridValueError(srid: String): SparkIllegalArgumentException = {
+ new SparkIllegalArgumentException(
+ errorClass = "ST_INVALID_SRID_VALUE",
+ messageParameters = Map("srid" -> srid)
+ )
+ }
+
+ def stInvalidSridValueError(srid: Int): SparkIllegalArgumentException = {
+ stInvalidSridValueError(srid.toString)
+ }
+
def withSuggestionIntervalArithmeticOverflowError(
suggestedFunc: String,
context: QueryContext): ArithmeticException = {
diff --git
a/sql/catalyst/src/test/scala/org/apache/spark/sql/catalyst/util/StUtilsSuite.java
b/sql/catalyst/src/test/scala/org/apache/spark/sql/catalyst/util/StUtilsSuite.java
index 0e18f8bdf919..f19a92b61641 100644
---
a/sql/catalyst/src/test/scala/org/apache/spark/sql/catalyst/util/StUtilsSuite.java
+++
b/sql/catalyst/src/test/scala/org/apache/spark/sql/catalyst/util/StUtilsSuite.java
@@ -17,6 +17,7 @@
package org.apache.spark.sql.catalyst.util;
+import org.apache.spark.SparkIllegalArgumentException;
import org.apache.spark.unsafe.types.GeographyVal;
import org.apache.spark.unsafe.types.GeometryVal;
import org.junit.jupiter.api.Test;
@@ -120,4 +121,49 @@ class STUtilsSuite {
assertEquals(testGeometrySrid, STUtils.stSrid(geometryVal));
}
+ // ST_SetSrid
+ @Test
+ void testStSetSridGeography() {
+ for (int validGeographySrid : new int[]{4326}) {
+ GeographyVal geographyVal = GeographyVal.fromBytes(testGeographyBytes);
+ GeographyVal updatedGeographyVal = STUtils.stSetSrid(geographyVal,
validGeographySrid);
+ assertNotNull(updatedGeographyVal);
+ Geography updatedGeography =
Geography.fromBytes(updatedGeographyVal.getBytes());
+ assertEquals(validGeographySrid, updatedGeography.srid());
+ }
+ }
+
+ @Test
+ void testStSetSridGeographyInvalidSrid() {
+ for (int invalidGeographySrid : new int[]{-9999, -2, -1, 0, 1, 2, 3857,
9999}) {
+ GeographyVal geographyVal = GeographyVal.fromBytes(testGeographyBytes);
+ SparkIllegalArgumentException exception =
assertThrows(SparkIllegalArgumentException.class,
+ () -> STUtils.stSetSrid(geographyVal, invalidGeographySrid));
+ assertEquals("ST_INVALID_SRID_VALUE", exception.getCondition());
+ assertTrue(exception.getMessage().contains("value: " +
invalidGeographySrid + "."));
+ }
+ }
+
+ @Test
+ void testStSetSridGeometry() {
+ for (int validGeographySrid : new int[]{0, 3857, 4326}) {
+ GeometryVal geometryVal = GeometryVal.fromBytes(testGeometryBytes);
+ GeometryVal updatedGeometryVal = STUtils.stSetSrid(geometryVal,
validGeographySrid);
+ assertNotNull(updatedGeometryVal);
+ Geometry updatedGeometry =
Geometry.fromBytes(updatedGeometryVal.getBytes());
+ assertEquals(validGeographySrid, updatedGeometry.srid());
+ }
+ }
+
+ @Test
+ void testStSetSridGeometryInvalidSrid() {
+ for (int invalidGeometrySrid : new int[]{-9999, -2, -1, 1, 2, 9999}) {
+ GeometryVal geometryVal = GeometryVal.fromBytes(testGeometryBytes);
+ SparkIllegalArgumentException exception =
assertThrows(SparkIllegalArgumentException.class,
+ () -> STUtils.stSetSrid(geometryVal, invalidGeometrySrid));
+ assertEquals("ST_INVALID_SRID_VALUE", exception.getCondition());
+ assertTrue(exception.getMessage().contains("value: " +
invalidGeometrySrid + "."));
+ }
+ }
+
}
diff --git a/sql/core/src/test/resources/sql-functions/sql-expression-schema.md
b/sql/core/src/test/resources/sql-functions/sql-expression-schema.md
index d9e4a960a2d7..34739ec1c44c 100644
--- a/sql/core/src/test/resources/sql-functions/sql-expression-schema.md
+++ b/sql/core/src/test/resources/sql-functions/sql-expression-schema.md
@@ -480,6 +480,7 @@
| org.apache.spark.sql.catalyst.expressions.st.ST_AsBinary | st_asbinary |
SELECT
hex(st_asbinary(st_geogfromwkb(X'0101000000000000000000F03F0000000000000040')))
|
struct<hex(st_asbinary(st_geogfromwkb(X'0101000000000000000000F03F0000000000000040'))):string>
|
| org.apache.spark.sql.catalyst.expressions.st.ST_GeogFromWKB | st_geogfromwkb
| SELECT
hex(st_asbinary(st_geogfromwkb(X'0101000000000000000000F03F0000000000000040')))
|
struct<hex(st_asbinary(st_geogfromwkb(X'0101000000000000000000F03F0000000000000040'))):string>
|
| org.apache.spark.sql.catalyst.expressions.st.ST_GeomFromWKB | st_geomfromwkb
| SELECT
hex(st_asbinary(st_geomfromwkb(X'0101000000000000000000F03F0000000000000040')))
|
struct<hex(st_asbinary(st_geomfromwkb(X'0101000000000000000000F03F0000000000000040'))):string>
|
+| org.apache.spark.sql.catalyst.expressions.st.ST_SetSrid | st_setsrid |
SELECT
st_srid(st_setsrid(ST_GeogFromWKB(X'0101000000000000000000F03F0000000000000040'),
4326)) |
struct<st_srid(st_setsrid(st_geogfromwkb(X'0101000000000000000000F03F0000000000000040'),
4326)):int> |
| org.apache.spark.sql.catalyst.expressions.st.ST_Srid | st_srid | SELECT
st_srid(st_geogfromwkb(X'0101000000000000000000F03F0000000000000040')) |
struct<st_srid(st_geogfromwkb(X'0101000000000000000000F03F0000000000000040')):int>
|
| org.apache.spark.sql.catalyst.expressions.variant.IsVariantNull |
is_variant_null | SELECT is_variant_null(parse_json('null')) |
struct<is_variant_null(parse_json(null)):boolean> |
| org.apache.spark.sql.catalyst.expressions.variant.ParseJsonExpressionBuilder
| parse_json | SELECT parse_json('{"a":1,"b":0.8}') |
struct<parse_json({"a":1,"b":0.8}):variant> |
diff --git
a/sql/core/src/test/resources/sql-tests/analyzer-results/nonansi/st-functions.sql.out
b/sql/core/src/test/resources/sql-tests/analyzer-results/nonansi/st-functions.sql.out
index dfc0b6b89a84..55bb5f6ab7b0 100644
---
a/sql/core/src/test/resources/sql-tests/analyzer-results/nonansi/st-functions.sql.out
+++
b/sql/core/src/test/resources/sql-tests/analyzer-results/nonansi/st-functions.sql.out
@@ -148,6 +148,90 @@ Aggregate [count(1) AS count(1)#xL]
+- Relation spark_catalog.default.geodata[wkb#x] parquet
+-- !query
+SELECT
ST_Srid(ST_SetSrid(ST_GeogFromWKB(X'0101000000000000000000F03F0000000000000040'),
4326))
+-- !query analysis
+Project
[st_srid(st_setsrid(st_geogfromwkb(0x0101000000000000000000F03F0000000000000040),
4326)) AS
st_srid(st_setsrid(st_geogfromwkb(X'0101000000000000000000F03F0000000000000040'),
4326))#x]
++- OneRowRelation
+
+
+-- !query
+SELECT
ST_Srid(ST_SetSrid(ST_GeomFromWKB(X'0101000000000000000000F03F0000000000000040'),
3857))
+-- !query analysis
+Project
[st_srid(st_setsrid(st_geomfromwkb(0x0101000000000000000000F03F0000000000000040),
3857)) AS
st_srid(st_setsrid(st_geomfromwkb(X'0101000000000000000000F03F0000000000000040'),
3857))#x]
++- OneRowRelation
+
+
+-- !query
+SELECT
ST_Srid(ST_SetSrid(ST_GeogFromWKB(X'0101000000000000000000F03F0000000000000040'),
3857))
+-- !query analysis
+org.apache.spark.SparkIllegalArgumentException
+{
+ "errorClass" : "ST_INVALID_SRID_VALUE",
+ "sqlState" : "22023",
+ "messageParameters" : {
+ "srid" : "3857"
+ }
+}
+
+
+-- !query
+SELECT
ST_Srid(ST_SetSrid(ST_GeomFromWKB(X'0101000000000000000000F03F0000000000000040'),
9999))
+-- !query analysis
+org.apache.spark.SparkIllegalArgumentException
+{
+ "errorClass" : "ST_INVALID_SRID_VALUE",
+ "sqlState" : "22023",
+ "messageParameters" : {
+ "srid" : "9999"
+ }
+}
+
+
+-- !query
+SELECT COUNT(*) FROM geodata WHERE ST_Srid(ST_SetSrid(ST_GeogFromWKB(wkb),
4326)) <> 4326
+-- !query analysis
+Aggregate [count(1) AS count(1)#xL]
++- Filter NOT (st_srid(st_setsrid(st_geogfromwkb(wkb#x), 4326)) = 4326)
+ +- SubqueryAlias spark_catalog.default.geodata
+ +- Relation spark_catalog.default.geodata[wkb#x] parquet
+
+
+-- !query
+SELECT COUNT(*) FROM geodata WHERE ST_Srid(ST_SetSrid(ST_GeomFromWKB(wkb),
3857)) <> 3857
+-- !query analysis
+Aggregate [count(1) AS count(1)#xL]
++- Filter NOT (st_srid(st_setsrid(st_geomfromwkb(wkb#x), 3857)) = 3857)
+ +- SubqueryAlias spark_catalog.default.geodata
+ +- Relation spark_catalog.default.geodata[wkb#x] parquet
+
+
+-- !query
+SELECT COUNT(*) FROM geodata WHERE ST_Srid(ST_SetSrid(ST_GeogFromWKB(wkb),
3857)) IS NOT NULL
+-- !query analysis
+org.apache.spark.SparkIllegalArgumentException
+{
+ "errorClass" : "ST_INVALID_SRID_VALUE",
+ "sqlState" : "22023",
+ "messageParameters" : {
+ "srid" : "3857"
+ }
+}
+
+
+-- !query
+SELECT COUNT(*) FROM geodata WHERE ST_Srid(ST_SetSrid(ST_GeomFromWKB(wkb),
9999)) IS NOT NULL
+-- !query analysis
+org.apache.spark.SparkIllegalArgumentException
+{
+ "errorClass" : "ST_INVALID_SRID_VALUE",
+ "sqlState" : "22023",
+ "messageParameters" : {
+ "srid" : "9999"
+ }
+}
+
+
-- !query
DROP TABLE geodata
-- !query analysis
diff --git
a/sql/core/src/test/resources/sql-tests/analyzer-results/st-functions.sql.out
b/sql/core/src/test/resources/sql-tests/analyzer-results/st-functions.sql.out
index dfc0b6b89a84..55bb5f6ab7b0 100644
---
a/sql/core/src/test/resources/sql-tests/analyzer-results/st-functions.sql.out
+++
b/sql/core/src/test/resources/sql-tests/analyzer-results/st-functions.sql.out
@@ -148,6 +148,90 @@ Aggregate [count(1) AS count(1)#xL]
+- Relation spark_catalog.default.geodata[wkb#x] parquet
+-- !query
+SELECT
ST_Srid(ST_SetSrid(ST_GeogFromWKB(X'0101000000000000000000F03F0000000000000040'),
4326))
+-- !query analysis
+Project
[st_srid(st_setsrid(st_geogfromwkb(0x0101000000000000000000F03F0000000000000040),
4326)) AS
st_srid(st_setsrid(st_geogfromwkb(X'0101000000000000000000F03F0000000000000040'),
4326))#x]
++- OneRowRelation
+
+
+-- !query
+SELECT
ST_Srid(ST_SetSrid(ST_GeomFromWKB(X'0101000000000000000000F03F0000000000000040'),
3857))
+-- !query analysis
+Project
[st_srid(st_setsrid(st_geomfromwkb(0x0101000000000000000000F03F0000000000000040),
3857)) AS
st_srid(st_setsrid(st_geomfromwkb(X'0101000000000000000000F03F0000000000000040'),
3857))#x]
++- OneRowRelation
+
+
+-- !query
+SELECT
ST_Srid(ST_SetSrid(ST_GeogFromWKB(X'0101000000000000000000F03F0000000000000040'),
3857))
+-- !query analysis
+org.apache.spark.SparkIllegalArgumentException
+{
+ "errorClass" : "ST_INVALID_SRID_VALUE",
+ "sqlState" : "22023",
+ "messageParameters" : {
+ "srid" : "3857"
+ }
+}
+
+
+-- !query
+SELECT
ST_Srid(ST_SetSrid(ST_GeomFromWKB(X'0101000000000000000000F03F0000000000000040'),
9999))
+-- !query analysis
+org.apache.spark.SparkIllegalArgumentException
+{
+ "errorClass" : "ST_INVALID_SRID_VALUE",
+ "sqlState" : "22023",
+ "messageParameters" : {
+ "srid" : "9999"
+ }
+}
+
+
+-- !query
+SELECT COUNT(*) FROM geodata WHERE ST_Srid(ST_SetSrid(ST_GeogFromWKB(wkb),
4326)) <> 4326
+-- !query analysis
+Aggregate [count(1) AS count(1)#xL]
++- Filter NOT (st_srid(st_setsrid(st_geogfromwkb(wkb#x), 4326)) = 4326)
+ +- SubqueryAlias spark_catalog.default.geodata
+ +- Relation spark_catalog.default.geodata[wkb#x] parquet
+
+
+-- !query
+SELECT COUNT(*) FROM geodata WHERE ST_Srid(ST_SetSrid(ST_GeomFromWKB(wkb),
3857)) <> 3857
+-- !query analysis
+Aggregate [count(1) AS count(1)#xL]
++- Filter NOT (st_srid(st_setsrid(st_geomfromwkb(wkb#x), 3857)) = 3857)
+ +- SubqueryAlias spark_catalog.default.geodata
+ +- Relation spark_catalog.default.geodata[wkb#x] parquet
+
+
+-- !query
+SELECT COUNT(*) FROM geodata WHERE ST_Srid(ST_SetSrid(ST_GeogFromWKB(wkb),
3857)) IS NOT NULL
+-- !query analysis
+org.apache.spark.SparkIllegalArgumentException
+{
+ "errorClass" : "ST_INVALID_SRID_VALUE",
+ "sqlState" : "22023",
+ "messageParameters" : {
+ "srid" : "3857"
+ }
+}
+
+
+-- !query
+SELECT COUNT(*) FROM geodata WHERE ST_Srid(ST_SetSrid(ST_GeomFromWKB(wkb),
9999)) IS NOT NULL
+-- !query analysis
+org.apache.spark.SparkIllegalArgumentException
+{
+ "errorClass" : "ST_INVALID_SRID_VALUE",
+ "sqlState" : "22023",
+ "messageParameters" : {
+ "srid" : "9999"
+ }
+}
+
+
-- !query
DROP TABLE geodata
-- !query analysis
diff --git a/sql/core/src/test/resources/sql-tests/inputs/st-functions.sql
b/sql/core/src/test/resources/sql-tests/inputs/st-functions.sql
index 6785a5b5254b..b824be221122 100644
--- a/sql/core/src/test/resources/sql-tests/inputs/st-functions.sql
+++ b/sql/core/src/test/resources/sql-tests/inputs/st-functions.sql
@@ -37,5 +37,23 @@ SELECT
ST_Srid(ST_GeomFromWKB(X'0101000000000000000000F03F0000000000000040'));
SELECT COUNT(*) FROM geodata WHERE ST_Srid(ST_GeogFromWKB(wkb)) <> 4326;
SELECT COUNT(*) FROM geodata WHERE ST_Srid(ST_GeomFromWKB(wkb)) <> 0;
+------ ST modifier expressions
+
+---- ST_SetSrid
+
+-- 1. Driver-level queries.
+SELECT
ST_Srid(ST_SetSrid(ST_GeogFromWKB(X'0101000000000000000000F03F0000000000000040'),
4326));
+SELECT
ST_Srid(ST_SetSrid(ST_GeomFromWKB(X'0101000000000000000000F03F0000000000000040'),
3857));
+-- Error handling: invalid SRID.
+SELECT
ST_Srid(ST_SetSrid(ST_GeogFromWKB(X'0101000000000000000000F03F0000000000000040'),
3857));
+SELECT
ST_Srid(ST_SetSrid(ST_GeomFromWKB(X'0101000000000000000000F03F0000000000000040'),
9999));
+
+-- 2. Table-level queries.
+SELECT COUNT(*) FROM geodata WHERE ST_Srid(ST_SetSrid(ST_GeogFromWKB(wkb),
4326)) <> 4326;
+SELECT COUNT(*) FROM geodata WHERE ST_Srid(ST_SetSrid(ST_GeomFromWKB(wkb),
3857)) <> 3857;
+-- Error handling: invalid SRID.
+SELECT COUNT(*) FROM geodata WHERE ST_Srid(ST_SetSrid(ST_GeogFromWKB(wkb),
3857)) IS NOT NULL;
+SELECT COUNT(*) FROM geodata WHERE ST_Srid(ST_SetSrid(ST_GeomFromWKB(wkb),
9999)) IS NOT NULL;
+
-- Drop the test table.
DROP TABLE geodata;
diff --git
a/sql/core/src/test/resources/sql-tests/results/nonansi/st-functions.sql.out
b/sql/core/src/test/resources/sql-tests/results/nonansi/st-functions.sql.out
index f1e876600a09..c5b6daea764b 100644
--- a/sql/core/src/test/resources/sql-tests/results/nonansi/st-functions.sql.out
+++ b/sql/core/src/test/resources/sql-tests/results/nonansi/st-functions.sql.out
@@ -161,6 +161,98 @@ struct<count(1):bigint>
0
+-- !query
+SELECT
ST_Srid(ST_SetSrid(ST_GeogFromWKB(X'0101000000000000000000F03F0000000000000040'),
4326))
+-- !query schema
+struct<st_srid(st_setsrid(st_geogfromwkb(X'0101000000000000000000F03F0000000000000040'),
4326)):int>
+-- !query output
+4326
+
+
+-- !query
+SELECT
ST_Srid(ST_SetSrid(ST_GeomFromWKB(X'0101000000000000000000F03F0000000000000040'),
3857))
+-- !query schema
+struct<st_srid(st_setsrid(st_geomfromwkb(X'0101000000000000000000F03F0000000000000040'),
3857)):int>
+-- !query output
+3857
+
+
+-- !query
+SELECT
ST_Srid(ST_SetSrid(ST_GeogFromWKB(X'0101000000000000000000F03F0000000000000040'),
3857))
+-- !query schema
+struct<>
+-- !query output
+org.apache.spark.SparkIllegalArgumentException
+{
+ "errorClass" : "ST_INVALID_SRID_VALUE",
+ "sqlState" : "22023",
+ "messageParameters" : {
+ "srid" : "3857"
+ }
+}
+
+
+-- !query
+SELECT
ST_Srid(ST_SetSrid(ST_GeomFromWKB(X'0101000000000000000000F03F0000000000000040'),
9999))
+-- !query schema
+struct<>
+-- !query output
+org.apache.spark.SparkIllegalArgumentException
+{
+ "errorClass" : "ST_INVALID_SRID_VALUE",
+ "sqlState" : "22023",
+ "messageParameters" : {
+ "srid" : "9999"
+ }
+}
+
+
+-- !query
+SELECT COUNT(*) FROM geodata WHERE ST_Srid(ST_SetSrid(ST_GeogFromWKB(wkb),
4326)) <> 4326
+-- !query schema
+struct<count(1):bigint>
+-- !query output
+0
+
+
+-- !query
+SELECT COUNT(*) FROM geodata WHERE ST_Srid(ST_SetSrid(ST_GeomFromWKB(wkb),
3857)) <> 3857
+-- !query schema
+struct<count(1):bigint>
+-- !query output
+0
+
+
+-- !query
+SELECT COUNT(*) FROM geodata WHERE ST_Srid(ST_SetSrid(ST_GeogFromWKB(wkb),
3857)) IS NOT NULL
+-- !query schema
+struct<>
+-- !query output
+org.apache.spark.SparkIllegalArgumentException
+{
+ "errorClass" : "ST_INVALID_SRID_VALUE",
+ "sqlState" : "22023",
+ "messageParameters" : {
+ "srid" : "3857"
+ }
+}
+
+
+-- !query
+SELECT COUNT(*) FROM geodata WHERE ST_Srid(ST_SetSrid(ST_GeomFromWKB(wkb),
9999)) IS NOT NULL
+-- !query schema
+struct<>
+-- !query output
+org.apache.spark.SparkIllegalArgumentException
+{
+ "errorClass" : "ST_INVALID_SRID_VALUE",
+ "sqlState" : "22023",
+ "messageParameters" : {
+ "srid" : "9999"
+ }
+}
+
+
-- !query
DROP TABLE geodata
-- !query schema
diff --git a/sql/core/src/test/resources/sql-tests/results/st-functions.sql.out
b/sql/core/src/test/resources/sql-tests/results/st-functions.sql.out
index f1e876600a09..c5b6daea764b 100644
--- a/sql/core/src/test/resources/sql-tests/results/st-functions.sql.out
+++ b/sql/core/src/test/resources/sql-tests/results/st-functions.sql.out
@@ -161,6 +161,98 @@ struct<count(1):bigint>
0
+-- !query
+SELECT
ST_Srid(ST_SetSrid(ST_GeogFromWKB(X'0101000000000000000000F03F0000000000000040'),
4326))
+-- !query schema
+struct<st_srid(st_setsrid(st_geogfromwkb(X'0101000000000000000000F03F0000000000000040'),
4326)):int>
+-- !query output
+4326
+
+
+-- !query
+SELECT
ST_Srid(ST_SetSrid(ST_GeomFromWKB(X'0101000000000000000000F03F0000000000000040'),
3857))
+-- !query schema
+struct<st_srid(st_setsrid(st_geomfromwkb(X'0101000000000000000000F03F0000000000000040'),
3857)):int>
+-- !query output
+3857
+
+
+-- !query
+SELECT
ST_Srid(ST_SetSrid(ST_GeogFromWKB(X'0101000000000000000000F03F0000000000000040'),
3857))
+-- !query schema
+struct<>
+-- !query output
+org.apache.spark.SparkIllegalArgumentException
+{
+ "errorClass" : "ST_INVALID_SRID_VALUE",
+ "sqlState" : "22023",
+ "messageParameters" : {
+ "srid" : "3857"
+ }
+}
+
+
+-- !query
+SELECT
ST_Srid(ST_SetSrid(ST_GeomFromWKB(X'0101000000000000000000F03F0000000000000040'),
9999))
+-- !query schema
+struct<>
+-- !query output
+org.apache.spark.SparkIllegalArgumentException
+{
+ "errorClass" : "ST_INVALID_SRID_VALUE",
+ "sqlState" : "22023",
+ "messageParameters" : {
+ "srid" : "9999"
+ }
+}
+
+
+-- !query
+SELECT COUNT(*) FROM geodata WHERE ST_Srid(ST_SetSrid(ST_GeogFromWKB(wkb),
4326)) <> 4326
+-- !query schema
+struct<count(1):bigint>
+-- !query output
+0
+
+
+-- !query
+SELECT COUNT(*) FROM geodata WHERE ST_Srid(ST_SetSrid(ST_GeomFromWKB(wkb),
3857)) <> 3857
+-- !query schema
+struct<count(1):bigint>
+-- !query output
+0
+
+
+-- !query
+SELECT COUNT(*) FROM geodata WHERE ST_Srid(ST_SetSrid(ST_GeogFromWKB(wkb),
3857)) IS NOT NULL
+-- !query schema
+struct<>
+-- !query output
+org.apache.spark.SparkIllegalArgumentException
+{
+ "errorClass" : "ST_INVALID_SRID_VALUE",
+ "sqlState" : "22023",
+ "messageParameters" : {
+ "srid" : "3857"
+ }
+}
+
+
+-- !query
+SELECT COUNT(*) FROM geodata WHERE ST_Srid(ST_SetSrid(ST_GeomFromWKB(wkb),
9999)) IS NOT NULL
+-- !query schema
+struct<>
+-- !query output
+org.apache.spark.SparkIllegalArgumentException
+{
+ "errorClass" : "ST_INVALID_SRID_VALUE",
+ "sqlState" : "22023",
+ "messageParameters" : {
+ "srid" : "9999"
+ }
+}
+
+
-- !query
DROP TABLE geodata
-- !query schema
diff --git
a/sql/core/src/test/scala/org/apache/spark/sql/STExpressionsSuite.scala
b/sql/core/src/test/scala/org/apache/spark/sql/STExpressionsSuite.scala
index 1b73617d050e..700f9700ebc9 100644
--- a/sql/core/src/test/scala/org/apache/spark/sql/STExpressionsSuite.scala
+++ b/sql/core/src/test/scala/org/apache/spark/sql/STExpressionsSuite.scala
@@ -17,6 +17,7 @@
package org.apache.spark.sql
+import org.apache.spark.SparkIllegalArgumentException
import org.apache.spark.sql.catalyst.expressions._
import org.apache.spark.sql.catalyst.expressions.st._
import org.apache.spark.sql.test.SharedSparkSession
@@ -33,6 +34,11 @@ class STExpressionsSuite
private final val defaultGeometrySrid: Int =
ExpressionDefaults.DEFAULT_GEOMETRY_SRID
private final val defaultGeometryType: DataType =
GeometryType(defaultGeometrySrid)
+ // Private helper method to assert the data type of a query result.
+ private def assertType(query: String, expectedDataType: DataType) = {
+ assert(sql(query).schema.fields.head.dataType.sameType(expectedDataType))
+ }
+
/** ST reader/writer expressions. */
test("ST_AsBinary") {
@@ -79,4 +85,126 @@ class STExpressionsSuite
checkEvaluation(stSridGeometryNull, null)
}
+ /** ST modifier expressions. */
+
+ test("ST_SetSrid - expressions") {
+ // Test data: WKB representation of POINT(1 2).
+ val wkbString = "0101000000000000000000F03F0000000000000040"
+ val wkb = Hex.unhex(wkbString.getBytes())
+ val wkbLiteral = Literal.create(wkb, BinaryType)
+ val geographyLiteral = ST_GeogFromWKB(wkbLiteral)
+ val nullGeographyLiteral = Literal.create(null, defaultGeographyType)
+ val geometryLiteral = ST_GeomFromWKB(wkbLiteral)
+ val nullGeometryLiteral = Literal.create(null, defaultGeometryType)
+ val srid = 4326
+ val sridLiteral = Literal.create(srid, IntegerType)
+ val nullSridLiteral = Literal.create(null, IntegerType)
+ val invalidSrid = 9999
+ val invalidSridLiteral = Literal.create(9999, IntegerType)
+
+ // ST_SetSrid on GEOGRAPHY expression.
+ val geogLit = ST_SetSrid(geographyLiteral, sridLiteral)
+ assert(geogLit.dataType.sameType(GeographyType(srid)))
+ checkEvaluation(ST_AsBinary(geogLit), wkb)
+ val geogLitSrid = ST_Srid(geogLit)
+ assert(geogLitSrid.dataType.sameType(IntegerType))
+ checkEvaluation(geogLitSrid, srid)
+ // Test NULL handling on GEOGRAPHY.
+ val nullGeog = ST_SetSrid(nullGeographyLiteral, sridLiteral)
+ assert(nullGeog.dataType.sameType(GeographyType(srid)))
+ checkEvaluation(nullGeog, null)
+ val geogNullSrid = ST_SetSrid(geographyLiteral, nullSridLiteral)
+ assert(geogNullSrid.dataType.sameType(GeographyType("ANY")))
+ checkEvaluation(geogNullSrid, null)
+ // Test error handling for invalid SRID.
+ val geogInvalidSrid = ST_SetSrid(geographyLiteral, invalidSridLiteral)
+ checkError(
+ exception = intercept[SparkIllegalArgumentException] {
+ geogInvalidSrid.eval()
+ },
+ condition = "ST_INVALID_SRID_VALUE",
+ parameters = Map("srid" -> s"$invalidSrid")
+ )
+
+ // ST_SetSrid on GEOMETRY expression.
+ val geomLit = ST_SetSrid(geometryLiteral, sridLiteral)
+ assert(geomLit.dataType.sameType(GeometryType(srid)))
+ checkEvaluation(ST_AsBinary(geomLit), wkb)
+ val geomLitSrid = ST_Srid(geomLit)
+ assert(geomLitSrid.dataType.sameType(IntegerType))
+ checkEvaluation(geomLitSrid, srid)
+ // Test NULL handling on GEOMETRY.
+ val nullGeom = ST_SetSrid(nullGeometryLiteral, sridLiteral)
+ assert(nullGeom.dataType.sameType(GeometryType(srid)))
+ checkEvaluation(nullGeom, null)
+ val geomNullSrid = ST_SetSrid(geometryLiteral, nullSridLiteral)
+ assert(geomNullSrid.dataType.sameType(GeometryType("ANY")))
+ checkEvaluation(geomNullSrid, null)
+ // Test error handling for invalid SRID.
+ val geomInvalidSrid = ST_SetSrid(geometryLiteral, invalidSridLiteral)
+ checkError(
+ exception = intercept[SparkIllegalArgumentException] {
+ geomInvalidSrid.eval()
+ },
+ condition = "ST_INVALID_SRID_VALUE",
+ parameters = Map("srid" -> s"$invalidSrid")
+ )
+ }
+
+ test("ST_SetSrid - columns") {
+ // Test data: WKB representation of POINT(1 2).
+ val wkbString = "0101000000000000000000F03F0000000000000040"
+ val srid = 4326
+
+ withTable("tbl") {
+ // Construct the test table.
+ sql(s"CREATE TABLE tbl (wkb BINARY, srid INT)")
+ sql(s"INSERT INTO tbl VALUES (X'$wkbString', $srid)")
+
+ // ST_SetSrid on GEOGRAPHY column value, with SRID column value.
+ val geogColSridCol = "ST_SetSrid(ST_GeogFromWKB(wkb), srid)"
+ assertType(s"SELECT $geogColSridCol FROM tbl", GeographyType("ANY"))
+ assertType(s"SELECT ST_Srid($geogColSridCol) FROM tbl", IntegerType)
+ checkAnswer(sql(s"SELECT ST_Srid($geogColSridCol) FROM tbl"), Row(srid))
+ // ST_SetSrid on GEOMETRY column value, with SRID column value.
+ val geomColSridCol = "ST_SetSrid(ST_GeomFromWKB(wkb), srid)"
+ assertType(s"SELECT $geomColSridCol FROM tbl", GeometryType("ANY"))
+ assertType(s"SELECT ST_Srid($geomColSridCol) FROM tbl", IntegerType)
+ checkAnswer(sql(s"SELECT ST_Srid($geomColSridCol) FROM tbl"), Row(srid))
+
+ // ST_SetSrid on GEOGRAPHY literal value, with SRID column value.
+ val geogLitSridCol = s"ST_SetSrid(ST_GeogFromWKB(X'$wkbString'), srid)"
+ assertType(s"SELECT $geogLitSridCol FROM tbl", GeographyType("ANY"))
+ assertType(s"SELECT ST_Srid($geogLitSridCol) FROM tbl", IntegerType)
+ checkAnswer(sql(s"SELECT ST_Srid($geogLitSridCol) FROM tbl"), Row(srid))
+ // ST_SetSrid on GEOMETRY literal value, with SRID column value.
+ val geomLitSridCol = s"ST_SetSrid(ST_GeomFromWKB(X'$wkbString'), srid)"
+ assertType(s"SELECT $geomLitSridCol FROM tbl", GeometryType("ANY"))
+ assertType(s"SELECT ST_Srid($geomLitSridCol) FROM tbl", IntegerType)
+ checkAnswer(sql(s"SELECT ST_Srid($geomLitSridCol) FROM tbl"), Row(srid))
+
+ // ST_SetSrid on GEOGRAPHY column value, with SRID literal.
+ val geogColSridLit = s"ST_SetSrid(ST_GeogFromWKB(wkb), $srid)"
+ assertType(s"SELECT $geogColSridLit FROM tbl", GeographyType(srid))
+ assertType(s"SELECT ST_Srid($geogColSridLit) FROM tbl", IntegerType)
+ checkAnswer(sql(s"SELECT ST_Srid($geogColSridLit) FROM tbl"), Row(srid))
+ // ST_SetSrid on GEOMETRY column value, with SRID literal.
+ val geomColSridLit = s"ST_SetSrid(ST_GeomFromWKB(wkb), $srid)"
+ assertType(s"SELECT $geomColSridLit FROM tbl", GeometryType(srid))
+ assertType(s"SELECT ST_Srid($geomColSridLit) FROM tbl", IntegerType)
+ checkAnswer(sql(s"SELECT ST_Srid($geomColSridLit) FROM tbl"), Row(srid))
+
+ // ST_SetSrid on GEOGRAPHY literal value, with SRID literal.
+ val geogLitSridLit = s"ST_SetSrid(ST_GeogFromWKB(X'$wkbString'), $srid)"
+ assertType(s"SELECT $geogLitSridLit FROM tbl", GeographyType(srid))
+ assertType(s"SELECT ST_Srid($geogLitSridLit) FROM tbl", IntegerType)
+ checkAnswer(sql(s"SELECT ST_Srid($geogLitSridLit) FROM tbl"), Row(srid))
+ // ST_SetSrid on GEOMETRY literal value, with SRID literal.
+ val geomLitSridLit = s"ST_SetSrid(ST_GeomFromWKB(X'$wkbString'), $srid)"
+ assertType(s"SELECT $geomLitSridLit FROM tbl", GeometryType(srid))
+ assertType(s"SELECT ST_Srid($geomLitSridLit) FROM tbl", IntegerType)
+ checkAnswer(sql(s"SELECT ST_Srid($geomLitSridLit) FROM tbl"), Row(srid))
+ }
+ }
+
}
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]