Skip to content
Open
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ public static boolean isSkippingEligibleDataType(DataType dataType) {
// be matched separately.
dataType instanceof StringType
// Geometry/geography types are eligible but need separate matching
// due to SRID (and algorithm) parameters
// due to CRS (and algorithm) parameters
|| dataType instanceof GeometryType
|| dataType instanceof GeographyType;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -467,31 +467,31 @@ private static DataType nameToType(String name) {
return new DecimalType(precision, scale);
}

// geometry has a special pattern with an SRID
// geometry has a special pattern with an CRS
Matcher geometryMatcher = GEOMETRY_PATTERN.matcher(name);
if (geometryMatcher.matches()) {
String srid = geometryMatcher.group(1);
return GeometryType.ofSRID(srid);
String crs = geometryMatcher.group(1);
return GeometryType.ofCRS(crs);
}

// geography has different patterns:
// 1. geography(<srid>, <algorithm>) - both specified
// 2. geography(<srid>) - SRID specified (contains colon)
// 1. geography(<crs>, <algorithm>) - both specified
// 2. geography(<crs>) - CRS specified (contains colon)
// 3. geography(<algorithm>) - algorithm specified (no colon)

// First check for both CRS and algorithm (contains comma)
Matcher geographyCrsAlgMatcher = GEOGRAPHY_CRS_ALG_PATTERN.matcher(name);
if (geographyCrsAlgMatcher.matches()) {
String srid = geographyCrsAlgMatcher.group(1);
String crs = geographyCrsAlgMatcher.group(1);
String algorithm = geographyCrsAlgMatcher.group(2);
return new GeographyType(srid, algorithm);
return new GeographyType(crs, algorithm);
}

// Check for CRS pattern (contains colon)
Matcher geographyCrsMatcher = GEOGRAPHY_CRS_PATTERN.matcher(name);
if (geographyCrsMatcher.matches()) {
String srid = geographyCrsMatcher.group(1);
return GeographyType.ofSRID(srid);
String crs = geographyCrsMatcher.group(1);
return GeographyType.ofCRS(crs);
}

// Check for algorithm pattern (no colon)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,59 +22,59 @@

/**
* The data type representing geography values. A Geography must have a fixed Spatial Reference
* System Identifier (SRID) that defines the coordinate system and an algorithm that determines how
* System Identifier (CRS) that defines the coordinate system and an algorithm that determines how
* geometric calculations are performed.
*
* <p>The SRID is specified as a string and the algorithm defines the calculation method. The engine
* is responsible for validating and interpreting the SRID and algorithm values.
* <p>The CRS is specified as a string and the algorithm defines the calculation method. The engine
* is responsible for validating and interpreting the CRS and algorithm values.
*
* @since 3.0.0
*/
@Evolving
public final class GeographyType extends DataType {
public static final String DEFAULT_SRID = "OGC:CRS84";
public static final String DEFAULT_CRS = "OGC:CRS84";
public static final String DEFAULT_ALGORITHM = "spherical";

public static final Set<String> VALID_ALGORITHMS =
Set.of("spherical", "vincenty", "thomas", "andoyer", "karney");

private final String srid;
private final String crs;
private final String algorithm;

/** Returns a GeographyType with the default SRID and algorithm. */
/** Returns a GeographyType with the default CRS and algorithm. */
public static GeographyType ofDefault() {
return new GeographyType(DEFAULT_SRID, DEFAULT_ALGORITHM);
return new GeographyType(DEFAULT_CRS, DEFAULT_ALGORITHM);
}

/**
* Returns a GeographyType with the specified SRID and default algorithm.
* Returns a GeographyType with the specified CRS and default algorithm.
*
* @param srid the Spatial Reference System Identifier (any non-null, non-empty string)
* @param crs the Spatial Reference System Identifier (any non-null, non-empty string)
*/
public static GeographyType ofSRID(String srid) {
return new GeographyType(srid, DEFAULT_ALGORITHM);
public static GeographyType ofCRS(String crs) {
return new GeographyType(crs, DEFAULT_ALGORITHM);
}

/**
* Returns a GeographyType with the default SRID and the specified algorithm.
* Returns a GeographyType with the default CRS and the specified algorithm.
*
* @param algorithm one of: spherical, vincenty, thomas, andoyer, karney
*/
public static GeographyType ofAlgorithm(String algorithm) {
return new GeographyType(DEFAULT_SRID, algorithm);
return new GeographyType(DEFAULT_CRS, algorithm);
}

/**
* Create a GeographyType with the specified SRID and algorithm.
* Create a GeographyType with the specified CRS and algorithm.
*
* @param srid the Spatial Reference System Identifier (any non-null, non-empty string)
* @param crs the Spatial Reference System Identifier (any non-null, non-empty string)
* @param algorithm the algorithm for geometric calculations (any non-null, non-empty string)
* @throws IllegalArgumentException if the SRID or algorithm is null or empty or algorithm is
* @throws IllegalArgumentException if the CRS or algorithm is null or empty or algorithm is
* invalid
*/
public GeographyType(String srid, String algorithm) {
if (srid == null || srid.isEmpty()) {
throw new IllegalArgumentException("SRID cannot be null or empty");
public GeographyType(String crs, String algorithm) {
if (crs == null || crs.isEmpty()) {
throw new IllegalArgumentException("CRS cannot be null or empty");
}
if (algorithm == null || algorithm.isEmpty()) {
throw new IllegalArgumentException("Algorithm cannot be null or empty");
Expand All @@ -84,17 +84,17 @@ public GeographyType(String srid, String algorithm) {
"Algorithm must be one of: spherical, vincenty, thomas, andoyer, karney, got: "
+ algorithm);
}
this.srid = srid;
this.crs = crs;
this.algorithm = algorithm;
}

/**
* Get the Spatial Reference System Identifier.
*
* @return the SRID string
* @return the CRS string
*/
public String getSRID() {
return srid;
public String getCRS() {
return crs;
}

/**
Expand All @@ -117,12 +117,12 @@ public boolean isNested() {
* @return the serialized string representation
*/
public String simpleString() {
return String.format("geography(%s, %s)", srid, algorithm);
return String.format("geography(%s, %s)", crs, algorithm);
}

@Override
public String toString() {
return String.format("Geography(srid=%s, algorithm=%s)", srid, algorithm);
return String.format("Geography(crs=%s, algorithm=%s)", crs, algorithm);
}

@Override
Expand All @@ -134,11 +134,11 @@ public boolean equals(Object o) {
return false;
}
GeographyType that = (GeographyType) o;
return srid.equals(that.srid) && algorithm.equals(that.algorithm);
return crs.equals(that.crs) && algorithm.equals(that.algorithm);
}

@Override
public int hashCode() {
return Objects.hash(srid, algorithm);
return Objects.hash(crs, algorithm);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -20,54 +20,54 @@

/**
* The data type representing geometry values. A Geometry must have a fixed Spatial Reference System
* Identifier (SRID) that defines the coordinate system.
* Identifier (CRS) that defines the coordinate system.
*
* <p>The SRID is specified as a string The engine is responsible for validating and interpreting
* the SRID value.
* <p>The CRS is specified as a string The engine is responsible for validating and interpreting
* the CRS value.
*
* @since 3.0.0
*/
@Evolving
public final class GeometryType extends DataType {

public static final String DEFAULT_SRID = "OGC:CRS84";
public static final String DEFAULT_CRS = "OGC:CRS84";

private final String srid;
private final String crs;

/** Returns a GeometryType with the default SRID. */
/** Returns a GeometryType with the default CRS. */
public static GeometryType ofDefault() {
return new GeometryType(DEFAULT_SRID);
return new GeometryType(DEFAULT_CRS);
}

/**
* Returns a GeometryType with the specified SRID.
* Returns a GeometryType with the specified CRS.
*
* @param srid the Spatial Reference System Identifier (any non-null, non-empty string)
* @param crs the Spatial Reference System Identifier (any non-null, non-empty string)
*/
public static GeometryType ofSRID(String srid) {
return new GeometryType(srid);
public static GeometryType ofCRS(String crs) {
return new GeometryType(crs);
}

/**
* Create a GeometryType with the specified SRID.
* Create a GeometryType with the specified CRS.
*
* @param srid the Spatial Reference System Identifier (any non-null, non-empty string)
* @throws IllegalArgumentException if the SRID is null or empty
* @param crs the Spatial Reference System Identifier (any non-null, non-empty string)
* @throws IllegalArgumentException if the CRS is null or empty
*/
public GeometryType(String srid) {
if (srid == null || srid.isEmpty()) {
throw new IllegalArgumentException("SRID cannot be null or empty");
public GeometryType(String crs) {
if (crs == null || crs.isEmpty()) {
throw new IllegalArgumentException("CRS cannot be null or empty");
}
this.srid = srid;
this.crs = crs;
}

/**
* Get the Spatial Reference System Identifier.
*
* @return the SRID string
* @return the CRS string
*/
public String getSRID() {
return srid;
public String getCRS() {
return crs;
}

@Override
Expand All @@ -81,12 +81,12 @@ public boolean isNested() {
* @return the serialized string representation
*/
public String simpleString() {
return String.format("geometry(%s)", srid);
return String.format("geometry(%s)", crs);
}

@Override
public String toString() {
return String.format("Geometry(srid=%s)", srid);
return String.format("Geometry(crs=%s)", crs);
}

@Override
Expand All @@ -98,11 +98,11 @@ public boolean equals(Object o) {
return false;
}
GeometryType that = (GeometryType) o;
return srid.equals(that.srid);
return crs.equals(that.crs);
}

@Override
public int hashCode() {
return Objects.hash(srid);
return Objects.hash(crs);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@ class DataTypeJsonSerDeSuite extends AnyFunSuite {
("\"decimal(10, 5)\"", new DecimalType(10, 5)),
("\"variant\"", VariantType.VARIANT),
("\"geometry\"", GeometryType.ofDefault()),
("\"geometry(EPSG:0)\"", GeometryType.ofSRID("EPSG:0")),
("\"geometry(EPSG:0)\"", GeometryType.ofCRS("EPSG:0")),
("\"geography\"", GeographyType.ofDefault()),
("\"geography(EPSG:4326)\"", new GeographyType("EPSG:4326", "spherical")),
("\"geography(vincenty)\"", new GeographyType("OGC:CRS84", "vincenty")),
Expand All @@ -96,39 +96,39 @@ class DataTypeJsonSerDeSuite extends AnyFunSuite {
"decimal(1) is not a supported delta data type")
}

test("deserialize: geometry with default SRID") {
// Parsing "geometry" should use default SRID (OGC:CRS84)
test("deserialize: geometry with default CRS") {
// Parsing "geometry" should use default CRS (OGC:CRS84)
assert(parse("\"geometry\"") === GeometryType.ofDefault())
// But serialization always writes full form
assert(serialize(GeometryType.ofDefault()) === "\"geometry(OGC:CRS84)\"")
}

test("serialize/deserialize: geometry with various SRID formats") {
// Kernel accepts any SRID format; engine validates compatibility
testRoundTrip("\"geometry(OGC:CRS84)\"", GeometryType.ofSRID("OGC:CRS84"))
testRoundTrip("\"geometry(EPSG:4326)\"", GeometryType.ofSRID("EPSG:4326"))
testRoundTrip("\"geometry(EPSG:0)\"", GeometryType.ofSRID("EPSG:0"))
testRoundTrip("\"geometry(epsg:4326)\"", GeometryType.ofSRID("epsg:4326"))
test("serialize/deserialize: geometry with various CRS formats") {
// Kernel accepts any CRS format; engine validates compatibility
testRoundTrip("\"geometry(OGC:CRS84)\"", GeometryType.ofCRS("OGC:CRS84"))
testRoundTrip("\"geometry(EPSG:4326)\"", GeometryType.ofCRS("EPSG:4326"))
testRoundTrip("\"geometry(EPSG:0)\"", GeometryType.ofCRS("EPSG:0"))
testRoundTrip("\"geometry(epsg:4326)\"", GeometryType.ofCRS("epsg:4326"))
}

test("deserialize: geography with default SRID and algorithm") {
test("deserialize: geography with default CRS and algorithm") {
// Parsing "geography" should use defaults (OGC:CRS84, spherical)
assert(parse("\"geography\"") === GeographyType.ofDefault())
// But serialization always writes full form
assert(serialize(GeographyType.ofDefault()) === "\"geography(OGC:CRS84, spherical)\"")
}

test("deserialize: geography with SRID and default algorithm") {
// Parsing "geography(<srid>)" should use default algorithm (spherical)
assert(parse("\"geography(EPSG:4326)\"") === GeographyType.ofSRID("EPSG:4326"))
assert(parse("\"geography(EPSG:3857)\"") === GeographyType.ofSRID("EPSG:3857"))
assert(parse("\"geography(OGC:CRS84)\"") === GeographyType.ofSRID("OGC:CRS84"))
test("deserialize: geography with CRS and default algorithm") {
// Parsing "geography(<crs>)" should use default algorithm (spherical)
assert(parse("\"geography(EPSG:4326)\"") === GeographyType.ofCRS("EPSG:4326"))
assert(parse("\"geography(EPSG:3857)\"") === GeographyType.ofCRS("EPSG:3857"))
assert(parse("\"geography(OGC:CRS84)\"") === GeographyType.ofCRS("OGC:CRS84"))
// But serialization always writes full form
assert(serialize(GeographyType.ofSRID("EPSG:4326")) === "\"geography(EPSG:4326, spherical)\"")
assert(serialize(GeographyType.ofCRS("EPSG:4326")) === "\"geography(EPSG:4326, spherical)\"")
}

test("deserialize: geography with default SRID and specified algorithm") {
// Parsing "geography(<algorithm>)" should use default SRID (OGC:CRS84)
test("deserialize: geography with default CRS and specified algorithm") {
// Parsing "geography(<algorithm>)" should use default CRS (OGC:CRS84)
assert(parse("\"geography(spherical)\"") === GeographyType.ofAlgorithm("spherical"))
assert(parse("\"geography(vincenty)\"") === GeographyType.ofAlgorithm("vincenty"))
assert(parse("\"geography(andoyer)\"") === GeographyType.ofAlgorithm("andoyer"))
Expand All @@ -138,8 +138,8 @@ class DataTypeJsonSerDeSuite extends AnyFunSuite {
"\"geography(OGC:CRS84, vincenty)\"")
}

test("serialize/deserialize: geography with both SRID and algorithm") {
// Both SRID and algorithm specified - round trips correctly
test("serialize/deserialize: geography with both CRS and algorithm") {
// Both CRS and algorithm specified - round trips correctly
testRoundTrip(
"\"geography(EPSG:4326, spherical)\"",
new GeographyType("EPSG:4326", "spherical"))
Expand All @@ -155,7 +155,7 @@ class DataTypeJsonSerDeSuite extends AnyFunSuite {
}

test("parseDataType: invalid geometry formats") {
// Missing SRID parameter
// Missing CRS parameter
checkError[IllegalArgumentException](
"\"geometry()\"",
"geometry() is not a supported delta data type")
Expand Down Expand Up @@ -494,7 +494,7 @@ class DataTypeJsonSerDeSuite extends AnyFunSuite {
arrayTypeJson("\"geometry(OGC:CRS84)\"", false),
new ArrayType(GeometryType.ofDefault(), false))

// Array of geography with non-default SRID and algorithm
// Array of geography with non-default CRS and algorithm
testRoundTrip(
arrayTypeJson("\"geography(EPSG:4326, vincenty)\"", true),
new ArrayType(new GeographyType("EPSG:4326", "vincenty"), true))
Expand All @@ -505,7 +505,7 @@ class DataTypeJsonSerDeSuite extends AnyFunSuite {
structFieldJson("geom", "\"geometry(EPSG:4326)\"", false),
structFieldJson("geog", "\"geography(EPSG:3857, spherical)\"", true))),
new StructType()
.add("geom", GeometryType.ofSRID("EPSG:4326"), false)
.add("geom", GeometryType.ofCRS("EPSG:4326"), false)
.add("geog", new GeographyType("EPSG:3857", "spherical"), true))

// Struct containing arrays of geometry and geography
Expand Down
Loading
Loading