Skip to content

Commit 2aab61b

Browse files
committed
support geometry type for create table
1 parent 4a386ea commit 2aab61b

File tree

27 files changed

+628
-75
lines changed

27 files changed

+628
-75
lines changed

Cargo.lock

+102-27
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

+1
Original file line numberDiff line numberDiff line change
@@ -261,3 +261,4 @@ sentry = { git = "https://github.com/getsentry/sentry-rust", rev = "6ef6d97" }
261261
micromarshal = { git = "https://github.com/ariesdevil/opensrv", rev = "6c96813" }
262262
async-backtrace = { git = "https://github.com/zhang2014/async-backtrace.git", rev = "dea4553" }
263263
geozero = { git = "https://github.com/georust/geozero", rev = "1d78b36" }
264+
proj = { git = "https://github.com/ariesdevil/proj", rev = "51e1c60" }

src/common/io/src/geometry.rs

+9-6
Original file line numberDiff line numberDiff line change
@@ -19,22 +19,25 @@ use geozero::CoordDimensions;
1919
use geozero::ToWkb;
2020
use wkt::TryFromWkt;
2121

22-
pub fn parse_to_ewkb(buf: &[u8]) -> Result<Vec<u8>> {
22+
pub fn parse_to_ewkb(buf: &[u8], srid: Option<i32>) -> Result<Vec<u8>> {
2323
let wkt = std::str::from_utf8(buf).map_err(|e| ErrorCode::GeometryError(e.to_string()))?;
24-
let mut srid: Option<i32> = None;
2524
let input_wkt = wkt.trim().to_ascii_uppercase();
2625

2726
let parts: Vec<&str> = input_wkt.split(';').collect();
2827

29-
if input_wkt.starts_with("SRID=") && parts.len() == 2 {
30-
srid = Some(parts[0].replace("SRID=", "").parse()?);
31-
}
28+
let parsed_srid: Option<i32> = srid.or_else(|| {
29+
if input_wkt.starts_with("SRID=") && parts.len() == 2 {
30+
parts[0].replace("SRID=", "").parse().ok()
31+
} else {
32+
None
33+
}
34+
});
3235

3336
let geo_part = if parts.len() == 2 { parts[1] } else { parts[0] };
3437

3538
let geom: Geometry<f64> = Geometry::try_from_wkt_str(geo_part)
3639
.map_err(|e| ErrorCode::GeometryError(e.to_string()))?;
3740

38-
geom.to_ewkb(CoordDimensions::xy(), srid)
41+
geom.to_ewkb(CoordDimensions::xy(), parsed_srid)
3942
.map_err(ErrorCode::from)
4043
}

src/query/ast/src/ast/expr.rs

+4
Original file line numberDiff line numberDiff line change
@@ -323,6 +323,7 @@ pub enum TypeName {
323323
fields_type: Vec<TypeName>,
324324
},
325325
Variant,
326+
Geometry,
326327
Nullable(Box<TypeName>),
327328
NotNull(Box<TypeName>),
328329
}
@@ -900,6 +901,9 @@ impl Display for TypeName {
900901
TypeName::Variant => {
901902
write!(f, "VARIANT")?;
902903
}
904+
TypeName::Geometry => {
905+
write!(f, "GEOMETRY")?;
906+
}
903907
TypeName::Nullable(ty) => {
904908
write!(f, "{} NULL", ty)?;
905909
}

src/query/ast/src/parser/expr.rs

+2
Original file line numberDiff line numberDiff line change
@@ -1586,6 +1586,7 @@ pub fn type_name(i: Input) -> IResult<TypeName> {
15861586
rule! { ( STRING | VARCHAR | CHAR | CHARACTER | TEXT ) ~ ( "(" ~ ^#literal_u64 ~ ^")" )? },
15871587
);
15881588
let ty_variant = value(TypeName::Variant, rule! { VARIANT | JSON });
1589+
let ty_geometry = value(TypeName::Geometry, rule! { GEOMETRY });
15891590
map_res(
15901591
alt((
15911592
rule! {
@@ -1614,6 +1615,7 @@ pub fn type_name(i: Input) -> IResult<TypeName> {
16141615
| #ty_binary
16151616
| #ty_string
16161617
| #ty_variant
1618+
| #ty_geometry
16171619
| #ty_nullable
16181620
) ~ #nullable? : "type name" },
16191621
)),

src/query/ast/src/parser/token.rs

+2
Original file line numberDiff line numberDiff line change
@@ -597,6 +597,8 @@ pub enum TokenKind {
597597
FUSE,
598598
#[token("GENERATED", ignore(ascii_case))]
599599
GENERATED,
600+
#[token("GEOMETRY", ignore(ascii_case))]
601+
GEOMETRY,
600602
#[token("GLOBAL", ignore(ascii_case))]
601603
GLOBAL,
602604
#[token("GRAPH", ignore(ascii_case))]

src/query/ast/tests/it/testdata/expr-error.txt

+1-1
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ error:
3030
--> SQL:1:14
3131
|
3232
1 | CAST(col1 AS foo)
33-
| ---- ^^^ unexpected `foo`, expecting `BOOL`, `FLOAT`, `BOOLEAN`, `FLOAT32`, `FLOAT64`, `BLOB`, `JSON`, `DOUBLE`, `LONGBLOB`, `UINT8`, `TINYINT`, `UINT16`, `SMALLINT`, `UINT32`, `INT`, `INTEGER`, `UINT64`, `UNSIGNED`, `BIGINT`, `INT8`, `INT16`, `INT32`, `INT64`, `SIGNED`, `DECIMAL`, `ARRAY`, `MAP`, `BITMAP`, `TUPLE`, `DATE`, `DATETIME`, `TIMESTAMP`, `BINARY`, `VARBINARY`, `MEDIUMBLOB`, `TINYBLOB`, `STRING`, `VARCHAR`, `CHAR`, `CHARACTER`, `TEXT`, `VARIANT`, or `NULLABLE`
33+
| ---- ^^^ unexpected `foo`, expecting `BOOL`, `FLOAT`, `BOOLEAN`, `FLOAT32`, `FLOAT64`, `BLOB`, `JSON`, `DOUBLE`, `LONGBLOB`, `GEOMETRY`, `UINT8`, `TINYINT`, `UINT16`, `SMALLINT`, `UINT32`, `INT`, `INTEGER`, `UINT64`, `UNSIGNED`, `BIGINT`, `INT8`, `INT16`, `INT32`, `INT64`, `SIGNED`, `DECIMAL`, `ARRAY`, `MAP`, `BITMAP`, `TUPLE`, `DATE`, `DATETIME`, `TIMESTAMP`, `BINARY`, `VARBINARY`, `MEDIUMBLOB`, `TINYBLOB`, `STRING`, `VARCHAR`, `CHAR`, `CHARACTER`, `TEXT`, `VARIANT`, or `NULLABLE`
3434
| |
3535
| while parsing `CAST(... AS ...)`
3636
| while parsing expression

src/query/ast/tests/it/testdata/statement-error.txt

+3-3
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ error:
2929
--> SQL:1:19
3030
|
3131
1 | create table a (c varch)
32-
| ------ - ^^^^^ unexpected `varch`, expecting `VARCHAR`, `CHAR`, `VARIANT`, `CHARACTER`, `VARBINARY`, `ARRAY`, `BINARY`, `MAP`, `DATE`, `STRING`, `FLOAT32`, `FLOAT64`, `DECIMAL`, `SMALLINT`, `DATETIME`, `NULLABLE`, `BOOLEAN`, `BOOL`, `UINT8`, `TINYINT`, `UINT16`, `UINT32`, `INT`, `INTEGER`, `UINT64`, `UNSIGNED`, `BIGINT`, `INT8`, `INT16`, `INT32`, `INT64`, `SIGNED`, `FLOAT`, `DOUBLE`, `BITMAP`, `TUPLE`, `TIMESTAMP`, `LONGBLOB`, `MEDIUMBLOB`, `TINYBLOB`, `BLOB`, `TEXT`, or `JSON`
32+
| ------ - ^^^^^ unexpected `varch`, expecting `VARCHAR`, `CHAR`, `VARIANT`, `CHARACTER`, `VARBINARY`, `ARRAY`, `BINARY`, `MAP`, `DATE`, `STRING`, `FLOAT32`, `FLOAT64`, `DECIMAL`, `SMALLINT`, `DATETIME`, `NULLABLE`, `BOOLEAN`, `BOOL`, `UINT8`, `TINYINT`, `UINT16`, `UINT32`, `INT`, `INTEGER`, `UINT64`, `UNSIGNED`, `BIGINT`, `INT8`, `INT16`, `INT32`, `INT64`, `SIGNED`, `FLOAT`, `DOUBLE`, `BITMAP`, `TUPLE`, `TIMESTAMP`, `LONGBLOB`, `MEDIUMBLOB`, `TINYBLOB`, `BLOB`, `TEXT`, `JSON`, or `GEOMETRY`
3333
| | |
3434
| | while parsing `<column name> <type> [DEFAULT <expr>] [AS (<expr>) VIRTUAL] [AS (<expr>) STORED] [COMMENT '<comment>']`
3535
| while parsing `CREATE [OR REPLACE] TABLE [IF NOT EXISTS] [<database>.]<table> [<source>] [<table_options>]`
@@ -42,7 +42,7 @@ error:
4242
--> SQL:1:25
4343
|
4444
1 | create table a (c tuple())
45-
| ------ - ----- ^ unexpected `)`, expecting `BOOLEAN`, `BOOL`, `UINT8`, `TINYINT`, `UINT16`, `SMALLINT`, `UINT32`, `INT`, `INTEGER`, `UINT64`, `UNSIGNED`, `BIGINT`, `INT8`, `INT16`, `INT32`, `INT64`, `SIGNED`, `FLOAT32`, `FLOAT`, `FLOAT64`, `DOUBLE`, `DECIMAL`, `ARRAY`, `MAP`, `BITMAP`, `TUPLE`, `DATE`, `DATETIME`, `TIMESTAMP`, `BINARY`, `VARBINARY`, `LONGBLOB`, `MEDIUMBLOB`, `TINYBLOB`, `BLOB`, `STRING`, `VARCHAR`, `CHAR`, `CHARACTER`, `TEXT`, `VARIANT`, `JSON`, `NULLABLE`, <Ident>, or <QuotedString>
45+
| ------ - ----- ^ unexpected `)`, expecting `BOOLEAN`, `BOOL`, `UINT8`, `TINYINT`, `UINT16`, `SMALLINT`, `UINT32`, `INT`, `INTEGER`, `UINT64`, `UNSIGNED`, `BIGINT`, `INT8`, `INT16`, `INT32`, `INT64`, `SIGNED`, `FLOAT32`, `FLOAT`, `FLOAT64`, `DOUBLE`, `DECIMAL`, `ARRAY`, `MAP`, `BITMAP`, `TUPLE`, `DATE`, `DATETIME`, `TIMESTAMP`, `BINARY`, `VARBINARY`, `LONGBLOB`, `MEDIUMBLOB`, `TINYBLOB`, `BLOB`, `STRING`, `VARCHAR`, `CHAR`, `CHARACTER`, `TEXT`, `VARIANT`, `JSON`, `GEOMETRY`, `NULLABLE`, <Ident>, or <QuotedString>
4646
| | | |
4747
| | | while parsing type name
4848
| | while parsing `<column name> <type> [DEFAULT <expr>] [AS (<expr>) VIRTUAL] [AS (<expr>) STORED] [COMMENT '<comment>']`
@@ -70,7 +70,7 @@ error:
7070
--> SQL:1:38
7171
|
7272
1 | create table a (b tuple(c int, uint64));
73-
| ------ - ----- ^ unexpected `)`, expecting `BOOLEAN`, `BOOL`, `UINT8`, `TINYINT`, `UINT16`, `SMALLINT`, `UINT32`, `INT`, `INTEGER`, `UINT64`, `UNSIGNED`, `BIGINT`, `INT8`, `INT16`, `INT32`, `INT64`, `SIGNED`, `FLOAT32`, `FLOAT`, `FLOAT64`, `DOUBLE`, `DECIMAL`, `ARRAY`, `MAP`, `BITMAP`, `TUPLE`, `DATE`, `DATETIME`, `TIMESTAMP`, `BINARY`, `VARBINARY`, `LONGBLOB`, `MEDIUMBLOB`, `TINYBLOB`, `BLOB`, `STRING`, `VARCHAR`, `CHAR`, `CHARACTER`, `TEXT`, `VARIANT`, `JSON`, or `NULLABLE`
73+
| ------ - ----- ^ unexpected `)`, expecting `BOOLEAN`, `BOOL`, `UINT8`, `TINYINT`, `UINT16`, `SMALLINT`, `UINT32`, `INT`, `INTEGER`, `UINT64`, `UNSIGNED`, `BIGINT`, `INT8`, `INT16`, `INT32`, `INT64`, `SIGNED`, `FLOAT32`, `FLOAT`, `FLOAT64`, `DOUBLE`, `DECIMAL`, `ARRAY`, `MAP`, `BITMAP`, `TUPLE`, `DATE`, `DATETIME`, `TIMESTAMP`, `BINARY`, `VARBINARY`, `LONGBLOB`, `MEDIUMBLOB`, `TINYBLOB`, `BLOB`, `STRING`, `VARCHAR`, `CHAR`, `CHARACTER`, `TEXT`, `VARIANT`, `JSON`, `GEOMETRY`, or `NULLABLE`
7474
| | | |
7575
| | | while parsing TUPLE(<name> <type>, ...)
7676
| | | while parsing type name

src/query/formats/src/field_decoder/fast_values.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -490,7 +490,7 @@ impl FastFieldDecoderValues {
490490
) -> Result<()> {
491491
let mut buf = Vec::new();
492492
self.read_string_inner(reader, &mut buf, positions)?;
493-
let geom = parse_to_ewkb(&buf)?;
493+
let geom = parse_to_ewkb(&buf, None)?;
494494
column.put_slice(geom.as_bytes());
495495
column.commit_row();
496496
Ok(())

src/query/formats/src/field_decoder/json_ast.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -330,7 +330,7 @@ impl FieldJsonAstDecoder {
330330
fn read_geometry(&self, column: &mut BinaryColumnBuilder, value: &Value) -> Result<()> {
331331
match value {
332332
Value::String(v) => {
333-
let geom = parse_to_ewkb(v.as_bytes())?;
333+
let geom = parse_to_ewkb(v.as_bytes(), None)?;
334334
column.put_slice(&geom);
335335
column.commit_row();
336336
Ok(())

src/query/formats/src/field_decoder/nested.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -327,7 +327,7 @@ impl NestedValues {
327327
) -> Result<()> {
328328
let mut buf = Vec::new();
329329
self.read_string_inner(reader, &mut buf)?;
330-
let geom = parse_to_ewkb(&buf)?;
330+
let geom = parse_to_ewkb(&buf, None)?;
331331
column.put_slice(geom.as_bytes());
332332
column.commit_row();
333333
Ok(())

0 commit comments

Comments
 (0)