Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,7 @@ jobs:
run: maturin develop

- name: "Run pytest"
run: pytest -v --workers auto
run: pytest -v -n auto
env:
HYPOTHESIS_PROFILE: slow

Expand Down
60 changes: 60 additions & 0 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 @@ -18,6 +18,7 @@ name = "rapidquery"
arcstr = { version = "1.2" }
bitflags = { version = "2.13.2", default-features = false }
chrono = { version = "0.4", default-features = false, features = ["clock"] }
derive_more = { version = "2.1.1", default-features = false, features = ["display", "from_str"] }
hashbrown = { version = "0.17.1", default-features = false, features = ["default-hasher", "allocator-api2", "inline-more"] }
ipnetwork = { version = "0.20", default-features = false }
mac_address = { version = "1.1", default-features = false }
Expand Down
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,8 @@ ASTs until being merged into default branch.

### DDL

- [ ] CREATE SCHEMA
- [ ] DROP SCHEMA
- [x] CREATE SCHEMA
- [x] DROP SCHEMA
- [ ] CREATE TABLE
- [ ] ALTER TABLE
- [ ] DROP TABLE
Expand Down
8 changes: 7 additions & 1 deletion rapidquery/ddl.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,11 @@
from ._core.ddl import DataDefinitionLanguage
from ._core.ddl import (
CreateSchema,
DataDefinitionLanguage,
DropSchema,
)

__all__ = [
"CreateSchema",
"DataDefinitionLanguage",
"DropSchema",
]
94 changes: 93 additions & 1 deletion rapidquery/ddl.pyi
Original file line number Diff line number Diff line change
@@ -1,6 +1,98 @@
"""Data Definition Language"""

import typing
from typing import Self, final

from rapidquery.dialect import Dialect
from rapidquery.expr import Ident, _IdentExtractor

class DataDefinitionLanguage:
"""Base of every DDL statement. Construct a subclass, not this class."""

...
def to_sql(self, dialect: Dialect) -> str:
"""
Render ``self`` with values written as SQL literals.

Args:
dialect: Dialect that chooses quoting and literal spelling.

Returns:
The SQL text.

Raises:
RuntimeError: The dialect rejects this construct.
ValueError: A `CustomExpr` template has a different number of `{}`
slots than arguments.
"""

@final
class CreateSchema(DataDefinitionLanguage):
"""
Represents ``CREATE SCHEMA`` statement (and can be ``CREATE DATABASE`` statement).
"""

def __new__(
cls,
name: _IdentExtractor,
*,
if_not_exists: bool = False,
authorization: str | None = None,
location: str | None = None,
) -> Self:
"""
Construct a new ``CREATE SCHEMA`` statement. If the target dialect specified
``OPT_SCHEMA_FEATURES_IS_DATABASE`` option, it generates ``CREATE DATABASE`` instead.

Args:
name: schema name e.g. `"analysis"`. Some dialects supports multipart names (like `"public"."analysis"`)
so there's no limit and it is in your control.
if_not_exists: Emits ``IF NOT EXISTS`` clause. Means do nothing if a schema with the same name
already exists. *If targeted dialect doesn't support this, it will be ignored.*
authorization: Emits ``AUTHORIZATION name`` clause. Some dialects allow us to names the owner of the new
schema.
location: Some dialects allow us to specify a location for the new schema. It binds the schema to a directory,
which can be a local FS path, HDFS, or even S3.
"""
...

@property
def name(self) -> Ident: ...
@property
def if_not_exists(self) -> bool: ...
@property
def authorization(self) -> str | None: ...
@property
def location(self) -> str | None: ...

@final
class DropSchema(DataDefinitionLanguage):
"""
Represents ``DROP SCHEMA`` statement (and can be ``DROP DATABASE`` statement).
"""

def __new__(
cls,
name: _IdentExtractor,
*,
if_exists: bool = False,
behavior: typing.Literal["CASCADE", "RESTRICT"] | str | None = None,
) -> Self:
"""
Construct a new ``DROP SCHEMA`` statement. If the target dialect specified
``OPT_SCHEMA_FEATURES_IS_DATABASE`` option, it generates ``DROP DATABASE`` instead.

Args:
name: schema name e.g. `"analysis"`. Some dialects supports multipart names (like `"public"."analysis"`)
so there's no limit and it is in your control.
if_exists: Emits ``IF EXISTS`` clause. Means do nothing if the schame doesn't exist.
*If targeted dialect doesn't support this, it will be ignored.*
behavior: Emits ``CASCADE`` or ``RESTRICT`` keywords.
"""
...

@property
def name(self) -> Ident: ...
@property
def if_exists(self) -> bool: ...
@property
def behavior(self) -> typing.Literal["CASCADE", "RESTRICT"] | None: ...
24 changes: 24 additions & 0 deletions rapidquery/dialect.py
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,18 @@
OPT_RLIKE_EXPRESSION_STANDARD,
OPT_RLIKE_EXPRESSION_TILDE,
OPT_RLIKE_EXPRESSION_UNSUPPORTED,
OPT_SCHEMA_AUTHORIZATION_STYLE_OPTIONAL,
OPT_SCHEMA_AUTHORIZATION_STYLE_UNSUPPORTED,
OPT_SCHEMA_FEATURES_DROP_CASCADE,
OPT_SCHEMA_FEATURES_DROP_RESTRICT,
OPT_SCHEMA_FEATURES_EMBEDDED_DDL,
OPT_SCHEMA_FEATURES_IF_NOT_EXISTS,
OPT_SCHEMA_FEATURES_IS_DATABASE,
OPT_SCHEMA_FEATURES_UNSUPPORTED,
OPT_SCHEMA_LOCATION_STYLE_EXTERNAL_VOLUME,
OPT_SCHEMA_LOCATION_STYLE_LOCATION_KEYWORD,
OPT_SCHEMA_LOCATION_STYLE_MANAGED_LOCATION_KEYWORD,
OPT_SCHEMA_LOCATION_STYLE_UNSUPPORTED,
OPT_STRING_CONCAT_CONCAT_FUNCTION,
OPT_STRING_CONCAT_PIPES,
OPT_STRING_CONCAT_PLUS,
Expand Down Expand Up @@ -215,6 +227,18 @@
"OPT_RLIKE_EXPRESSION_STANDARD",
"OPT_RLIKE_EXPRESSION_TILDE",
"OPT_RLIKE_EXPRESSION_UNSUPPORTED",
"OPT_SCHEMA_AUTHORIZATION_STYLE_OPTIONAL",
"OPT_SCHEMA_AUTHORIZATION_STYLE_UNSUPPORTED",
"OPT_SCHEMA_FEATURES_DROP_CASCADE",
"OPT_SCHEMA_FEATURES_DROP_RESTRICT",
"OPT_SCHEMA_FEATURES_EMBEDDED_DDL",
"OPT_SCHEMA_FEATURES_IF_NOT_EXISTS",
"OPT_SCHEMA_FEATURES_IS_DATABASE",
"OPT_SCHEMA_FEATURES_UNSUPPORTED",
"OPT_SCHEMA_LOCATION_STYLE_EXTERNAL_VOLUME",
"OPT_SCHEMA_LOCATION_STYLE_LOCATION_KEYWORD",
"OPT_SCHEMA_LOCATION_STYLE_MANAGED_LOCATION_KEYWORD",
"OPT_SCHEMA_LOCATION_STYLE_UNSUPPORTED",
"OPT_STRING_CONCAT_CONCAT_FUNCTION",
"OPT_STRING_CONCAT_PIPES",
"OPT_STRING_CONCAT_PLUS",
Expand Down
33 changes: 27 additions & 6 deletions rapidquery/dialect.pyi
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,10 @@ OPT_ARRAY_FORMAT_CONSTRUCTOR: typing.Final[int]
OPT_ARRAY_FORMAT_FUNCTION: typing.Final[int]
OPT_ARRAY_FORMAT_LIST: typing.Final[int]
OPT_ARRAY_FORMAT_UNSUPPORTED: typing.Final[int]
OPT_BIT_FORMAT_POSTFIX_BIG_B: typing.Final[int]
OPT_BIT_FORMAT_PREFIX_BIG_B: typing.Final[int]
OPT_BIT_FORMAT_PREFIX_SMALL_B: typing.Final[int]
OPT_BIT_FORMAT_UNSUPPORTED: typing.Final[int]
OPT_BITWISE_CALL_SYNTAX_BIT_FUNCTION: typing.Final[int]
OPT_BITWISE_CALL_SYNTAX_INFIX: typing.Final[int]
OPT_BITWISE_CALL_SYNTAX_SHIFT_FUNCTION: typing.Final[int]
Expand All @@ -21,10 +25,6 @@ OPT_BITWISE_XOR_SPELLING_CARET: typing.Final[int]
OPT_BITWISE_XOR_SPELLING_FUNCTION: typing.Final[int]
OPT_BITWISE_XOR_SPELLING_HASH: typing.Final[int]
OPT_BITWISE_XOR_SPELLING_UNSUPPORTED: typing.Final[int]
OPT_BIT_FORMAT_POSTFIX_BIG_B: typing.Final[int]
OPT_BIT_FORMAT_PREFIX_BIG_B: typing.Final[int]
OPT_BIT_FORMAT_PREFIX_SMALL_B: typing.Final[int]
OPT_BIT_FORMAT_UNSUPPORTED: typing.Final[int]
OPT_BOOL_FORMAT_INTEGER: typing.Final[int]
OPT_BOOL_FORMAT_KEYWORD: typing.Final[int]
OPT_BYTES_FORMAT_HEX_TO_RAW: typing.Final[int]
Expand Down Expand Up @@ -89,6 +89,18 @@ OPT_RLIKE_EXPRESSION_REGEXP_MATCHES: typing.Final[int]
OPT_RLIKE_EXPRESSION_STANDARD: typing.Final[int]
OPT_RLIKE_EXPRESSION_TILDE: typing.Final[int]
OPT_RLIKE_EXPRESSION_UNSUPPORTED: typing.Final[int]
OPT_SCHEMA_AUTHORIZATION_STYLE_OPTIONAL: typing.Final[int]
OPT_SCHEMA_AUTHORIZATION_STYLE_UNSUPPORTED: typing.Final[int]
OPT_SCHEMA_FEATURES_EMBEDDED_DDL: typing.Final[int]
OPT_SCHEMA_FEATURES_IF_NOT_EXISTS: typing.Final[int]
OPT_SCHEMA_FEATURES_IS_DATABASE: typing.Final[int]
OPT_SCHEMA_FEATURES_DROP_CASCADE: typing.Final[int]
OPT_SCHEMA_FEATURES_DROP_RESTRICT: typing.Final[int]
OPT_SCHEMA_FEATURES_UNSUPPORTED: typing.Final[int]
OPT_SCHEMA_LOCATION_STYLE_EXTERNAL_VOLUME: typing.Final[int]
OPT_SCHEMA_LOCATION_STYLE_LOCATION_KEYWORD: typing.Final[int]
OPT_SCHEMA_LOCATION_STYLE_MANAGED_LOCATION_KEYWORD: typing.Final[int]
OPT_SCHEMA_LOCATION_STYLE_UNSUPPORTED: typing.Final[int]
OPT_STRING_CONCAT_CONCAT_FUNCTION: typing.Final[int]
OPT_STRING_CONCAT_PIPES: typing.Final[int]
OPT_STRING_CONCAT_PLUS: typing.Final[int]
Expand All @@ -101,11 +113,11 @@ OPT_STRING_ESCAPE_QUOTE: typing.Final[int]
OPT_STRING_FORMAT_PREFIX_BIG_E: typing.Final[int]
OPT_STRING_FORMAT_PREFIX_BIG_N: typing.Final[int]
OPT_STRING_FORMAT_SINGLE_QUOTE: typing.Final[int]
OPT_TIME_FORMAT_KEYWORD: typing.Final[int]
OPT_TIME_FORMAT_QUOTED: typing.Final[int]
OPT_TIMESTAMP_FORMAT_QUOTED: typing.Final[int]
OPT_TIMESTAMP_FORMAT_TIMESTAMPTZ: typing.Final[int]
OPT_TIMESTAMP_FORMAT_WITH_TIMEZONE: typing.Final[int]
OPT_TIME_FORMAT_KEYWORD: typing.Final[int]
OPT_TIME_FORMAT_QUOTED: typing.Final[int]
OPT_TRIM_SPELLING_FUNCTION: typing.Final[int]
OPT_TRIM_SPELLING_SPACES_ONLY: typing.Final[int]
OPT_TRIM_SPELLING_SQL_FROM: typing.Final[int]
Expand Down Expand Up @@ -161,6 +173,9 @@ class Dialect:
is_distinct_from_spelling: int = ...,
trim_spelling: int = ...,
collate_spelling: int = ...,
schema_features: int = ...,
schema_authorization_style: int = ...,
schema_location_style: int = ...,
) -> typing.Self:
"""
Build a dialect from flags.
Expand Down Expand Up @@ -241,6 +256,12 @@ class Dialect:
def tuple_syntax(self) -> int: ...
@property
def uuid_format(self) -> int: ...
@property
def schema_features(self) -> int: ...
@property
def schema_authorization_style(self) -> int: ...
@property
def schema_location_style(self) -> int: ...
def write_boolean(self, value: bool) -> str:
"""
Write `value` as this dialect's boolean literal.
Expand Down
11 changes: 11 additions & 0 deletions src/ddl/mod.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,10 @@
//! Data Definition Language

mod schema;
pub use schema::DropSchemaBehavior;
pub use schema::PyCreateSchema;
pub use schema::PyDropSchema;

/// Base of every DDL statement. Construct a subclass, not this class.
#[rapidquery_macros::pyclass("rapidquery.ddl.DataDefinitionLanguage", subclass)]
#[derive(Debug, Clone, Copy)]
Expand All @@ -9,4 +14,10 @@ pub struct PyDataDefinitionLanguage;
pub mod ddl_mod {
#[pymodule_export]
use super::PyDataDefinitionLanguage;

#[pymodule_export]
use super::PyCreateSchema;

#[pymodule_export]
use super::PyDropSchema;
}
Loading
Loading