This is an automated email from the ASF dual-hosted git repository.

cloud-fan pushed a commit to branch branch-4.x
in repository https://gitbox.apache.org/repos/asf/spark.git


The following commit(s) were added to refs/heads/branch-4.x by this push:
     new 89142b39777d [SPARK-56682][GEO][CONNECT][PYTHON][SQL] Extend the 
ST_AsBinary function to take optional endianness
89142b39777d is described below

commit 89142b39777d410af4ba62df371812bf95430a6e
Author: Uros Bojanic <[email protected]>
AuthorDate: Sat May 9 03:01:27 2026 +0800

    [SPARK-56682][GEO][CONNECT][PYTHON][SQL] Extend the ST_AsBinary function to 
take optional endianness
    
    ### What changes were proposed in this pull request?
    Extend the geometry & geography WKB writer function in SQL, Scala, and 
PySpark to take an optional second argument - the endianness: 
`st_asbinary(geo[, endianness])`.
    
    Arguments:
    - `geo` - A geospatial value, either a GEOGRAPHY or a GEOMETRY.
    - `endianness` -  The optional endianness of the output WKB.
    
    ### Why are the changes needed?
    The `ST_AsBinary` function should take an optional endianness value for the 
output WKB.
    
    ### Does this PR introduce _any_ user-facing change?
    Yes, the `st_asbinary` function now takes an optional second argument (the 
endianness).
    
    ### How was this patch tested?
    Added new tests for the catalyst expression, SQL function, Scala function, 
and PySpark function.
    
    ### Was this patch authored or co-authored using generative AI tooling?
    No.
    
    Closes #55631 from uros-db/geo-ST_AsBinary_endianness.
    
    Lead-authored-by: Uros Bojanic <[email protected]>
    Co-authored-by: Wenchen Fan <[email protected]>
    Signed-off-by: Wenchen Fan <[email protected]>
    (cherry picked from commit bae066b57c0fa3bc8400f1bd5fd69c67a8682c65)
    Signed-off-by: Wenchen Fan <[email protected]>
---
 .../src/main/resources/error/error-conditions.json |   6 +
 python/pyspark/errors/error-conditions.json        |   6 +
 python/pyspark/sql/connect/functions/builtin.py    |   8 +-
 python/pyspark/sql/functions/builtin.py            |  34 +++-
 python/pyspark/sql/tests/test_functions.py         |  16 +-
 .../scala/org/apache/spark/sql/functions.scala     |  18 ++
 .../org/apache/spark/sql/catalyst/util/Geo.java    |   1 -
 .../apache/spark/sql/catalyst/util/Geography.java  |   5 -
 .../apache/spark/sql/catalyst/util/Geometry.java   |   5 -
 .../apache/spark/sql/catalyst/util/STUtils.java    |  21 ++-
 .../catalyst/expressions/st/stExpressions.scala    |  39 ++--
 .../spark/sql/errors/QueryExecutionErrors.scala    |   8 +
 .../sql/catalyst/CatalystTypeConvertersSuite.scala |  28 +--
 .../sql/catalyst/util/GeographyExecutionSuite.java |   6 +-
 .../sql/catalyst/util/GeometryExecutionSuite.java  |   6 +-
 .../spark/sql/catalyst/util/StUtilsSuite.java      |   7 +-
 .../sql-functions/sql-expression-schema.md         |   6 +-
 .../analyzer-results/st-functions.sql.out          | 183 ++++++++++++++++--
 .../resources/sql-tests/inputs/st-functions.sql    |  27 +++
 .../sql-tests/results/st-functions.sql.out         | 208 ++++++++++++++++++++-
 .../org/apache/spark/sql/STExpressionsSuite.scala  |  52 ++++--
 .../org/apache/spark/sql/STFunctionsSuite.scala    |  35 +++-
 22 files changed, 622 insertions(+), 103 deletions(-)

diff --git a/common/utils/src/main/resources/error/error-conditions.json 
b/common/utils/src/main/resources/error/error-conditions.json
index 48a9f57b75dd..95f0c303e35f 100644
--- a/common/utils/src/main/resources/error/error-conditions.json
+++ b/common/utils/src/main/resources/error/error-conditions.json
@@ -7032,6 +7032,12 @@
     ],
     "sqlState" : "22023"
   },
+  "ST_INVALID_ENDIANNESS_VALUE" : {
+    "message" : [
+      "Endianness '<endianness>' must be either 'NDR' (little-endian) or 'XDR' 
(big-endian)."
+    ],
+    "sqlState" : "22023"
+  },
   "ST_INVALID_SRID_VALUE" : {
     "message" : [
       "Invalid or unsupported SRID (spatial reference identifier) value: 
<srid>."
diff --git a/python/pyspark/errors/error-conditions.json 
b/python/pyspark/errors/error-conditions.json
index 808127772f72..485d48b6d7d5 100644
--- a/python/pyspark/errors/error-conditions.json
+++ b/python/pyspark/errors/error-conditions.json
@@ -958,6 +958,12 @@
     ],
     "sqlState" : "22023"
   },
+  "ST_INVALID_ENDIANNESS_VALUE" : {
+    "message" : [
+      "Endianness '<endianness>' must be either 'NDR' (little-endian) or 'XDR' 
(big-endian)."
+    ],
+    "sqlState" : "22023"
+  },
   "ST_INVALID_SRID_VALUE" : {
     "message" : [
       "Invalid or unsupported SRID (spatial reference identifier) value: 
<srid>."
diff --git a/python/pyspark/sql/connect/functions/builtin.py 
b/python/pyspark/sql/connect/functions/builtin.py
index 76e3f40a101a..22e52d91232c 100644
--- a/python/pyspark/sql/connect/functions/builtin.py
+++ b/python/pyspark/sql/connect/functions/builtin.py
@@ -5417,8 +5417,12 @@ bitmap_and_agg.__doc__ = 
pysparkfuncs.bitmap_and_agg.__doc__
 # Geospatial ST Functions
 
 
-def st_asbinary(geo: "ColumnOrName") -> Column:
-    return _invoke_function_over_columns("st_asbinary", geo)
+def st_asbinary(geo: "ColumnOrName", endianness: Optional["ColumnOrName"] = 
None) -> Column:
+    if endianness is None:
+        return _invoke_function_over_columns("st_asbinary", geo)
+    else:
+        _endianness = lit(endianness) if isinstance(endianness, str) else 
endianness
+        return _invoke_function_over_columns("st_asbinary", geo, _endianness)
 
 
 st_asbinary.__doc__ = pysparkfuncs.st_asbinary.__doc__
diff --git a/python/pyspark/sql/functions/builtin.py 
b/python/pyspark/sql/functions/builtin.py
index 5e0fd250c8a9..be948a22a30f 100644
--- a/python/pyspark/sql/functions/builtin.py
+++ b/python/pyspark/sql/functions/builtin.py
@@ -26379,15 +26379,21 @@ def bucket(numBuckets: Union[Column, int], col: 
"ColumnOrName") -> Column:
 
 
 @_try_remote_functions
-def st_asbinary(geo: "ColumnOrName") -> Column:
+def st_asbinary(geo: "ColumnOrName", endianness: Optional["ColumnOrName"] = 
None) -> Column:
     """Returns the input GEOGRAPHY or GEOMETRY value in WKB format.
 
     .. versionadded:: 4.1.0
 
+    .. versionchanged:: 4.2.0
+        Added the optional `endianness` parameter.
+
     Parameters
     ----------
     geo : :class:`~pyspark.sql.Column` or str
         A geospatial value, either a GEOGRAPHY or a GEOMETRY.
+    endianness : :class:`~pyspark.sql.Column` or str, optional
+        The optional endianness of the output WKB, 'NDR' for little-endian 
(default) or 'XDR' for
+        big-endian.
 
     Examples
     --------
@@ -26396,15 +26402,31 @@ def st_asbinary(geo: "ColumnOrName") -> Column:
     >>> from pyspark.sql import functions as sf
     >>> df = 
spark.createDataFrame([(bytes.fromhex('0101000000000000000000F03F0000000000000040'),)],
 ['wkb'])  # noqa
     >>> df.select(sf.hex(sf.st_asbinary(sf.st_geogfromwkb('wkb')))).collect()
-    
[Row(hex(st_asbinary(st_geogfromwkb(wkb)))='0101000000000000000000F03F0000000000000040')]
+    [Row(hex(st_asbinary(st_geogfromwkb(wkb), 
NDR))='0101000000000000000000F03F0000000000000040')]
 
     Example 2: Getting WKB from GEOMETRY.
     >>> from pyspark.sql import functions as sf
     >>> df = 
spark.createDataFrame([(bytes.fromhex('0101000000000000000000F03F0000000000000040'),)],
 ['wkb'])  # noqa
     >>> df.select(sf.hex(sf.st_asbinary(sf.st_geomfromwkb('wkb')))).collect()
-    [Row(hex(st_asbinary(st_geomfromwkb(wkb, 
0)))='0101000000000000000000F03F0000000000000040')]
+    [Row(hex(st_asbinary(st_geomfromwkb(wkb, 0), 
NDR))='0101000000000000000000F03F0000000000000040')]
+
+    Example 3: Getting WKB (little-endian) from GEOGRAPHY.
+    >>> from pyspark.sql import functions as sf
+    >>> df = 
spark.createDataFrame([(bytes.fromhex('0101000000000000000000F03F0000000000000040'),)],
 ['wkb'])  # noqa
+    >>> df.select(sf.hex(sf.st_asbinary(sf.st_geogfromwkb('wkb'), 
'NDR'))).collect()
+    [Row(hex(st_asbinary(st_geogfromwkb(wkb), 
NDR))='0101000000000000000000F03F0000000000000040')]
+
+    Example 4: Getting WKB (big-endian) from GEOMETRY.
+    >>> from pyspark.sql import functions as sf
+    >>> df = 
spark.createDataFrame([(bytes.fromhex('0101000000000000000000F03F0000000000000040'),)],
 ['wkb'])  # noqa
+    >>> df.select(sf.hex(sf.st_asbinary(sf.st_geomfromwkb('wkb'), 
'XDR'))).collect()
+    [Row(hex(st_asbinary(st_geomfromwkb(wkb, 0), 
XDR))='00000000013FF00000000000004000000000000000')]
     """
-    return _invoke_function_over_columns("st_asbinary", geo)
+    if endianness is None:
+        return _invoke_function_over_columns("st_asbinary", geo)
+    else:
+        _endianness = lit(endianness) if isinstance(endianness, str) else 
endianness
+        return _invoke_function_over_columns("st_asbinary", geo, _endianness)
 
 
 @_try_remote_functions
@@ -26423,7 +26445,7 @@ def st_geogfromwkb(wkb: "ColumnOrName") -> Column:
     >>> from pyspark.sql import functions as sf
     >>> df = 
spark.createDataFrame([(bytes.fromhex('0101000000000000000000F03F0000000000000040'),)],
 ['wkb'])  # noqa
     >>> df.select(sf.hex(sf.st_asbinary(sf.st_geogfromwkb('wkb')))).collect()
-    
[Row(hex(st_asbinary(st_geogfromwkb(wkb)))='0101000000000000000000F03F0000000000000040')]
+    [Row(hex(st_asbinary(st_geogfromwkb(wkb), 
NDR))='0101000000000000000000F03F0000000000000040')]
     """
     return _invoke_function_over_columns("st_geogfromwkb", wkb)
 
@@ -26448,7 +26470,7 @@ def st_geomfromwkb(
     >>> from pyspark.sql import functions as sf
     >>> df = 
spark.createDataFrame([(bytes.fromhex('0101000000000000000000F03F0000000000000040'),)],
 ['wkb'])  # noqa
     >>> df.select(sf.hex(sf.st_asbinary(sf.st_geomfromwkb('wkb')))).collect()
-    [Row(hex(st_asbinary(st_geomfromwkb(wkb, 
0)))='0101000000000000000000F03F0000000000000040')]
+    [Row(hex(st_asbinary(st_geomfromwkb(wkb, 0), 
NDR))='0101000000000000000000F03F0000000000000040')]
     """
     if srid is None:
         return _invoke_function_over_columns("st_geomfromwkb", wkb)
diff --git a/python/pyspark/sql/tests/test_functions.py 
b/python/pyspark/sql/tests/test_functions.py
index 417e93760ef3..75824d3ebe49 100644
--- a/python/pyspark/sql/tests/test_functions.py
+++ b/python/pyspark/sql/tests/test_functions.py
@@ -3848,16 +3848,28 @@ class FunctionsTestsMixin:
 
     def test_st_asbinary(self):
         df = self.spark.createDataFrame(
-            [(bytes.fromhex("0101000000000000000000F03F0000000000000040"),)],
-            ["wkb"],
+            [(bytes.fromhex("0101000000000000000000F03F0000000000000040"), 
"XDR")],
+            ["wkb", "end"],
         )
         results = df.select(
             F.hex(F.st_asbinary(F.st_geogfromwkb("wkb"))),
+            F.hex(F.st_asbinary(F.st_geogfromwkb("wkb"), "NDR")),
+            F.hex(F.st_asbinary(F.st_geogfromwkb("wkb"), "XDR")),
+            F.hex(F.st_asbinary(F.st_geogfromwkb("wkb"), F.col("end"))),
             F.hex(F.st_asbinary(F.st_geomfromwkb("wkb"))),
+            F.hex(F.st_asbinary(F.st_geomfromwkb("wkb"), "NDR")),
+            F.hex(F.st_asbinary(F.st_geomfromwkb("wkb"), "XDR")),
+            F.hex(F.st_asbinary(F.st_geomfromwkb("wkb"), F.col("end"))),
         ).collect()
         expected = Row(
             "0101000000000000000000F03F0000000000000040",
             "0101000000000000000000F03F0000000000000040",
+            "00000000013FF00000000000004000000000000000",
+            "00000000013FF00000000000004000000000000000",
+            "0101000000000000000000F03F0000000000000040",
+            "0101000000000000000000F03F0000000000000040",
+            "00000000013FF00000000000004000000000000000",
+            "00000000013FF00000000000004000000000000000",
         )
         self.assertEqual(results, [expected])
 
diff --git a/sql/api/src/main/scala/org/apache/spark/sql/functions.scala 
b/sql/api/src/main/scala/org/apache/spark/sql/functions.scala
index ccc7820d5d95..4ad731f6d8b0 100644
--- a/sql/api/src/main/scala/org/apache/spark/sql/functions.scala
+++ b/sql/api/src/main/scala/org/apache/spark/sql/functions.scala
@@ -11166,6 +11166,24 @@ object functions {
   def st_asbinary(geo: Column): Column =
     Column.fn("st_asbinary", geo)
 
+  /**
+   * Returns the input GEOGRAPHY or GEOMETRY value in WKB format using the 
specified endianness.
+   *
+   * @group st_funcs
+   * @since 4.2.0
+   */
+  def st_asbinary(geo: Column, endianness: Column): Column =
+    Column.fn("st_asbinary", geo, endianness)
+
+  /**
+   * Returns the input GEOGRAPHY or GEOMETRY value in WKB format using the 
specified endianness.
+   *
+   * @group st_funcs
+   * @since 4.2.0
+   */
+  def st_asbinary(geo: Column, endianness: String): Column =
+    Column.fn("st_asbinary", geo, lit(endianness))
+
   /**
    * Parses the WKB description of a geography and returns the corresponding 
GEOGRAPHY value.
    *
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 bf723a8efef9..1002cdd28a77 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
@@ -58,7 +58,6 @@ interface Geo {
   /** Binary converters. */
 
   // Returns the Well-Known Binary (WKB) representation of the geo object.
-  byte[] toWkb();
   byte[] toWkb(ByteOrder endianness);
 
   // Returns the Extended Well-Known Binary (EWKB) representation of the geo 
object.
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 f446d71d5a5b..dd5b69a12e7a 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
@@ -129,11 +129,6 @@ public final class Geography implements Geo {
 
   /** Geography binary standard format converters: WKB and EWKB. */
 
-  @Override
-  public byte[] toWkb() {
-    return toWkbInternal(DEFAULT_ENDIANNESS);
-  }
-
   @Override
   public byte[] toWkb(ByteOrder endianness) {
     return toWkbInternal(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 58be589b86ff..74cbb9d3b418 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
@@ -129,11 +129,6 @@ public final class Geometry implements Geo {
 
   /** Geometry binary standard format converters: WKB and EWKB. */
 
-  @Override
-  public byte[] toWkb() {
-    return toWkbInternal(DEFAULT_ENDIANNESS);
-  }
-
   @Override
   public byte[] toWkb(ByteOrder endianness) {
     return toWkbInternal(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 4026bbb2c22d..c5d57fd08fed 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
@@ -25,6 +25,8 @@ import org.apache.spark.unsafe.types.GeographyVal;
 import org.apache.spark.unsafe.types.GeometryVal;
 import org.apache.spark.unsafe.types.UTF8String;
 
+import java.nio.ByteOrder;
+
 // This class defines static methods that used to implement ST expressions 
using `StaticInvoke`.
 public final class STUtils {
 
@@ -112,13 +114,28 @@ public final class STUtils {
 
   /** Methods for implementing ST expressions. */
 
+  private static ByteOrder parseEndianness(UTF8String endianness) {
+    String endiannessString = endianness.toString();
+    if (endiannessString.equalsIgnoreCase("NDR")) return 
ByteOrder.LITTLE_ENDIAN;
+    if (endiannessString.equalsIgnoreCase("XDR")) return ByteOrder.BIG_ENDIAN;
+    throw 
QueryExecutionErrors.stInvalidArgumentErrorInvalidEndiannessValue(endiannessString);
+  }
+
   // ST_AsBinary
   public static byte[] stAsBinary(GeographyVal geo) {
-    return fromPhysVal(geo).toWkb();
+    return fromPhysVal(geo).toWkb(ByteOrder.LITTLE_ENDIAN);
+  }
+
+  public static byte[] stAsBinary(GeographyVal geo, UTF8String endianness) {
+    return fromPhysVal(geo).toWkb(parseEndianness(endianness));
   }
 
   public static byte[] stAsBinary(GeometryVal geo) {
-    return fromPhysVal(geo).toWkb();
+    return fromPhysVal(geo).toWkb(ByteOrder.LITTLE_ENDIAN);
+  }
+
+  public static byte[] stAsBinary(GeometryVal geo, UTF8String endianness) {
+    return fromPhysVal(geo).toWkb(parseEndianness(endianness));
   }
 
   // ST_AsEWKT
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 986c0ef3a2ef..4e9a783b1b73 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
@@ -24,6 +24,7 @@ import org.apache.spark.sql.catalyst.expressions.objects._
 import org.apache.spark.sql.catalyst.trees._
 import org.apache.spark.sql.catalyst.util.{Geography, Geometry, STUtils}
 import org.apache.spark.sql.internal.SQLConf
+import org.apache.spark.sql.internal.types.StringTypeWithCollation
 import org.apache.spark.sql.types._
 
 /**
@@ -51,55 +52,69 @@ sealed trait GeospatialInputTypes extends 
ImplicitCastInputTypes {
 private[sql] object ExpressionDefaults {
   val DEFAULT_GEOGRAPHY_SRID: Int = Geography.DEFAULT_SRID
   val DEFAULT_GEOMETRY_SRID: Int = Geometry.DEFAULT_SRID
+  val DEFAULT_WKB_ENDIANNESS: String = "NDR"
 }
 
 /** ST writer expressions. */
 
 /**
- * Returns the input GEOGRAPHY or GEOMETRY value in WKB format.
+ * Returns the input GEOGRAPHY or GEOMETRY value in WKB format using the 
specified endianness, if
+ * provided. If no endianness is provided, it defaults to little endian.
  * See 
https://en.wikipedia.org/wiki/Well-known_text_representation_of_geometry#Well-known_binary
  * for more details on the WKB format.
  */
 @ExpressionDescription(
-  usage = "_FUNC_(geo) - Returns the geospatial value (value of type GEOGRAPHY 
or GEOMETRY) "
-    + "in WKB format.",
+  usage = "_FUNC_(geo[, endianness]) - Returns the geospatial value (value of 
type GEOGRAPHY or "
+    + "GEOMETRY) in WKB format using the specified endianness ('NDR' for 
little-endian, 'XDR' for "
+    + "big-endian), if provided. Defaults to little-endian encoding.",
   arguments = """
     Arguments:
       * geo - A geospatial value, either a GEOGRAPHY or a GEOMETRY.
+      * endianness - The optional endianness of the output WKB, 'NDR' for 
little-endian (default)
+                     or 'XDR' for big-endian.
   """,
   examples = """
     Examples:
       > SELECT 
hex(_FUNC_(st_geogfromwkb(X'0101000000000000000000F03F0000000000000040')));
        0101000000000000000000F03F0000000000000040
-      > SELECT 
hex(_FUNC_(st_geomfromwkb(X'0101000000000000000000F03F0000000000000040')));
-       0101000000000000000000F03F0000000000000040
+      > SELECT 
hex(_FUNC_(st_geomfromwkb(X'0101000000000000000000F03F0000000000000040'), 
'XDR'));
+       00000000013FF00000000000004000000000000000
   """,
   since = "4.1.0",
   group = "st_funcs"
 )
-case class ST_AsBinary(geo: Expression)
+case class ST_AsBinary(geo: Expression, endianness: Expression)
     extends RuntimeReplaceable
     with GeospatialInputTypes
-    with UnaryLike[Expression] {
+    with BinaryLike[Expression] {
+
+  // If no endianness is given, default to little-endian encoding which is 
represented by "NDR".
+  def this(geo: Expression) = {
+    this(geo, Literal(ExpressionDefaults.DEFAULT_WKB_ENDIANNESS))
+  }
 
   override def inputTypes: Seq[AbstractDataType] = Seq(
-    TypeCollection(GeographyType, GeometryType)
+    TypeCollection(GeographyType, GeometryType),
+    StringTypeWithCollation(supportsTrimCollation = true)
   )
 
   override lazy val replacement: Expression = StaticInvoke(
     classOf[STUtils],
     BinaryType,
     "stAsBinary",
-    Seq(geo),
+    Seq(geo, endianness),
     returnNullable = false
   )
 
   override def prettyName: String = "st_asbinary"
 
-  override def child: Expression = geo
+  override def left: Expression = geo
 
-  override protected def withNewChildInternal(newChild: Expression): 
ST_AsBinary =
-    copy(geo = newChild)
+  override def right: Expression = endianness
+
+  override protected def withNewChildrenInternal(
+      newLeft: Expression,
+      newRight: Expression): ST_AsBinary = copy(geo = newLeft, endianness = 
newRight)
 }
 
 /** ST reader expressions. */
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 84fb16521105..0aa830827687 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
@@ -666,6 +666,14 @@ private[sql] object QueryExecutionErrors extends 
QueryErrorsBase with ExecutionE
       summary = "")
   }
 
+  def stInvalidArgumentErrorInvalidEndiannessValue(
+      endianness: String): SparkIllegalArgumentException = {
+    new SparkIllegalArgumentException(
+      errorClass = "ST_INVALID_ENDIANNESS_VALUE",
+      messageParameters = Map("endianness" -> endianness)
+    )
+  }
+
   def stInvalidSridValueError(srid: String): SparkIllegalArgumentException = {
     new SparkIllegalArgumentException(
       errorClass = "ST_INVALID_SRID_VALUE",
diff --git 
a/sql/catalyst/src/test/scala/org/apache/spark/sql/catalyst/CatalystTypeConvertersSuite.scala
 
b/sql/catalyst/src/test/scala/org/apache/spark/sql/catalyst/CatalystTypeConvertersSuite.scala
index 9f4ce6797cf8..b730a6c27a3b 100644
--- 
a/sql/catalyst/src/test/scala/org/apache/spark/sql/catalyst/CatalystTypeConvertersSuite.scala
+++ 
b/sql/catalyst/src/test/scala/org/apache/spark/sql/catalyst/CatalystTypeConvertersSuite.scala
@@ -459,12 +459,14 @@ class CatalystTypeConvertersSuite extends SparkFunSuite 
with SQLHelper {
   private val pointWkb: Array[Byte] = 
"010100000000000000000031400000000000001C40"
     .grouped(2).map(Integer.parseInt(_, 16).toByte).toArray
 
+  private val NDR: UTF8String = UTF8String.fromString("NDR")
+
   test("converting Geometry to GeometryType via convertToCatalyst") {
     val geom = Geometry.fromWKB(pointWkb, 0)
     val result = CatalystTypeConverters.convertToCatalyst(geom)
     assert(result.isInstanceOf[GeometryVal])
     val resultVal = result.asInstanceOf[GeometryVal]
-    assert(java.util.Arrays.equals(STUtils.stAsBinary(resultVal), pointWkb))
+    assert(java.util.Arrays.equals(STUtils.stAsBinary(resultVal, NDR), 
pointWkb))
     assert(STUtils.stSrid(resultVal) === 0)
   }
 
@@ -473,7 +475,7 @@ class CatalystTypeConvertersSuite extends SparkFunSuite 
with SQLHelper {
     val result = CatalystTypeConverters.convertToCatalyst(geom)
     assert(result.isInstanceOf[GeometryVal])
     val resultVal = result.asInstanceOf[GeometryVal]
-    assert(java.util.Arrays.equals(STUtils.stAsBinary(resultVal), pointWkb))
+    assert(java.util.Arrays.equals(STUtils.stAsBinary(resultVal, NDR), 
pointWkb))
     assert(STUtils.stSrid(resultVal) === 4326)
   }
 
@@ -482,7 +484,7 @@ class CatalystTypeConvertersSuite extends SparkFunSuite 
with SQLHelper {
     val result = CatalystTypeConverters.convertToCatalyst(geog)
     assert(result.isInstanceOf[GeographyVal])
     val resultVal = result.asInstanceOf[GeographyVal]
-    assert(java.util.Arrays.equals(STUtils.stAsBinary(resultVal), pointWkb))
+    assert(java.util.Arrays.equals(STUtils.stAsBinary(resultVal, NDR), 
pointWkb))
     assert(STUtils.stSrid(resultVal) === 4326)
   }
 
@@ -508,7 +510,7 @@ class CatalystTypeConvertersSuite extends SparkFunSuite 
with SQLHelper {
     val result = converter(geom)
     assert(result.isInstanceOf[GeometryVal])
     val resultVal = result.asInstanceOf[GeometryVal]
-    assert(java.util.Arrays.equals(STUtils.stAsBinary(resultVal), pointWkb))
+    assert(java.util.Arrays.equals(STUtils.stAsBinary(resultVal, NDR), 
pointWkb))
     assert(STUtils.stSrid(resultVal) === 0)
   }
 
@@ -519,7 +521,7 @@ class CatalystTypeConvertersSuite extends SparkFunSuite 
with SQLHelper {
     val result = converter(geog)
     assert(result.isInstanceOf[GeographyVal])
     val resultVal = result.asInstanceOf[GeographyVal]
-    assert(java.util.Arrays.equals(STUtils.stAsBinary(resultVal), pointWkb))
+    assert(java.util.Arrays.equals(STUtils.stAsBinary(resultVal, NDR), 
pointWkb))
     assert(STUtils.stSrid(resultVal) === 4326)
   }
 
@@ -581,7 +583,7 @@ class CatalystTypeConvertersSuite extends SparkFunSuite 
with SQLHelper {
     val element = array.get(0, GeometryType("ANY"))
     assert(element.isInstanceOf[GeometryVal])
     assert(java.util.Arrays.equals(
-      STUtils.stAsBinary(element.asInstanceOf[GeometryVal]), pointWkb))
+      STUtils.stAsBinary(element.asInstanceOf[GeometryVal], NDR), pointWkb))
   }
 
   test("convertToCatalyst with Geometry nested in Array") {
@@ -593,7 +595,7 @@ class CatalystTypeConvertersSuite extends SparkFunSuite 
with SQLHelper {
     val element = array.get(0, GeometryType("ANY"))
     assert(element.isInstanceOf[GeometryVal])
     assert(java.util.Arrays.equals(
-      STUtils.stAsBinary(element.asInstanceOf[GeometryVal]), pointWkb))
+      STUtils.stAsBinary(element.asInstanceOf[GeometryVal], NDR), pointWkb))
   }
 
   test("convertToCatalyst with Geometry nested in Map") {
@@ -604,7 +606,7 @@ class CatalystTypeConvertersSuite extends SparkFunSuite 
with SQLHelper {
     val value = mapData.valueArray.get(0, GeometryType("ANY"))
     assert(value.isInstanceOf[GeometryVal])
     assert(java.util.Arrays.equals(
-      STUtils.stAsBinary(value.asInstanceOf[GeometryVal]), pointWkb))
+      STUtils.stAsBinary(value.asInstanceOf[GeometryVal], NDR), pointWkb))
   }
 
   test("convertToCatalyst with Geometry nested in Row") {
@@ -614,7 +616,7 @@ class CatalystTypeConvertersSuite extends SparkFunSuite 
with SQLHelper {
     val element = result.asInstanceOf[InternalRow].get(0, GeometryType("ANY"))
     assert(element.isInstanceOf[GeometryVal])
     assert(java.util.Arrays.equals(
-      STUtils.stAsBinary(element.asInstanceOf[GeometryVal]), pointWkb))
+      STUtils.stAsBinary(element.asInstanceOf[GeometryVal], NDR), pointWkb))
   }
 
   test("convertToCatalyst with Geography nested in Seq") {
@@ -626,7 +628,7 @@ class CatalystTypeConvertersSuite extends SparkFunSuite 
with SQLHelper {
     val element = array.get(0, GeographyType("ANY"))
     assert(element.isInstanceOf[GeographyVal])
     assert(java.util.Arrays.equals(
-      STUtils.stAsBinary(element.asInstanceOf[GeographyVal]), pointWkb))
+      STUtils.stAsBinary(element.asInstanceOf[GeographyVal], NDR), pointWkb))
   }
 
   test("convertToCatalyst with Geography nested in Array") {
@@ -638,7 +640,7 @@ class CatalystTypeConvertersSuite extends SparkFunSuite 
with SQLHelper {
     val element = array.get(0, GeographyType("ANY"))
     assert(element.isInstanceOf[GeographyVal])
     assert(java.util.Arrays.equals(
-      STUtils.stAsBinary(element.asInstanceOf[GeographyVal]), pointWkb))
+      STUtils.stAsBinary(element.asInstanceOf[GeographyVal], NDR), pointWkb))
   }
 
   test("convertToCatalyst with Geography nested in Map") {
@@ -649,7 +651,7 @@ class CatalystTypeConvertersSuite extends SparkFunSuite 
with SQLHelper {
     val value = mapData.valueArray.get(0, GeographyType("ANY"))
     assert(value.isInstanceOf[GeographyVal])
     assert(java.util.Arrays.equals(
-      STUtils.stAsBinary(value.asInstanceOf[GeographyVal]), pointWkb))
+      STUtils.stAsBinary(value.asInstanceOf[GeographyVal], NDR), pointWkb))
   }
 
   test("convertToCatalyst with Geography nested in Row") {
@@ -659,6 +661,6 @@ class CatalystTypeConvertersSuite extends SparkFunSuite 
with SQLHelper {
     val element = result.asInstanceOf[InternalRow].get(0, GeographyType("ANY"))
     assert(element.isInstanceOf[GeographyVal])
     assert(java.util.Arrays.equals(
-      STUtils.stAsBinary(element.asInstanceOf[GeographyVal]), pointWkb))
+      STUtils.stAsBinary(element.asInstanceOf[GeographyVal], NDR), pointWkb))
   }
 }
diff --git 
a/sql/catalyst/src/test/scala/org/apache/spark/sql/catalyst/util/GeographyExecutionSuite.java
 
b/sql/catalyst/src/test/scala/org/apache/spark/sql/catalyst/util/GeographyExecutionSuite.java
index fece3e36bc59..537aa96f7026 100644
--- 
a/sql/catalyst/src/test/scala/org/apache/spark/sql/catalyst/util/GeographyExecutionSuite.java
+++ 
b/sql/catalyst/src/test/scala/org/apache/spark/sql/catalyst/util/GeographyExecutionSuite.java
@@ -101,7 +101,7 @@ class GeographyExecutionSuite {
     byte[] wkb = getTestWKBPoint();
     Geography geography = Geography.fromWkb(wkb, 4326);
     assertNotNull(geography);
-    assertArrayEquals(wkb, geography.toWkb());
+    assertArrayEquals(wkb, geography.toWkb(ByteOrder.LITTLE_ENDIAN));
     assertEquals(4326, geography.srid());
   }
 
@@ -110,7 +110,7 @@ class GeographyExecutionSuite {
     byte[] wkb = getTestWKBPoint();
     Geography geography = Geography.fromWkb(wkb);
     assertNotNull(geography);
-    assertArrayEquals(wkb, geography.toWkb());
+    assertArrayEquals(wkb, geography.toWkb(ByteOrder.LITTLE_ENDIAN));
     assertEquals(4326, geography.srid());
   }
 
@@ -178,7 +178,7 @@ class GeographyExecutionSuite {
     Geography geography = Geography.fromBytes(testGeographyVal);
     // WKB value (endianness: NDR) corresponding to WKT: POINT(1 2).
     byte[] wkb = 
HexFormat.of().parseHex("0101000000000000000000f03f0000000000000040");
-    assertArrayEquals(wkb, geography.toWkb());
+    assertArrayEquals(wkb, geography.toWkb(ByteOrder.LITTLE_ENDIAN));
   }
 
   @Test
diff --git 
a/sql/catalyst/src/test/scala/org/apache/spark/sql/catalyst/util/GeometryExecutionSuite.java
 
b/sql/catalyst/src/test/scala/org/apache/spark/sql/catalyst/util/GeometryExecutionSuite.java
index 5d0b11e969ad..7258f5915558 100644
--- 
a/sql/catalyst/src/test/scala/org/apache/spark/sql/catalyst/util/GeometryExecutionSuite.java
+++ 
b/sql/catalyst/src/test/scala/org/apache/spark/sql/catalyst/util/GeometryExecutionSuite.java
@@ -113,7 +113,7 @@ class GeometryExecutionSuite {
     byte[] wkb = getTestWKBPoint();
     Geometry geometry = Geometry.fromWkb(wkb, 4326);
     assertNotNull(geometry);
-    assertArrayEquals(wkb, geometry.toWkb());
+    assertArrayEquals(wkb, geometry.toWkb(ByteOrder.LITTLE_ENDIAN));
     assertEquals(4326, geometry.srid());
   }
 
@@ -124,7 +124,7 @@ class GeometryExecutionSuite {
     // Once we implement the appropriate parsing logic, this test should be 
updated accordingly.
     Geometry geometry = Geometry.fromWkb(wkb);
     assertNotNull(geometry);
-    assertArrayEquals(wkb, geometry.toWkb());
+    assertArrayEquals(wkb, geometry.toWkb(ByteOrder.LITTLE_ENDIAN));
     assertEquals(0, geometry.srid());
   }
 
@@ -192,7 +192,7 @@ class GeometryExecutionSuite {
     Geometry geometry = Geometry.fromBytes(testGeometryVal);
     // WKB value (endianness: NDR) corresponding to WKT: POINT(1 2).
     byte[] wkb = 
HexFormat.of().parseHex("0101000000000000000000f03f0000000000000040");
-    assertArrayEquals(wkb, geometry.toWkb());
+    assertArrayEquals(wkb, geometry.toWkb(ByteOrder.LITTLE_ENDIAN));
   }
 
   @Test
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 aa1b4735cf62..c3a806d897dd 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
@@ -20,6 +20,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.apache.spark.unsafe.types.UTF8String;
 import org.junit.jupiter.api.Test;
 
 import java.nio.ByteBuffer;
@@ -38,6 +39,8 @@ class STUtilsSuite {
   private final byte[] testWkb = new byte[] {0x01, 0x01, 0x00, 0x00, 0x00, 
0x00, 0x00, 0x00,
     0x00, 0x00, 0x00, (byte)0xF0, 0x3F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
0x00, 0x40};
 
+  private final UTF8String ENDIANNESS_NDR = UTF8String.fromString("NDR");
+
   // A sample Geography byte array for testing purposes, representing a 
POINT(1 2) with SRID 4326.
   private final int testGeographySrid = 4326;
   private final byte[] testGeographyBytes;
@@ -111,7 +114,7 @@ class STUtilsSuite {
   @Test
   void testStAsBinaryGeography() {
     GeographyVal geographyVal = GeographyVal.fromBytes(testGeographyBytes);
-    byte[] geographyWkb = STUtils.stAsBinary(geographyVal);
+    byte[] geographyWkb = STUtils.stAsBinary(geographyVal, ENDIANNESS_NDR);
     assertNotNull(geographyWkb);
     assertArrayEquals(testWkb, geographyWkb);
   }
@@ -119,7 +122,7 @@ class STUtilsSuite {
   @Test
   void testStAsBinaryGeometry() {
     GeometryVal geometryVal = GeometryVal.fromBytes(testGeometryBytes);
-    byte[] geometryWkb = STUtils.stAsBinary(geometryVal);
+    byte[] geometryWkb = STUtils.stAsBinary(geometryVal, ENDIANNESS_NDR);
     assertNotNull(geometryWkb);
     assertArrayEquals(testWkb, geometryWkb);
   }
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 b195f7615687..c56db6c9b7e3 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
@@ -537,9 +537,9 @@
 | org.apache.spark.sql.catalyst.expressions.aggregate.VariancePop | var_pop | 
SELECT var_pop(col) FROM VALUES (1), (2), (3) AS tab(col) | 
struct<var_pop(col):double> |
 | org.apache.spark.sql.catalyst.expressions.aggregate.VarianceSamp | var_samp 
| SELECT var_samp(col) FROM VALUES (1), (2), (3) AS tab(col) | 
struct<var_samp(col):double> |
 | org.apache.spark.sql.catalyst.expressions.aggregate.VarianceSamp | variance 
| SELECT variance(col) FROM VALUES (1), (2), (3) AS tab(col) | 
struct<variance(col):double> |
-| 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',
 0))):string> |
+| 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'),
 NDR)):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'),
 NDR)):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',
 0), NDR)):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.IsValidVariant | 
is_valid_variant | SELECT is_valid_variant(parse_json('null')) | 
struct<is_valid_variant(parse_json(null)):boolean> |
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 34969f43e1f7..dd30adde9843 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
@@ -224,7 +224,7 @@ org.apache.spark.sql.catalyst.ExtendedAnalysisException
 -- !query
 SELECT 
hex(ST_AsBinary(CAST(ST_GeogFromWKB(X'0101000000000000000000f03f0000000000000040')
 AS GEOGRAPHY(ANY)))) AS result
 -- !query analysis
-Project 
[hex(st_asbinary(cast(st_geogfromwkb(0x0101000000000000000000F03F0000000000000040)
 as geography(any)))) AS result#x]
+Project 
[hex(st_asbinary(cast(st_geogfromwkb(0x0101000000000000000000F03F0000000000000040)
 as geography(any)), NDR)) AS result#x]
 +- OneRowRelation
 
 
@@ -253,7 +253,7 @@ org.apache.spark.sql.catalyst.ExtendedAnalysisException
 -- !query
 SELECT 
hex(ST_AsBinary(CAST(ST_GeogFromWKB(X'0101000000000000000000f03f0000000000000040')
 AS GEOMETRY(4326)))) AS result
 -- !query analysis
-Project 
[hex(st_asbinary(cast(st_geogfromwkb(0x0101000000000000000000F03F0000000000000040)
 as geometry(4326)))) AS result#x]
+Project 
[hex(st_asbinary(cast(st_geogfromwkb(0x0101000000000000000000F03F0000000000000040)
 as geometry(4326)), NDR)) AS result#x]
 +- OneRowRelation
 
 
@@ -282,7 +282,7 @@ org.apache.spark.sql.catalyst.ExtendedAnalysisException
 -- !query
 SELECT 
hex(ST_AsBinary(CAST(ST_GeomFromWKB(X'0101000000000000000000f03f0000000000000040')
 AS GEOMETRY(ANY)))) AS result
 -- !query analysis
-Project 
[hex(st_asbinary(cast(st_geomfromwkb(0x0101000000000000000000F03F0000000000000040,
 0) as geometry(any)))) AS result#x]
+Project 
[hex(st_asbinary(cast(st_geomfromwkb(0x0101000000000000000000F03F0000000000000040,
 0) as geometry(any)), NDR)) AS result#x]
 +- OneRowRelation
 
 
@@ -311,7 +311,7 @@ org.apache.spark.sql.catalyst.ExtendedAnalysisException
 -- !query
 SELECT 
hex(ST_AsBinary(CAST(ST_GeomFromWKB(X'0101000000000000000000f03f0000000000000040',
 4326) AS GEOGRAPHY(4326)))) AS result
 -- !query analysis
-Project 
[hex(st_asbinary(cast(st_geomfromwkb(0x0101000000000000000000F03F0000000000000040,
 4326) as geography(4326)))) AS result#x]
+Project 
[hex(st_asbinary(cast(st_geomfromwkb(0x0101000000000000000000F03F0000000000000040,
 4326) as geography(4326)), NDR)) AS result#x]
 +- OneRowRelation
 
 
@@ -491,28 +491,28 @@ Project [typeof(if (isnotnull(wkb#x)) 
cast(st_geomfromwkb(wkb#x, 0) as geometry(
 -- !query
 SELECT 
hex(ST_AsBinary(ST_GeogFromWKB(X'0101000000000000000000f03f0000000000000040'))) 
AS result
 -- !query analysis
-Project 
[hex(st_asbinary(st_geogfromwkb(0x0101000000000000000000F03F0000000000000040))) 
AS result#x]
+Project 
[hex(st_asbinary(st_geogfromwkb(0x0101000000000000000000F03F0000000000000040), 
NDR)) AS result#x]
 +- OneRowRelation
 
 
 -- !query
 SELECT 
hex(ST_AsBinary(ST_GeomFromWKB(X'0101000000000000000000f03f0000000000000040'))) 
AS result
 -- !query analysis
-Project 
[hex(st_asbinary(st_geomfromwkb(0x0101000000000000000000F03F0000000000000040, 
0))) AS result#x]
+Project 
[hex(st_asbinary(st_geomfromwkb(0x0101000000000000000000F03F0000000000000040, 
0), NDR)) AS result#x]
 +- OneRowRelation
 
 
 -- !query
 SELECT ST_AsBinary(ST_GeogFromWKB(NULL))
 -- !query analysis
-Project [st_asbinary(st_geogfromwkb(cast(null as binary))) AS 
st_asbinary(st_geogfromwkb(NULL))#x]
+Project [st_asbinary(st_geogfromwkb(cast(null as binary)), NDR) AS 
st_asbinary(st_geogfromwkb(NULL), NDR)#x]
 +- OneRowRelation
 
 
 -- !query
 SELECT 
hex(ST_AsBinary(ST_GeogFromWKB(X'0101000000000000000000F03F0000000000000040')))
 -- !query analysis
-Project 
[hex(st_asbinary(st_geogfromwkb(0x0101000000000000000000F03F0000000000000040))) 
AS 
hex(st_asbinary(st_geogfromwkb(X'0101000000000000000000F03F0000000000000040')))#x]
+Project 
[hex(st_asbinary(st_geogfromwkb(0x0101000000000000000000F03F0000000000000040), 
NDR)) AS 
hex(st_asbinary(st_geogfromwkb(X'0101000000000000000000F03F0000000000000040'), 
NDR))#x]
 +- OneRowRelation
 
 
@@ -536,7 +536,7 @@ Aggregate [count(1) AS count(1)#xL]
 SELECT COUNT(*) FROM geodata WHERE ST_AsBinary(ST_GeogFromWKB(wkb)) <> wkb
 -- !query analysis
 Aggregate [count(1) AS count(1)#xL]
-+- Filter NOT (st_asbinary(st_geogfromwkb(wkb#x)) = wkb#x)
++- Filter NOT (st_asbinary(st_geogfromwkb(wkb#x), NDR) = wkb#x)
    +- SubqueryAlias spark_catalog.default.geodata
       +- Relation spark_catalog.default.geodata[wkb#x] parquet
 
@@ -544,35 +544,35 @@ Aggregate [count(1) AS count(1)#xL]
 -- !query
 SELECT ST_AsBinary(ST_GeomFromWKB(NULL))
 -- !query analysis
-Project [st_asbinary(st_geomfromwkb(cast(null as binary), 0)) AS 
st_asbinary(st_geomfromwkb(NULL, 0))#x]
+Project [st_asbinary(st_geomfromwkb(cast(null as binary), 0), NDR) AS 
st_asbinary(st_geomfromwkb(NULL, 0), NDR)#x]
 +- OneRowRelation
 
 
 -- !query
 SELECT 
hex(ST_AsBinary(ST_GeomFromWKB(X'0101000000000000000000F03F0000000000000040')))
 -- !query analysis
-Project 
[hex(st_asbinary(st_geomfromwkb(0x0101000000000000000000F03F0000000000000040, 
0))) AS 
hex(st_asbinary(st_geomfromwkb(X'0101000000000000000000F03F0000000000000040', 
0)))#x]
+Project 
[hex(st_asbinary(st_geomfromwkb(0x0101000000000000000000F03F0000000000000040, 
0), NDR)) AS 
hex(st_asbinary(st_geomfromwkb(X'0101000000000000000000F03F0000000000000040', 
0), NDR))#x]
 +- OneRowRelation
 
 
 -- !query
 SELECT 
hex(ST_AsBinary(ST_GeomFromWKB(X'0101000000000000000000F03F0000000000000040', 
0)))
 -- !query analysis
-Project 
[hex(st_asbinary(st_geomfromwkb(0x0101000000000000000000F03F0000000000000040, 
0))) AS 
hex(st_asbinary(st_geomfromwkb(X'0101000000000000000000F03F0000000000000040', 
0)))#x]
+Project 
[hex(st_asbinary(st_geomfromwkb(0x0101000000000000000000F03F0000000000000040, 
0), NDR)) AS 
hex(st_asbinary(st_geomfromwkb(X'0101000000000000000000F03F0000000000000040', 
0), NDR))#x]
 +- OneRowRelation
 
 
 -- !query
 SELECT 
hex(ST_AsBinary(ST_GeomFromWKB(X'0101000000000000000000F03F0000000000000040', 
3857)))
 -- !query analysis
-Project 
[hex(st_asbinary(st_geomfromwkb(0x0101000000000000000000F03F0000000000000040, 
3857))) AS 
hex(st_asbinary(st_geomfromwkb(X'0101000000000000000000F03F0000000000000040', 
3857)))#x]
+Project 
[hex(st_asbinary(st_geomfromwkb(0x0101000000000000000000F03F0000000000000040, 
3857), NDR)) AS 
hex(st_asbinary(st_geomfromwkb(X'0101000000000000000000F03F0000000000000040', 
3857), NDR))#x]
 +- OneRowRelation
 
 
 -- !query
 SELECT 
hex(ST_AsBinary(ST_GeomFromWKB(X'0101000000000000000000F03F0000000000000040', 
4326)))
 -- !query analysis
-Project 
[hex(st_asbinary(st_geomfromwkb(0x0101000000000000000000F03F0000000000000040, 
4326))) AS 
hex(st_asbinary(st_geomfromwkb(X'0101000000000000000000F03F0000000000000040', 
4326)))#x]
+Project 
[hex(st_asbinary(st_geomfromwkb(0x0101000000000000000000F03F0000000000000040, 
4326), NDR)) AS 
hex(st_asbinary(st_geomfromwkb(X'0101000000000000000000F03F0000000000000040', 
4326), NDR))#x]
 +- OneRowRelation
 
 
@@ -638,7 +638,7 @@ Aggregate [count(1) AS count(1)#xL]
 SELECT COUNT(*) FROM geodata WHERE ST_AsBinary(ST_GeomFromWKB(wkb)) <> wkb
 -- !query analysis
 Aggregate [count(1) AS count(1)#xL]
-+- Filter NOT (st_asbinary(st_geomfromwkb(wkb#x, 0)) = wkb#x)
++- Filter NOT (st_asbinary(st_geomfromwkb(wkb#x, 0), NDR) = wkb#x)
    +- SubqueryAlias spark_catalog.default.geodata
       +- Relation spark_catalog.default.geodata[wkb#x] parquet
 
@@ -647,7 +647,7 @@ Aggregate [count(1) AS count(1)#xL]
 SELECT COUNT(*) FROM geodata WHERE ST_AsBinary(ST_GeomFromWKB(wkb, 4326)) <> 
wkb
 -- !query analysis
 Aggregate [count(1) AS count(1)#xL]
-+- Filter NOT (st_asbinary(st_geomfromwkb(wkb#x, 4326)) = wkb#x)
++- Filter NOT (st_asbinary(st_geomfromwkb(wkb#x, 4326), NDR) = wkb#x)
    +- SubqueryAlias spark_catalog.default.geodata
       +- Relation spark_catalog.default.geodata[wkb#x] parquet
 
@@ -665,6 +665,157 @@ org.apache.spark.SparkIllegalArgumentException
 }
 
 
+-- !query
+SELECT ST_AsBinary(NULL)
+-- !query analysis
+Project [st_asbinary(cast(null as geography(any)), NDR) AS st_asbinary(NULL, 
NDR)#x]
++- OneRowRelation
+
+
+-- !query
+SELECT 
hex(ST_AsBinary(ST_GeogFromWKB(X'0101000000000000000000F03F0000000000000040')))
+-- !query analysis
+Project 
[hex(st_asbinary(st_geogfromwkb(0x0101000000000000000000F03F0000000000000040), 
NDR)) AS 
hex(st_asbinary(st_geogfromwkb(X'0101000000000000000000F03F0000000000000040'), 
NDR))#x]
++- OneRowRelation
+
+
+-- !query
+SELECT 
hex(ST_AsBinary(ST_GeogFromWKB(X'00000000013FF00000000000004000000000000000'), 
'NDR'))
+-- !query analysis
+Project 
[hex(st_asbinary(st_geogfromwkb(0x00000000013FF00000000000004000000000000000), 
NDR)) AS 
hex(st_asbinary(st_geogfromwkb(X'00000000013FF00000000000004000000000000000'), 
NDR))#x]
++- OneRowRelation
+
+
+-- !query
+SELECT 
hex(ST_AsBinary(ST_GeogFromWKB(X'0101000000000000000000F03F0000000000000040'), 
'XDR'))
+-- !query analysis
+Project 
[hex(st_asbinary(st_geogfromwkb(0x0101000000000000000000F03F0000000000000040), 
XDR)) AS 
hex(st_asbinary(st_geogfromwkb(X'0101000000000000000000F03F0000000000000040'), 
XDR))#x]
++- OneRowRelation
+
+
+-- !query
+SELECT 
hex(ST_AsBinary(ST_GeomFromWKB(X'0101000000000000000000F03F0000000000000040')))
+-- !query analysis
+Project 
[hex(st_asbinary(st_geomfromwkb(0x0101000000000000000000F03F0000000000000040, 
0), NDR)) AS 
hex(st_asbinary(st_geomfromwkb(X'0101000000000000000000F03F0000000000000040', 
0), NDR))#x]
++- OneRowRelation
+
+
+-- !query
+SELECT 
hex(ST_AsBinary(ST_GeomFromWKB(X'00000000013FF00000000000004000000000000000'), 
'NDR'))
+-- !query analysis
+Project 
[hex(st_asbinary(st_geomfromwkb(0x00000000013FF00000000000004000000000000000, 
0), NDR)) AS 
hex(st_asbinary(st_geomfromwkb(X'00000000013FF00000000000004000000000000000', 
0), NDR))#x]
++- OneRowRelation
+
+
+-- !query
+SELECT 
hex(ST_AsBinary(ST_GeomFromWKB(X'0101000000000000000000F03F0000000000000040'), 
'XDR'))
+-- !query analysis
+Project 
[hex(st_asbinary(st_geomfromwkb(0x0101000000000000000000F03F0000000000000040, 
0), XDR)) AS 
hex(st_asbinary(st_geomfromwkb(X'0101000000000000000000F03F0000000000000040', 
0), XDR))#x]
++- OneRowRelation
+
+
+-- !query
+SELECT 
ST_AsBinary(ST_GeogFromWKB(X'0101000000000000000000F03F0000000000000040'), '')
+-- !query analysis
+Project 
[st_asbinary(st_geogfromwkb(0x0101000000000000000000F03F0000000000000040), ) AS 
st_asbinary(st_geogfromwkb(X'0101000000000000000000F03F0000000000000040'), )#x]
++- OneRowRelation
+
+
+-- !query
+SELECT 
ST_AsBinary(ST_GeogFromWKB(X'0101000000000000000000F03F0000000000000040'), 
'ABC')
+-- !query analysis
+Project 
[st_asbinary(st_geogfromwkb(0x0101000000000000000000F03F0000000000000040), ABC) 
AS st_asbinary(st_geogfromwkb(X'0101000000000000000000F03F0000000000000040'), 
ABC)#x]
++- OneRowRelation
+
+
+-- !query
+SELECT 
ST_AsBinary(ST_GeogFromWKB(X'0101000000000000000000F03F0000000000000040'), 
'big-endian')
+-- !query analysis
+Project 
[st_asbinary(st_geogfromwkb(0x0101000000000000000000F03F0000000000000040), 
big-endian) AS 
st_asbinary(st_geogfromwkb(X'0101000000000000000000F03F0000000000000040'), 
big-endian)#x]
++- OneRowRelation
+
+
+-- !query
+SELECT COUNT(*) FROM geodata WHERE ST_AsBinary(ST_GeogFromWKB(wkb)) <> wkb
+-- !query analysis
+Aggregate [count(1) AS count(1)#xL]
++- Filter NOT (st_asbinary(st_geogfromwkb(wkb#x), NDR) = wkb#x)
+   +- SubqueryAlias spark_catalog.default.geodata
+      +- Relation spark_catalog.default.geodata[wkb#x] parquet
+
+
+-- !query
+SELECT COUNT(*) FROM geodata WHERE ST_AsBinary(ST_GeogFromWKB(wkb), 'NDR') <> 
wkb
+-- !query analysis
+Aggregate [count(1) AS count(1)#xL]
++- Filter NOT (st_asbinary(st_geogfromwkb(wkb#x), NDR) = wkb#x)
+   +- SubqueryAlias spark_catalog.default.geodata
+      +- Relation spark_catalog.default.geodata[wkb#x] parquet
+
+
+-- !query
+SELECT COUNT(*) FROM geodata WHERE ST_AsBinary(ST_GeogFromWKB(wkb), 'XDR') = 
wkb
+-- !query analysis
+Aggregate [count(1) AS count(1)#xL]
++- Filter (st_asbinary(st_geogfromwkb(wkb#x), XDR) = wkb#x)
+   +- SubqueryAlias spark_catalog.default.geodata
+      +- Relation spark_catalog.default.geodata[wkb#x] parquet
+
+
+-- !query
+SELECT COUNT(*) FROM geodata WHERE ST_AsBinary(ST_GeomFromWKB(wkb)) <> wkb
+-- !query analysis
+Aggregate [count(1) AS count(1)#xL]
++- Filter NOT (st_asbinary(st_geomfromwkb(wkb#x, 0), NDR) = wkb#x)
+   +- SubqueryAlias spark_catalog.default.geodata
+      +- Relation spark_catalog.default.geodata[wkb#x] parquet
+
+
+-- !query
+SELECT COUNT(*) FROM geodata WHERE ST_AsBinary(ST_GeomFromWKB(wkb), 'NDR') <> 
wkb
+-- !query analysis
+Aggregate [count(1) AS count(1)#xL]
++- Filter NOT (st_asbinary(st_geomfromwkb(wkb#x, 0), NDR) = wkb#x)
+   +- SubqueryAlias spark_catalog.default.geodata
+      +- Relation spark_catalog.default.geodata[wkb#x] parquet
+
+
+-- !query
+SELECT COUNT(*) FROM geodata WHERE ST_AsBinary(ST_GeomFromWKB(wkb), 'XDR') = 
wkb
+-- !query analysis
+Aggregate [count(1) AS count(1)#xL]
++- Filter (st_asbinary(st_geomfromwkb(wkb#x, 0), XDR) = wkb#x)
+   +- SubqueryAlias spark_catalog.default.geodata
+      +- Relation spark_catalog.default.geodata[wkb#x] parquet
+
+
+-- !query
+SELECT COUNT(*) FROM geodata WHERE ST_AsBinary(ST_GeogFromWKB(wkb), '') IS NOT 
NULL
+-- !query analysis
+Aggregate [count(1) AS count(1)#xL]
++- Filter isnotnull(st_asbinary(st_geogfromwkb(wkb#x), ))
+   +- SubqueryAlias spark_catalog.default.geodata
+      +- Relation spark_catalog.default.geodata[wkb#x] parquet
+
+
+-- !query
+SELECT COUNT(*) FROM geodata WHERE ST_AsBinary(ST_GeogFromWKB(wkb), 'ABC') IS 
NOT NULL
+-- !query analysis
+Aggregate [count(1) AS count(1)#xL]
++- Filter isnotnull(st_asbinary(st_geogfromwkb(wkb#x), ABC))
+   +- SubqueryAlias spark_catalog.default.geodata
+      +- Relation spark_catalog.default.geodata[wkb#x] parquet
+
+
+-- !query
+SELECT COUNT(*) FROM geodata WHERE ST_AsBinary(ST_GeogFromWKB(wkb), 
'big-endian') IS NOT NULL
+-- !query analysis
+Aggregate [count(1) AS count(1)#xL]
++- Filter isnotnull(st_asbinary(st_geogfromwkb(wkb#x), big-endian))
+   +- SubqueryAlias spark_catalog.default.geodata
+      +- Relation spark_catalog.default.geodata[wkb#x] parquet
+
+
 -- !query
 SELECT ST_Srid(NULL)
 -- !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 0db835bc7e85..62b9a1b8f614 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
@@ -137,6 +137,33 @@ SELECT COUNT(*) FROM geodata WHERE 
ST_AsBinary(ST_GeomFromWKB(wkb, 4326)) <> wkb
 -- Error handling: invalid SRID.
 SELECT COUNT(*) FROM geodata WHERE ST_GeomFromWKB(wkb, 1);
 
+---- ST_AsBinary
+
+-- 1. Driver-level queries.
+SELECT ST_AsBinary(NULL);
+SELECT 
hex(ST_AsBinary(ST_GeogFromWKB(X'0101000000000000000000F03F0000000000000040')));
+SELECT 
hex(ST_AsBinary(ST_GeogFromWKB(X'00000000013FF00000000000004000000000000000'), 
'NDR'));
+SELECT 
hex(ST_AsBinary(ST_GeogFromWKB(X'0101000000000000000000F03F0000000000000040'), 
'XDR'));
+SELECT 
hex(ST_AsBinary(ST_GeomFromWKB(X'0101000000000000000000F03F0000000000000040')));
+SELECT 
hex(ST_AsBinary(ST_GeomFromWKB(X'00000000013FF00000000000004000000000000000'), 
'NDR'));
+SELECT 
hex(ST_AsBinary(ST_GeomFromWKB(X'0101000000000000000000F03F0000000000000040'), 
'XDR'));
+-- Error handling: invalid endianness.
+SELECT 
ST_AsBinary(ST_GeogFromWKB(X'0101000000000000000000F03F0000000000000040'), '');
+SELECT 
ST_AsBinary(ST_GeogFromWKB(X'0101000000000000000000F03F0000000000000040'), 
'ABC');
+SELECT 
ST_AsBinary(ST_GeogFromWKB(X'0101000000000000000000F03F0000000000000040'), 
'big-endian');
+
+-- 2. Table-level queries.
+SELECT COUNT(*) FROM geodata WHERE ST_AsBinary(ST_GeogFromWKB(wkb)) <> wkb;
+SELECT COUNT(*) FROM geodata WHERE ST_AsBinary(ST_GeogFromWKB(wkb), 'NDR') <> 
wkb;
+SELECT COUNT(*) FROM geodata WHERE ST_AsBinary(ST_GeogFromWKB(wkb), 'XDR') = 
wkb;
+SELECT COUNT(*) FROM geodata WHERE ST_AsBinary(ST_GeomFromWKB(wkb)) <> wkb;
+SELECT COUNT(*) FROM geodata WHERE ST_AsBinary(ST_GeomFromWKB(wkb), 'NDR') <> 
wkb;
+SELECT COUNT(*) FROM geodata WHERE ST_AsBinary(ST_GeomFromWKB(wkb), 'XDR') = 
wkb;
+-- Error handling: invalid endianness.
+SELECT COUNT(*) FROM geodata WHERE ST_AsBinary(ST_GeogFromWKB(wkb), '') IS NOT 
NULL;
+SELECT COUNT(*) FROM geodata WHERE ST_AsBinary(ST_GeogFromWKB(wkb), 'ABC') IS 
NOT NULL;
+SELECT COUNT(*) FROM geodata WHERE ST_AsBinary(ST_GeogFromWKB(wkb), 
'big-endian') IS NOT NULL;
+
 ------ ST accessor expressions
 
 ---- ST_Srid
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 11ca99bc2304..e9cc3242225a 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
@@ -574,7 +574,7 @@ struct<result:string>
 -- !query
 SELECT ST_AsBinary(ST_GeogFromWKB(NULL))
 -- !query schema
-struct<st_asbinary(st_geogfromwkb(NULL)):binary>
+struct<st_asbinary(st_geogfromwkb(NULL), NDR):binary>
 -- !query output
 NULL
 
@@ -582,7 +582,7 @@ NULL
 -- !query
 SELECT 
hex(ST_AsBinary(ST_GeogFromWKB(X'0101000000000000000000F03F0000000000000040')))
 -- !query schema
-struct<hex(st_asbinary(st_geogfromwkb(X'0101000000000000000000F03F0000000000000040'))):string>
+struct<hex(st_asbinary(st_geogfromwkb(X'0101000000000000000000F03F0000000000000040'),
 NDR)):string>
 -- !query output
 0101000000000000000000F03F0000000000000040
 
@@ -622,7 +622,7 @@ struct<count(1):bigint>
 -- !query
 SELECT ST_AsBinary(ST_GeomFromWKB(NULL))
 -- !query schema
-struct<st_asbinary(st_geomfromwkb(NULL, 0)):binary>
+struct<st_asbinary(st_geomfromwkb(NULL, 0), NDR):binary>
 -- !query output
 NULL
 
@@ -630,7 +630,7 @@ NULL
 -- !query
 SELECT 
hex(ST_AsBinary(ST_GeomFromWKB(X'0101000000000000000000F03F0000000000000040')))
 -- !query schema
-struct<hex(st_asbinary(st_geomfromwkb(X'0101000000000000000000F03F0000000000000040',
 0))):string>
+struct<hex(st_asbinary(st_geomfromwkb(X'0101000000000000000000F03F0000000000000040',
 0), NDR)):string>
 -- !query output
 0101000000000000000000F03F0000000000000040
 
@@ -638,7 +638,7 @@ 
struct<hex(st_asbinary(st_geomfromwkb(X'0101000000000000000000F03F00000000000000
 -- !query
 SELECT 
hex(ST_AsBinary(ST_GeomFromWKB(X'0101000000000000000000F03F0000000000000040', 
0)))
 -- !query schema
-struct<hex(st_asbinary(st_geomfromwkb(X'0101000000000000000000F03F0000000000000040',
 0))):string>
+struct<hex(st_asbinary(st_geomfromwkb(X'0101000000000000000000F03F0000000000000040',
 0), NDR)):string>
 -- !query output
 0101000000000000000000F03F0000000000000040
 
@@ -646,7 +646,7 @@ 
struct<hex(st_asbinary(st_geomfromwkb(X'0101000000000000000000F03F00000000000000
 -- !query
 SELECT 
hex(ST_AsBinary(ST_GeomFromWKB(X'0101000000000000000000F03F0000000000000040', 
3857)))
 -- !query schema
-struct<hex(st_asbinary(st_geomfromwkb(X'0101000000000000000000F03F0000000000000040',
 3857))):string>
+struct<hex(st_asbinary(st_geomfromwkb(X'0101000000000000000000F03F0000000000000040',
 3857), NDR)):string>
 -- !query output
 0101000000000000000000F03F0000000000000040
 
@@ -654,7 +654,7 @@ 
struct<hex(st_asbinary(st_geomfromwkb(X'0101000000000000000000F03F00000000000000
 -- !query
 SELECT 
hex(ST_AsBinary(ST_GeomFromWKB(X'0101000000000000000000F03F0000000000000040', 
4326)))
 -- !query schema
-struct<hex(st_asbinary(st_geomfromwkb(X'0101000000000000000000F03F0000000000000040',
 4326))):string>
+struct<hex(st_asbinary(st_geomfromwkb(X'0101000000000000000000F03F0000000000000040',
 4326), NDR)):string>
 -- !query output
 0101000000000000000000F03F0000000000000040
 
@@ -768,6 +768,200 @@ org.apache.spark.SparkIllegalArgumentException
 }
 
 
+-- !query
+SELECT ST_AsBinary(NULL)
+-- !query schema
+struct<st_asbinary(NULL, NDR):binary>
+-- !query output
+NULL
+
+
+-- !query
+SELECT 
hex(ST_AsBinary(ST_GeogFromWKB(X'0101000000000000000000F03F0000000000000040')))
+-- !query schema
+struct<hex(st_asbinary(st_geogfromwkb(X'0101000000000000000000F03F0000000000000040'),
 NDR)):string>
+-- !query output
+0101000000000000000000F03F0000000000000040
+
+
+-- !query
+SELECT 
hex(ST_AsBinary(ST_GeogFromWKB(X'00000000013FF00000000000004000000000000000'), 
'NDR'))
+-- !query schema
+struct<hex(st_asbinary(st_geogfromwkb(X'00000000013FF00000000000004000000000000000'),
 NDR)):string>
+-- !query output
+0101000000000000000000F03F0000000000000040
+
+
+-- !query
+SELECT 
hex(ST_AsBinary(ST_GeogFromWKB(X'0101000000000000000000F03F0000000000000040'), 
'XDR'))
+-- !query schema
+struct<hex(st_asbinary(st_geogfromwkb(X'0101000000000000000000F03F0000000000000040'),
 XDR)):string>
+-- !query output
+00000000013FF00000000000004000000000000000
+
+
+-- !query
+SELECT 
hex(ST_AsBinary(ST_GeomFromWKB(X'0101000000000000000000F03F0000000000000040')))
+-- !query schema
+struct<hex(st_asbinary(st_geomfromwkb(X'0101000000000000000000F03F0000000000000040',
 0), NDR)):string>
+-- !query output
+0101000000000000000000F03F0000000000000040
+
+
+-- !query
+SELECT 
hex(ST_AsBinary(ST_GeomFromWKB(X'00000000013FF00000000000004000000000000000'), 
'NDR'))
+-- !query schema
+struct<hex(st_asbinary(st_geomfromwkb(X'00000000013FF00000000000004000000000000000',
 0), NDR)):string>
+-- !query output
+0101000000000000000000F03F0000000000000040
+
+
+-- !query
+SELECT 
hex(ST_AsBinary(ST_GeomFromWKB(X'0101000000000000000000F03F0000000000000040'), 
'XDR'))
+-- !query schema
+struct<hex(st_asbinary(st_geomfromwkb(X'0101000000000000000000F03F0000000000000040',
 0), XDR)):string>
+-- !query output
+00000000013FF00000000000004000000000000000
+
+
+-- !query
+SELECT 
ST_AsBinary(ST_GeogFromWKB(X'0101000000000000000000F03F0000000000000040'), '')
+-- !query schema
+struct<>
+-- !query output
+org.apache.spark.SparkIllegalArgumentException
+{
+  "errorClass" : "ST_INVALID_ENDIANNESS_VALUE",
+  "sqlState" : "22023",
+  "messageParameters" : {
+    "endianness" : ""
+  }
+}
+
+
+-- !query
+SELECT 
ST_AsBinary(ST_GeogFromWKB(X'0101000000000000000000F03F0000000000000040'), 
'ABC')
+-- !query schema
+struct<>
+-- !query output
+org.apache.spark.SparkIllegalArgumentException
+{
+  "errorClass" : "ST_INVALID_ENDIANNESS_VALUE",
+  "sqlState" : "22023",
+  "messageParameters" : {
+    "endianness" : "ABC"
+  }
+}
+
+
+-- !query
+SELECT 
ST_AsBinary(ST_GeogFromWKB(X'0101000000000000000000F03F0000000000000040'), 
'big-endian')
+-- !query schema
+struct<>
+-- !query output
+org.apache.spark.SparkIllegalArgumentException
+{
+  "errorClass" : "ST_INVALID_ENDIANNESS_VALUE",
+  "sqlState" : "22023",
+  "messageParameters" : {
+    "endianness" : "big-endian"
+  }
+}
+
+
+-- !query
+SELECT COUNT(*) FROM geodata WHERE ST_AsBinary(ST_GeogFromWKB(wkb)) <> wkb
+-- !query schema
+struct<count(1):bigint>
+-- !query output
+0
+
+
+-- !query
+SELECT COUNT(*) FROM geodata WHERE ST_AsBinary(ST_GeogFromWKB(wkb), 'NDR') <> 
wkb
+-- !query schema
+struct<count(1):bigint>
+-- !query output
+0
+
+
+-- !query
+SELECT COUNT(*) FROM geodata WHERE ST_AsBinary(ST_GeogFromWKB(wkb), 'XDR') = 
wkb
+-- !query schema
+struct<count(1):bigint>
+-- !query output
+0
+
+
+-- !query
+SELECT COUNT(*) FROM geodata WHERE ST_AsBinary(ST_GeomFromWKB(wkb)) <> wkb
+-- !query schema
+struct<count(1):bigint>
+-- !query output
+0
+
+
+-- !query
+SELECT COUNT(*) FROM geodata WHERE ST_AsBinary(ST_GeomFromWKB(wkb), 'NDR') <> 
wkb
+-- !query schema
+struct<count(1):bigint>
+-- !query output
+0
+
+
+-- !query
+SELECT COUNT(*) FROM geodata WHERE ST_AsBinary(ST_GeomFromWKB(wkb), 'XDR') = 
wkb
+-- !query schema
+struct<count(1):bigint>
+-- !query output
+0
+
+
+-- !query
+SELECT COUNT(*) FROM geodata WHERE ST_AsBinary(ST_GeogFromWKB(wkb), '') IS NOT 
NULL
+-- !query schema
+struct<>
+-- !query output
+org.apache.spark.SparkIllegalArgumentException
+{
+  "errorClass" : "ST_INVALID_ENDIANNESS_VALUE",
+  "sqlState" : "22023",
+  "messageParameters" : {
+    "endianness" : ""
+  }
+}
+
+
+-- !query
+SELECT COUNT(*) FROM geodata WHERE ST_AsBinary(ST_GeogFromWKB(wkb), 'ABC') IS 
NOT NULL
+-- !query schema
+struct<>
+-- !query output
+org.apache.spark.SparkIllegalArgumentException
+{
+  "errorClass" : "ST_INVALID_ENDIANNESS_VALUE",
+  "sqlState" : "22023",
+  "messageParameters" : {
+    "endianness" : "ABC"
+  }
+}
+
+
+-- !query
+SELECT COUNT(*) FROM geodata WHERE ST_AsBinary(ST_GeogFromWKB(wkb), 
'big-endian') IS NOT NULL
+-- !query schema
+struct<>
+-- !query output
+org.apache.spark.SparkIllegalArgumentException
+{
+  "errorClass" : "ST_INVALID_ENDIANNESS_VALUE",
+  "sqlState" : "22023",
+  "messageParameters" : {
+    "endianness" : "big-endian"
+  }
+}
+
+
 -- !query
 SELECT ST_Srid(NULL)
 -- !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 3406a7109de7..7deb30cf9e9c 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
@@ -106,11 +106,11 @@ class STExpressionsSuite
     // Construct the input GEOGRAPHY expression.
     val geogExpr = ST_GeogFromWKB(wkbLiteral)
     assert(geogExpr.dataType.sameType(defaultGeographyType))
-    checkEvaluation(ST_AsBinary(geogExpr), wkb)
+    checkEvaluation(new ST_AsBinary(geogExpr), wkb)
     // Cast the GEOGRAPHY with fixed SRID to GEOGRAPHY with mixed SRID.
     val castExpr = Cast(geogExpr, mixedSridGeographyType)
     assert(castExpr.dataType.sameType(mixedSridGeographyType))
-    checkEvaluation(ST_AsBinary(castExpr), wkb)
+    checkEvaluation(new ST_AsBinary(castExpr), wkb)
 
     // Construct the input GEOGRAPHY SQL query, using WKB literal.
     val geogQueryLit: String = s"ST_GeogFromWKB(X'$wkbString')"
@@ -146,11 +146,11 @@ class STExpressionsSuite
     // Construct the input GEOMETRY expression.
     val geomExpr = new ST_GeomFromWKB(wkbLiteral)
     assert(geomExpr.dataType.sameType(defaultGeometryType))
-    checkEvaluation(ST_AsBinary(geomExpr), wkb)
+    checkEvaluation(new ST_AsBinary(geomExpr), wkb)
     // Cast the GEOMETRY with fixed SRID to GEOMETRY with mixed SRID.
     val castExpr = Cast(geomExpr, mixedSridGeometryType)
     assert(castExpr.dataType.sameType(mixedSridGeometryType))
-    checkEvaluation(ST_AsBinary(castExpr), wkb)
+    checkEvaluation(new ST_AsBinary(castExpr), wkb)
 
     // Construct the input GEOMETRY SQL query, using WKB literal.
     val geomQueryLit: String = s"ST_GeomFromWKB(X'$wkbString')"
@@ -475,16 +475,42 @@ class STExpressionsSuite
 
   test("ST_AsBinary") {
     // Test data: WKB representation of POINT(1 2).
-    val wkb = 
Hex.unhex("0101000000000000000000F03F0000000000000040".getBytes())
-    val wkbLiteral = Literal.create(wkb, BinaryType)
+    val wkbNdr = 
Hex.unhex("0101000000000000000000F03F0000000000000040".getBytes())
+    val wkbXdr = 
Hex.unhex("00000000013FF00000000000004000000000000000".getBytes())
+    val wkbLiteral = Literal.create(wkbNdr, BinaryType)
+    val endiannessNdr = Literal.create("NDR")
+    val endiannessXdr = Literal.create("XDR")
     // ST_GeogFromWKB and ST_AsBinary.
     val geographyExpression = ST_GeogFromWKB(wkbLiteral)
     assert(geographyExpression.dataType.sameType(defaultGeographyType))
-    checkEvaluation(ST_AsBinary(geographyExpression), wkb)
+    checkEvaluation(new ST_AsBinary(geographyExpression), wkbNdr)
+    checkEvaluation(ST_AsBinary(geographyExpression, endiannessNdr), wkbNdr)
+    checkEvaluation(ST_AsBinary(geographyExpression, Literal.create("nDr")), 
wkbNdr)
+    checkEvaluation(ST_AsBinary(geographyExpression, endiannessXdr), wkbXdr)
     // ST_GeomFromWKB and ST_AsBinary.
     val geometryExpression = new ST_GeomFromWKB(wkbLiteral)
     assert(geometryExpression.dataType.sameType(defaultGeometryType))
-    checkEvaluation(ST_AsBinary(geometryExpression), wkb)
+    checkEvaluation(new ST_AsBinary(geometryExpression), wkbNdr)
+    checkEvaluation(ST_AsBinary(geometryExpression, endiannessNdr), wkbNdr)
+    checkEvaluation(ST_AsBinary(geometryExpression, endiannessXdr), wkbXdr)
+    checkEvaluation(ST_AsBinary(geometryExpression, Literal.create("XdR")), 
wkbXdr)
+    // Test NULL handling.
+    checkEvaluation(new ST_AsBinary(Literal.create(null, 
defaultGeographyType)), null)
+    checkEvaluation(ST_AsBinary(Literal.create(null, defaultGeographyType), 
endiannessNdr), null)
+    checkEvaluation(new ST_AsBinary(Literal.create(null, 
defaultGeometryType)), null)
+    checkEvaluation(ST_AsBinary(Literal.create(null, defaultGeometryType), 
endiannessXdr), null)
+    checkEvaluation(ST_AsBinary(geographyExpression, Literal.create(null, 
StringType)), null)
+    checkEvaluation(ST_AsBinary(geometryExpression, Literal.create(null, 
StringType)), null)
+    // Test invalid endianness.
+    Seq(geographyExpression, geometryExpression).foreach { expr =>
+      checkError(
+        exception = intercept[SparkIllegalArgumentException] {
+          ST_AsBinary(expr, Literal.create("ABC")).eval()
+        },
+        condition = "ST_INVALID_ENDIANNESS_VALUE",
+        parameters = Map("endianness" -> "ABC")
+      )
+    }
   }
 
   test("ST_GeogFromWKB - expressions") {
@@ -494,7 +520,7 @@ class STExpressionsSuite
     // ST_GeogFromWKB with default SRID.
     val geographyExpression = ST_GeogFromWKB(wkbLiteral)
     assert(geographyExpression.dataType.sameType(defaultGeographyType))
-    checkEvaluation(ST_AsBinary(geographyExpression), wkb)
+    checkEvaluation(new ST_AsBinary(geographyExpression), wkb)
     checkEvaluation(ST_Srid(geographyExpression), defaultGeographySrid)
     // ST_GeogFromWKB with NULL input.
     val nullLiteral = Literal.create(null, BinaryType)
@@ -523,11 +549,11 @@ class STExpressionsSuite
     // ST_GeomFromWKB with default SRID.
     val geometryExpressionNoSrid = new ST_GeomFromWKB(wkbLiteral)
     assert(geometryExpressionNoSrid.dataType.sameType(defaultGeometryType))
-    checkEvaluation(ST_AsBinary(geometryExpressionNoSrid), wkb)
+    checkEvaluation(new ST_AsBinary(geometryExpressionNoSrid), wkb)
     // ST_GeomFromWKB with valid SRID.
     val geometryExpressionValidSrid = ST_GeomFromWKB(wkbLiteral, 
validSridLiteral)
     
assert(geometryExpressionValidSrid.dataType.sameType(GeometryType(validSrid)))
-    checkEvaluation(ST_AsBinary(geometryExpressionValidSrid), wkb)
+    checkEvaluation(new ST_AsBinary(geometryExpressionValidSrid), wkb)
     // ST_GeomFromWKB with invalid SRID.
     val geometryExpressionInvalidSrid = ST_GeomFromWKB(wkbLiteral, 
invalidSridLiteral)
     checkError(
@@ -638,7 +664,7 @@ class STExpressionsSuite
     // ST_SetSrid on GEOGRAPHY expression.
     val geogLit = ST_SetSrid(geographyLiteral, sridLiteral)
     assert(geogLit.dataType.sameType(GeographyType(srid)))
-    checkEvaluation(ST_AsBinary(geogLit), wkb)
+    checkEvaluation(new ST_AsBinary(geogLit), wkb)
     val geogLitSrid = ST_Srid(geogLit)
     assert(geogLitSrid.dataType.sameType(IntegerType))
     checkEvaluation(geogLitSrid, srid)
@@ -662,7 +688,7 @@ class STExpressionsSuite
     // ST_SetSrid on GEOMETRY expression.
     val geomLit = ST_SetSrid(geometryLiteral, sridLiteral)
     assert(geomLit.dataType.sameType(GeometryType(srid)))
-    checkEvaluation(ST_AsBinary(geomLit), wkb)
+    checkEvaluation(new ST_AsBinary(geomLit), wkb)
     val geomLitSrid = ST_Srid(geomLit)
     assert(geomLitSrid.dataType.sameType(IntegerType))
     checkEvaluation(geomLitSrid, srid)
diff --git 
a/sql/core/src/test/scala/org/apache/spark/sql/STFunctionsSuite.scala 
b/sql/core/src/test/scala/org/apache/spark/sql/STFunctionsSuite.scala
index 6cb8894ae525..7cd0d84df8c2 100644
--- a/sql/core/src/test/scala/org/apache/spark/sql/STFunctionsSuite.scala
+++ b/sql/core/src/test/scala/org/apache/spark/sql/STFunctionsSuite.scala
@@ -30,18 +30,37 @@ class STFunctionsSuite extends SharedSparkSession {
 
   test("st_asbinary") {
     // Test data: Well-Known Binary (WKB) representations.
-    val df = Seq[(String)](
-      (
-        "0101000000000000000000f03f0000000000000040"
-      )).toDF("wkb")
+    val wkbNdr = "0101000000000000000000f03f0000000000000040"
+    val wkbXdr = "00000000013ff00000000000004000000000000000"
+    val df = Seq[(String, String, String, String)](
+        (wkbNdr, wkbXdr, "NDR", "XDR")
+      ).toDF("wkbNDR", "wkbXDR", "endNDR", "endXDR")
     // ST_GeogFromWKB/ST_GeomFromWKB and ST_AsBinary.
     checkAnswer(
       df.select(
-        lower(hex(st_asbinary(st_geogfromwkb(unhex($"wkb"))))).as("col0"),
-        lower(hex(st_asbinary(st_geomfromwkb(unhex($"wkb"))))).as("col1")),
+        lower(hex(st_asbinary(st_geogfromwkb(unhex($"wkbNDR"))))),
+        lower(hex(st_asbinary(st_geogfromwkb(unhex($"wkbNDR")), "NDR"))),
+        lower(hex(st_asbinary(st_geogfromwkb(unhex($"wkbNDR")), $"endNDR"))),
+        lower(hex(st_asbinary(st_geogfromwkb(unhex($"wkbNDR")), "XDR"))),
+        lower(hex(st_asbinary(st_geogfromwkb(unhex($"wkbNDR")), $"endXDR"))),
+        lower(hex(st_asbinary(st_geogfromwkb(unhex($"wkbXDR"))))),
+        lower(hex(st_asbinary(st_geogfromwkb(unhex($"wkbXDR")), "NDR"))),
+        lower(hex(st_asbinary(st_geogfromwkb(unhex($"wkbXDR")), $"endNDR"))),
+        lower(hex(st_asbinary(st_geogfromwkb(unhex($"wkbXDR")), "XDR"))),
+        lower(hex(st_asbinary(st_geogfromwkb(unhex($"wkbXDR")), $"endXDR"))),
+        lower(hex(st_asbinary(st_geomfromwkb(unhex($"wkbNDR"))))),
+        lower(hex(st_asbinary(st_geomfromwkb(unhex($"wkbNDR")), "NDR"))),
+        lower(hex(st_asbinary(st_geomfromwkb(unhex($"wkbNDR")), $"endNDR"))),
+        lower(hex(st_asbinary(st_geomfromwkb(unhex($"wkbNDR")), "XDR"))),
+        lower(hex(st_asbinary(st_geomfromwkb(unhex($"wkbNDR")), $"endXDR"))),
+        lower(hex(st_asbinary(st_geomfromwkb(unhex($"wkbXDR"))))),
+        lower(hex(st_asbinary(st_geomfromwkb(unhex($"wkbXDR")), "NDR"))),
+        lower(hex(st_asbinary(st_geomfromwkb(unhex($"wkbXDR")), $"endNDR"))),
+        lower(hex(st_asbinary(st_geomfromwkb(unhex($"wkbXDR")), "XDR"))),
+        lower(hex(st_asbinary(st_geomfromwkb(unhex($"wkbXDR")), $"endXDR")))),
       Row(
-        "0101000000000000000000f03f0000000000000040",
-        "0101000000000000000000f03f0000000000000040"))
+        wkbNdr, wkbNdr, wkbNdr, wkbXdr, wkbXdr, wkbNdr, wkbNdr, wkbNdr, 
wkbXdr, wkbXdr,
+        wkbNdr, wkbNdr, wkbNdr, wkbXdr, wkbXdr, wkbNdr, wkbNdr, wkbNdr, 
wkbXdr, wkbXdr))
   }
 
   test("st_geogfromwkb") {


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to