Skip to content

Commit

Permalink
support geometry type for create table
Browse files Browse the repository at this point in the history
  • Loading branch information
ariesdevil committed Feb 20, 2024
1 parent 346a955 commit 340c8bc
Show file tree
Hide file tree
Showing 27 changed files with 628 additions and 75 deletions.
129 changes: 102 additions & 27 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -261,3 +261,4 @@ sentry = { git = "https://github.com/getsentry/sentry-rust", rev = "6ef6d97" }
micromarshal = { git = "https://github.com/ariesdevil/opensrv", rev = "6c96813" }
async-backtrace = { git = "https://github.com/zhang2014/async-backtrace.git", rev = "dea4553" }
geozero = { git = "https://github.com/georust/geozero", rev = "1d78b36" }
proj = { git = "https://github.com/ariesdevil/proj", rev = "51e1c60" }
15 changes: 9 additions & 6 deletions src/common/io/src/geometry.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,22 +19,25 @@ use geozero::CoordDimensions;
use geozero::ToWkb;
use wkt::TryFromWkt;

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

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

if input_wkt.starts_with("SRID=") && parts.len() == 2 {
srid = Some(parts[0].replace("SRID=", "").parse()?);
}
let parsed_srid: Option<i32> = srid.or_else(|| {
if input_wkt.starts_with("SRID=") && parts.len() == 2 {
parts[0].replace("SRID=", "").parse().ok()
} else {
None
}
});

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

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

geom.to_ewkb(CoordDimensions::xy(), srid)
geom.to_ewkb(CoordDimensions::xy(), parsed_srid)
.map_err(ErrorCode::from)
}
4 changes: 4 additions & 0 deletions src/query/ast/src/ast/expr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -323,6 +323,7 @@ pub enum TypeName {
fields_type: Vec<TypeName>,
},
Variant,
Geometry,
Nullable(Box<TypeName>),
NotNull(Box<TypeName>),
}
Expand Down Expand Up @@ -900,6 +901,9 @@ impl Display for TypeName {
TypeName::Variant => {
write!(f, "VARIANT")?;
}
TypeName::Geometry => {
write!(f, "GEOMETRY")?;
}
TypeName::Nullable(ty) => {
write!(f, "{} NULL", ty)?;
}
Expand Down
2 changes: 2 additions & 0 deletions src/query/ast/src/parser/expr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1586,6 +1586,7 @@ pub fn type_name(i: Input) -> IResult<TypeName> {
rule! { ( STRING | VARCHAR | CHAR | CHARACTER | TEXT ) ~ ( "(" ~ ^#literal_u64 ~ ^")" )? },
);
let ty_variant = value(TypeName::Variant, rule! { VARIANT | JSON });
let ty_geometry = value(TypeName::Geometry, rule! { GEOMETRY });
map_res(
alt((
rule! {
Expand Down Expand Up @@ -1614,6 +1615,7 @@ pub fn type_name(i: Input) -> IResult<TypeName> {
| #ty_binary
| #ty_string
| #ty_variant
| #ty_geometry
| #ty_nullable
) ~ #nullable? : "type name" },
)),
Expand Down
2 changes: 2 additions & 0 deletions src/query/ast/src/parser/token.rs
Original file line number Diff line number Diff line change
Expand Up @@ -597,6 +597,8 @@ pub enum TokenKind {
FUSE,
#[token("GENERATED", ignore(ascii_case))]
GENERATED,
#[token("GEOMETRY", ignore(ascii_case))]
GEOMETRY,
#[token("GLOBAL", ignore(ascii_case))]
GLOBAL,
#[token("GRAPH", ignore(ascii_case))]
Expand Down
2 changes: 1 addition & 1 deletion src/query/ast/tests/it/testdata/expr-error.txt
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ error:
--> SQL:1:14
|
1 | CAST(col1 AS foo)
| ---- ^^^ 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`
| ---- ^^^ 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`
| |
| while parsing `CAST(... AS ...)`
| while parsing expression
Expand Down
6 changes: 3 additions & 3 deletions src/query/ast/tests/it/testdata/statement-error.txt
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ error:
--> SQL:1:19
|
1 | create table a (c varch)
| ------ - ^^^^^ 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`
| ------ - ^^^^^ 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`
| | |
| | while parsing `<column name> <type> [DEFAULT <expr>] [AS (<expr>) VIRTUAL] [AS (<expr>) STORED] [COMMENT '<comment>']`
| while parsing `CREATE [OR REPLACE] TABLE [IF NOT EXISTS] [<database>.]<table> [<source>] [<table_options>]`
Expand All @@ -42,7 +42,7 @@ error:
--> SQL:1:25
|
1 | create table a (c tuple())
| ------ - ----- ^ 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>
| ------ - ----- ^ 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>
| | | |
| | | while parsing type name
| | while parsing `<column name> <type> [DEFAULT <expr>] [AS (<expr>) VIRTUAL] [AS (<expr>) STORED] [COMMENT '<comment>']`
Expand Down Expand Up @@ -70,7 +70,7 @@ error:
--> SQL:1:38
|
1 | create table a (b tuple(c int, uint64));
| ------ - ----- ^ 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`
| ------ - ----- ^ 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`
| | | |
| | | while parsing TUPLE(<name> <type>, ...)
| | | while parsing type name
Expand Down
2 changes: 1 addition & 1 deletion src/query/formats/src/field_decoder/fast_values.rs
Original file line number Diff line number Diff line change
Expand Up @@ -489,7 +489,7 @@ impl FastFieldDecoderValues {
) -> Result<()> {
let mut buf = Vec::new();
self.read_string_inner(reader, &mut buf, positions)?;
let geom = parse_to_ewkb(&buf)?;
let geom = parse_to_ewkb(&buf, None)?;
column.put_slice(geom.as_bytes());
column.commit_row();
Ok(())
Expand Down
2 changes: 1 addition & 1 deletion src/query/formats/src/field_decoder/json_ast.rs
Original file line number Diff line number Diff line change
Expand Up @@ -330,7 +330,7 @@ impl FieldJsonAstDecoder {
fn read_geometry(&self, column: &mut BinaryColumnBuilder, value: &Value) -> Result<()> {
match value {
Value::String(v) => {
let geom = parse_to_ewkb(v.as_bytes())?;
let geom = parse_to_ewkb(v.as_bytes(), None)?;
column.put_slice(&geom);
column.commit_row();
Ok(())
Expand Down
2 changes: 1 addition & 1 deletion src/query/formats/src/field_decoder/nested.rs
Original file line number Diff line number Diff line change
Expand Up @@ -328,7 +328,7 @@ impl NestedValues {
) -> Result<()> {
let mut buf = Vec::new();
self.read_string_inner(reader, &mut buf)?;
let geom = parse_to_ewkb(&buf)?;
let geom = parse_to_ewkb(&buf, None)?;
column.put_slice(geom.as_bytes());
column.commit_row();
Ok(())
Expand Down
Loading

0 comments on commit 340c8bc

Please sign in to comment.