-
Notifications
You must be signed in to change notification settings - Fork 133
Add MultiPoint datatype support #4662
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: BABEL_5_X_DEV
Are you sure you want to change the base?
Changes from 5 commits
aa41e21
373cc67
5dfc3ce
5ada761
78f48da
3c9f2b7
082145f
4e2b31f
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -313,6 +313,32 @@ CREATE OR REPLACE FUNCTION sys.Geometry__STPolyFromText(sys.NVARCHAR,srid intege | |
| END; | ||
| $$ LANGUAGE plpgsql IMMUTABLE PARALLEL SAFE; | ||
|
|
||
| CREATE OR REPLACE FUNCTION sys.Geometry__STMPointFromText(sys.NVARCHAR, srid integer) | ||
| RETURNS sys.GEOMETRY | ||
| AS $$ | ||
| DECLARE | ||
| Geomtype text; | ||
| geom sys.GEOMETRY; | ||
| BEGIN | ||
| IF $2 IS NULL THEN | ||
| RAISE EXCEPTION '''geometry::STMPointFromText'' failed because parameter 2 is not allowed to be null.'; | ||
| ELSIF $1 IS NULL THEN | ||
| RETURN NULL; | ||
| ELSIF $2 < 0 THEN | ||
|
||
| RAISE EXCEPTION 'SRID value must be non-negative.'; | ||
| END IF; | ||
|
|
||
| geom = sys.geomfromtext_helper($1::text, $2); | ||
| Geomtype = sys.ST_GeometryType(geom); | ||
|
|
||
| IF Geomtype = 'ST_MultiPoint' THEN | ||
| RETURN geom; | ||
| ELSE | ||
| RAISE EXCEPTION 'Expected "MULTIPOINT" at Position 1. The input has %s', $1; | ||
| END IF; | ||
| END; | ||
| $$ LANGUAGE plpgsql IMMUTABLE PARALLEL SAFE; | ||
|
|
||
| CREATE OR REPLACE FUNCTION sys.ST_GeometryType(sys.GEOMETRY) | ||
| RETURNS text | ||
| AS '$libdir/postgis-3', 'geometry_geometrytype' | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -667,3 +667,90 @@ rewrite_dim_polygon_query(PointArrayList *pal) | |
|
|
||
| return output.data; | ||
| } | ||
|
|
||
| char* | ||
| rewrite_multipoint_wkt(PointArray *pa) | ||
| { | ||
| DimensionType type; | ||
| StringInfoData output; | ||
|
|
||
| if (!pa) | ||
| return NULL; | ||
|
||
|
|
||
| if (pa->count == 0) | ||
| { | ||
| if (pa->points) | ||
| pfree(pa->points); | ||
| pfree(pa); | ||
| return pstrdup("MULTIPOINT EMPTY"); | ||
| } | ||
| initStringInfo(&output); | ||
|
|
||
| type = determine_ptarray_type(pa); | ||
|
|
||
| appendStringInfoString(&output, "MULTIPOINT"); | ||
|
|
||
| if (type == M) | ||
| appendStringInfoString(&output, " M"); | ||
|
|
||
| appendStringInfoChar(&output, '('); | ||
|
|
||
| transform_points(pa, type); | ||
|
|
||
| for (int i = 0; i < pa->count; i++) | ||
| { | ||
| POINT p = pa->points[i]; | ||
|
|
||
| appendStringInfoChar(&output, '('); | ||
| format_tsql_point_coordinates(&output, p); | ||
| appendStringInfoChar(&output, ')'); | ||
|
|
||
| if (i < pa->count - 1) | ||
| appendStringInfoString(&output, ", "); | ||
| } | ||
|
|
||
| appendStringInfoChar(&output, ')'); | ||
|
|
||
| pfree(pa->points); | ||
| pfree(pa); | ||
|
|
||
| return output.data; | ||
| } | ||
|
|
||
|
|
||
| char* | ||
| rewrite_dim_multipoint_wkt(PointArray *pa) | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This and the above function share a lot of common code, can we extract the logic to helper function?
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. done |
||
| { | ||
| StringInfoData output; | ||
|
|
||
| if (!pa || pa->count == 0) | ||
| { | ||
| if (pa) { | ||
| pfree(pa->points); | ||
| pfree(pa); | ||
| } | ||
| return pstrdup("MULTIPOINT EMPTY"); | ||
| } | ||
|
|
||
| initStringInfo(&output); | ||
| appendStringInfoString(&output, "MULTIPOINT("); | ||
|
|
||
| for (int i = 0; i < pa->count; i++) | ||
| { | ||
| POINT p = pa->points[i]; | ||
|
|
||
| appendStringInfoChar(&output, '('); | ||
| format_postgis_point_coordinates(&output, p); | ||
| appendStringInfoChar(&output, ')'); | ||
|
|
||
| if (i < pa->count - 1) | ||
| appendStringInfoString(&output, ", "); | ||
| } | ||
|
|
||
| appendStringInfoChar(&output, ')'); | ||
|
|
||
| pfree(pa->points); | ||
| pfree(pa); | ||
|
|
||
| return output.data; | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -27,6 +27,8 @@ static int scanbuflen; | |
| %type <pointarray> ptarray ptarraym ptarrayzm ptarrayz | ||
| %type <pointarraylist> ringlist ringlistm ringlistz ringlistzm | ||
| %type <str> geospatial_query point_query linestring_query polygon_query | ||
| %type <str> multipoint_query | ||
| %type <pointarray> mpoint_list mpoint_list_z mpoint_list_m mpoint_list_zm | ||
|
|
||
| %start geospatial_query | ||
| %define api.prefix {geo_yy} | ||
|
|
@@ -39,6 +41,7 @@ geospatial_query: | |
| linestring_query { $$ = $1; *result = $$; } | ||
| | point_query { $$ = $1; *result = $$; } | ||
| | polygon_query { $$ = $1; *result = $$; } | ||
| | multipoint_query { $$ = $1; *result = $$; } | ||
| ; | ||
|
|
||
| point_query: | ||
|
|
@@ -230,6 +233,98 @@ coordinate: | |
| { $$ = create_point($1, $2, 0, $4, 0, 1); } | ||
| ; | ||
|
|
||
| multipoint_query: | ||
| MPOINT_TOK LPAREN mpoint_list RPAREN | ||
| { $$ = rewrite_multipoint_wkt($3); } | ||
| | MPOINT_TOK LPAREN ptarray RPAREN | ||
| { $$ = rewrite_multipoint_wkt($3); } | ||
| | MPOINT_TOK EMPTY_TOK | ||
| { $$ = pstrdup("MULTIPOINT EMPTY"); } | ||
| | MPOINT_TOK Z_TOK LPAREN mpoint_list_z RPAREN | ||
| { $$ = rewrite_dim_multipoint_wkt($4); } | ||
| | MPOINT_TOK M_TOK LPAREN mpoint_list_m RPAREN | ||
| { $$ = rewrite_dim_multipoint_wkt($4); } | ||
| | MPOINT_TOK ZM_TOK LPAREN mpoint_list_zm RPAREN | ||
| { $$ = rewrite_dim_multipoint_wkt($4); } | ||
| | MPOINT_TOK Z_TOK LPAREN ptarrayz RPAREN | ||
| { $$ = rewrite_dim_multipoint_wkt($4); } | ||
| | MPOINT_TOK M_TOK LPAREN ptarraym RPAREN | ||
| { $$ = rewrite_dim_multipoint_wkt($4); } | ||
| | MPOINT_TOK ZM_TOK LPAREN ptarrayzm RPAREN | ||
| { $$ = rewrite_dim_multipoint_wkt($4); } | ||
| | MPOINT_TOK Z_TOK EMPTY_TOK | ||
| { $$ = pstrdup("MULTIPOINT EMPTY"); } | ||
| | MPOINT_TOK M_TOK EMPTY_TOK | ||
| { $$ = pstrdup("MULTIPOINT EMPTY"); } | ||
| | MPOINT_TOK ZM_TOK EMPTY_TOK | ||
| { $$ = pstrdup("MULTIPOINT EMPTY"); } | ||
|
||
| ; | ||
|
|
||
|
|
||
| /* 2D MULTIPOINT: MULTIPOINT((x y), (x y), ...) */ | ||
| mpoint_list: | ||
| LPAREN coordinate RPAREN | ||
| { | ||
| PointArray *pa = palloc(sizeof(PointArray)); | ||
| init_point_array(pa); | ||
| add_point(pa, $2); | ||
| $$ = pa; | ||
| } | ||
| | mpoint_list COMMA_TOK LPAREN coordinate RPAREN | ||
| { | ||
| add_point($1, $4); | ||
| $$ = $1; | ||
| } | ||
| ; | ||
|
|
||
| /* Z MULTIPOINT: MULTIPOINT Z((x y z), (x y z), ...) */ | ||
| mpoint_list_z: | ||
| LPAREN coordz RPAREN | ||
| { | ||
| PointArray *pa = palloc(sizeof(PointArray)); | ||
| init_point_array(pa); | ||
| add_point(pa, $2); | ||
| $$ = pa; | ||
| } | ||
| | mpoint_list_z COMMA_TOK LPAREN coordz RPAREN | ||
| { | ||
| add_point($1, $4); | ||
| $$ = $1; | ||
| } | ||
| ; | ||
|
|
||
| /* M MULTIPOINT: MULTIPOINT M((x y m), (x y m), ...) */ | ||
| mpoint_list_m: | ||
| LPAREN coordm RPAREN | ||
| { | ||
| PointArray *pa = palloc(sizeof(PointArray)); | ||
| init_point_array(pa); | ||
| add_point(pa, $2); | ||
| $$ = pa; | ||
| } | ||
| | mpoint_list_m COMMA_TOK LPAREN coordm RPAREN | ||
| { | ||
| add_point($1, $4); | ||
| $$ = $1; | ||
| } | ||
| ; | ||
|
|
||
| /* ZM MULTIPOINT: MULTIPOINT ZM((x y z m), (x y z m), ...) */ | ||
| mpoint_list_zm: | ||
| LPAREN coordzm RPAREN | ||
| { | ||
| PointArray *pa = palloc(sizeof(PointArray)); | ||
| init_point_array(pa); | ||
| add_point(pa, $2); | ||
| $$ = pa; | ||
| } | ||
| | mpoint_list_zm COMMA_TOK LPAREN coordzm RPAREN | ||
| { | ||
| add_point($1, $4); | ||
| $$ = $1; | ||
| } | ||
| ; | ||
|
|
||
| %% | ||
|
|
||
| /* Include lexer after parser to avoid circular dependencies and ensure shared context */ | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We don't need this check since we already have SRID validity check later on