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 19, 2024
1 parent b5b40f7 commit 96913d9
Show file tree
Hide file tree
Showing 26 changed files with 605 additions and 71 deletions.
103 changes: 80 additions & 23 deletions Cargo.lock

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

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 @@ -322,6 +322,7 @@ pub enum TypeName {
fields_type: Vec<TypeName>,
},
Variant,
Geometry,
Nullable(Box<TypeName>),
NotNull(Box<TypeName>),
}
Expand Down Expand Up @@ -899,6 +900,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 @@ -490,7 +490,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 @@ -327,7 +327,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
2 changes: 1 addition & 1 deletion src/query/formats/src/field_decoder/separated_text.rs
Original file line number Diff line number Diff line change
Expand Up @@ -345,7 +345,7 @@ impl SeparatedTextDecoder {
}

fn read_geometry(&self, column: &mut BinaryColumnBuilder, data: &[u8]) -> Result<()> {
let geom = parse_to_ewkb(data)?;
let geom = parse_to_ewkb(data, None)?;
column.put_slice(geom.as_bytes());
column.commit_row();
Ok(())
Expand Down
13 changes: 6 additions & 7 deletions src/query/formats/src/field_encoder/values.rs
Original file line number Diff line number Diff line change
Expand Up @@ -32,9 +32,9 @@ use databend_common_io::constants::NAN_BYTES_LOWER;
use databend_common_io::constants::NAN_BYTES_SNAKE;
use databend_common_io::constants::NULL_BYTES_UPPER;
use databend_common_io::constants::TRUE_BYTES_NUM;
use geozero::wkb::Ewkb;
use geozero::CoordDimensions;
use geozero::ToWkb;
use geozero::wkb::FromWkb;
use geozero::wkb::WkbDialect;
use geozero::wkt::Ewkt;
use lexical_core::ToLexical;
use micromarshal::Marshal;
use micromarshal::Unmarshal;
Expand Down Expand Up @@ -296,10 +296,9 @@ impl FieldEncoderValues {
in_nested: bool,
) {
let v = unsafe { column.index_unchecked(row_index) };
let s = Ewkb(v.to_vec())
.to_ewkb(CoordDimensions::xy(), None)
.unwrap();
self.write_string_inner(&s, out_buf, in_nested);
let mut data_cursor = std::io::Cursor::new(v);
let s = Ewkt::from_wkb(&mut data_cursor, WkbDialect::Ewkb).unwrap();
self.write_string_inner(s.0.as_bytes(), out_buf, in_nested);
}

fn write_array<T: ValueType>(
Expand Down
2 changes: 2 additions & 0 deletions src/query/functions/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -51,9 +51,11 @@ ordered-float = { workspace = true, features = [
"serde",
"rand",
] }
proj = { version = "0.27.2", features = ["geo-types", "bundled_proj"] }
rand = { workspace = true }
regex = { workspace = true }
roaring = "0.10.1"
scroll = "0.12.0"
sha1 = "0.10.5"
sha2 = "0.10.6"
simdutf8 = "0.1.4"
Expand Down
Loading

0 comments on commit 96913d9

Please sign in to comment.