-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
30 changed files
with
748 additions
and
54 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -2,4 +2,5 @@ pub mod expr; | |
pub mod parser; | ||
pub mod projection; | ||
pub mod statement; | ||
pub mod target; | ||
pub mod type_; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
use crate::util::span::Spanned; | ||
|
||
pub enum Target { | ||
Table(Spanned<String>), | ||
Record(Spanned<String>, Spanned<String>), | ||
} | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -4,4 +4,5 @@ use super::type_::Type; | |
pub struct Field { | ||
pub name: String, | ||
pub ty: Type, | ||
pub is_required: bool, | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,127 @@ | ||
// r#"## `count` | ||
// | ||
// The count function counts the number of times that the function is called. This is useful for returning the total number of rows in a SELECT statement with a `GROUP BY` clause. | ||
// | ||
// ### API Definition | ||
// ``` | ||
// count() -> 1 | ||
// ``` | ||
// If a value is given as the first argument, then this function checks whether a given value is truthy. This is useful for returning the total number of rows, which match a certain condition, in a [`SELECT`](/docs/surrealql/statements/select) statement, with a GROUP BY clause. | ||
// | ||
// ### API Definition | ||
// ``` | ||
// count(any) -> number | ||
// ``` | ||
// | ||
// If an array is given, this function counts the number of items in the array which are truthy. If, instead, you want to count the total number of items in the given array, then use the [`array::len()`](/docs/surrealql/functions/array#len) function. | ||
// | ||
// ### API Definition | ||
// ``` | ||
// count(array) -> number | ||
// ``` | ||
// The following example shows this function, and its output, when used in a [`RETURN`](/docs/surrealql/statements/return) statement: | ||
// | ||
// ``` | ||
// RETURN count(); | ||
// | ||
// 1 | ||
// ``` | ||
// ``` | ||
// RETURN count(true); | ||
// | ||
// 1 | ||
// ``` | ||
// ``` | ||
// RETURN count(10 > 15); | ||
// | ||
// 0 | ||
// ``` | ||
// ``` | ||
// RETURN count([ 1, 2, 3, null, 0, false, (15 > 10), rand::uuid() ]); | ||
// | ||
// 5 | ||
// ``` | ||
// The following examples show this function being used in a [`SELECT`](/docs/surrealql/statements/select) statement with a GROUP clause: | ||
// | ||
// ``` | ||
// SELECT count() FROM [{ age: 33 }, { age: 45 }, { age: 39 }] GROUP ALL; | ||
// | ||
// 3 | ||
// ``` | ||
// ``` | ||
// SELECT count(age > 35) FROM [{ age: 33 }, { age: 45 }, { age: 39 }] GROUP ALL; | ||
// | ||
// 2 | ||
// ``` | ||
// An advanced example of the count function can be seen below: | ||
// | ||
// ``` | ||
// SELECT | ||
// country, | ||
// count(age > 30) AS total | ||
// FROM [ | ||
// { age: 33, country: 'GBR' }, | ||
// { age: 45, country: 'GBR' }, | ||
// { age: 39, country: 'USA' }, | ||
// { age: 29, country: 'GBR' }, | ||
// { age: 43, country: 'USA' } | ||
// ] | ||
// GROUP BY country; | ||
// ``` | ||
// ```json | ||
// [ | ||
// { | ||
// country: 'GBR', | ||
// total: 2 | ||
// }, | ||
// { | ||
// country: 'USA', | ||
// total: 2 | ||
// } | ||
// ] | ||
// ```"#.to_string(), | ||
// | ||
|
||
use std::collections::HashMap; | ||
|
||
use crate::declarations::{ | ||
functions::{Function, GenericType}, | ||
type_::Type, | ||
}; | ||
|
||
pub fn get_count_functions() -> HashMap<String, Function> { | ||
let mut map: HashMap<String, Function> = HashMap::new(); | ||
|
||
map.insert( | ||
"count".to_string(), | ||
Function { | ||
args: vec![], | ||
return_type: GenericType::Named(Type::Int), | ||
doc: Some(r#" | ||
## Count | ||
The count function counts the number of times that the function is called. This is useful for returning the total number of rows in a SELECT statement with a `GROUP BY` clause. | ||
### Examples | ||
```surqls | ||
SELECT | ||
count() AS total | ||
FROM [ | ||
{ age: 33 }, | ||
{ age: 45 }, | ||
{ age: 39 } | ||
] | ||
GROUP ALL; | ||
``` | ||
```json | ||
[ | ||
{ | ||
total: 3 | ||
} | ||
] | ||
``` | ||
"#.to_string()), | ||
}, | ||
); | ||
|
||
map | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
pub mod count; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,106 @@ | ||
use std::{collections::HashMap, fmt::Display}; | ||
|
||
use super::{func::count::get_count_functions, type_::Type}; | ||
|
||
#[derive(Clone, Debug)] | ||
pub enum GenericType { | ||
Named(Type), | ||
TypeParam { super_: Type }, | ||
GenericArray { inner_super_: Type }, | ||
GenericOption { inner_super_: Type }, | ||
} | ||
|
||
impl Display for GenericType { | ||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { | ||
match self { | ||
GenericType::Named(ref t) => write!(f, "{}", t), | ||
GenericType::TypeParam { super_: _ } => write!(f, "T"), | ||
GenericType::GenericArray { inner_super_: _ } => write!(f, "array<T>"), | ||
GenericType::GenericOption { inner_super_: _ } => write!(f, "option<T>"), | ||
} | ||
} | ||
} | ||
|
||
#[derive(Clone, Debug)] | ||
pub struct Function { | ||
pub args: Vec<FunctionArg>, | ||
pub return_type: GenericType, | ||
pub doc: Option<String>, | ||
} | ||
|
||
#[derive(Clone, Debug)] | ||
pub struct FunctionArg(pub String, pub GenericType); | ||
|
||
impl Function { | ||
pub fn get_type(&self, arg: Type) -> Type { | ||
match self.return_type { | ||
GenericType::Named(ref t) => t.clone(), | ||
GenericType::TypeParam { super_: _ } => arg, | ||
GenericType::GenericArray { inner_super_: _ } => Type::Array(Box::new(arg)), | ||
GenericType::GenericOption { inner_super_: _ } => Type::Option(Box::new(arg)), | ||
} | ||
} | ||
|
||
pub fn get_arg_type(&self, args: Vec<Type>) -> Type { | ||
let mut found: Option<Type> = None; | ||
for (index, FunctionArg(_, expected)) in self.args.iter().enumerate() { | ||
let actual = args.get(index).unwrap(); | ||
match expected { | ||
GenericType::Named(ref t) => {} | ||
GenericType::TypeParam { super_ } => { | ||
let found_type = if actual.is_assignable_to(super_) { | ||
actual.clone() | ||
} else { | ||
Type::Error | ||
}; | ||
let new_type = match found { | ||
Some(ref found_type) => found_type.get_shared_super_type(&found_type), | ||
None => found_type, | ||
}; | ||
let found = Some(new_type); | ||
} | ||
GenericType::GenericArray { inner_super_ } => { | ||
if let Type::Array(ref t) = actual { | ||
if t.is_assignable_to(inner_super_) { | ||
return t.as_ref().clone(); | ||
} else { | ||
return Type::Error; | ||
} | ||
} | ||
} | ||
GenericType::GenericOption { inner_super_ } => { | ||
if let Type::Option(ref t) = actual { | ||
if t.is_assignable_to(inner_super_) { | ||
return t.as_ref().clone(); | ||
} else { | ||
return Type::Error; | ||
} | ||
} | ||
} | ||
} | ||
} | ||
match found { | ||
Some(t) => t, | ||
None => Type::Any, | ||
} | ||
} | ||
|
||
pub fn get_return_type(&self, args: Vec<Type>) -> Type { | ||
let arg_type = self.get_arg_type(args); | ||
self.get_type(arg_type) | ||
} | ||
} | ||
|
||
impl Display for Function { | ||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { | ||
let mut args = vec![]; | ||
for arg in &self.args { | ||
args.push(format!("{}: {}", arg.0, arg.1)); | ||
} | ||
write!(f, "({}) -> {}", args.join(", "), self.return_type) | ||
} | ||
} | ||
|
||
pub fn get_functions() -> HashMap<String, Function> { | ||
return get_count_functions(); | ||
} |
Oops, something went wrong.