Skip to content

Commit

Permalink
Case conditions
Browse files Browse the repository at this point in the history
  • Loading branch information
Sibyx committed Nov 30, 2021
1 parent 3a9d231 commit cbd566a
Show file tree
Hide file tree
Showing 28 changed files with 386 additions and 144 deletions.
6 changes: 5 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,8 +1,12 @@
# Changelog

## 0.10.0 : 2021-11-30

- **Feature**: `Case` introduced (without docs, there was no time, sry, let's call it Easter Egg for a while)

## 0.9.1 : 2021-07-20

- **Fix**: Fixed problem with multiple properites in operations (I had to remove comparison property check)
- **Fix**: Fixed problem with multiple properties in operations (I had to remove comparison property check)

## 0.9.0 : 2021-06-25

Expand Down
3 changes: 2 additions & 1 deletion duckql/functions/avg.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,12 @@
from ..properties import Constant
from ..properties.property import Property
from ..structures.cast_operator import CastOperator
from ..structures.case import Case


class Avg(BaseFunction):
obj: Literal['functions.Avg'] = 'functions.Avg'
property: Union[Property, BaseFunction, Constant, CastOperator]
property: Union[Property, BaseFunction, Constant, CastOperator, Case]
alias: str = None

def to_sql(self) -> str:
Expand Down
3 changes: 2 additions & 1 deletion duckql/functions/concat.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,12 @@
from ..properties.property import Property
from ..properties.constant import Constant
from ..structures.cast_operator import CastOperator
from ..structures.case import Case


class Concat(BaseFunction):
obj: Literal['functions.Concat'] = 'functions.Concat'
properties: List[Union[Property, BaseFunction, Constant, CastOperator]]
properties: List[Union[Property, BaseFunction, Constant, CastOperator, Case]]
alias: str = None

def to_sql(self) -> str:
Expand Down
3 changes: 2 additions & 1 deletion duckql/functions/convert_timezone.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,12 @@
from ..properties.constant import Constant
from ..properties.property import Property
from ..structures.cast_operator import CastOperator
from ..structures.case import Case


class ConvertTimezone(BaseFunction):
obj: Literal['functions.ConvertTimezone'] = 'functions.ConvertTimezone'
property: Union[Property, BaseFunction, Constant, CastOperator]
property: Union[Property, BaseFunction, Constant, CastOperator, Case]
date_from: Constant
date_to: Constant
alias: str = None
Expand Down
3 changes: 2 additions & 1 deletion duckql/functions/count.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,11 +10,12 @@
from ..properties.property import Property
from ..structures.cast_operator import CastOperator
from ..structures.distinct import Distinct
from ..structures.case import Case


class Count(BaseFunction):
obj: Literal['functions.Count'] = 'functions.Count'
property: Union[Property, BaseFunction, Constant, CastOperator, Distinct]
property: Union[Property, BaseFunction, Constant, CastOperator, Distinct, Case]
alias: str = None

def to_sql(self) -> str:
Expand Down
3 changes: 2 additions & 1 deletion duckql/functions/date_add.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,11 +10,12 @@
from ..properties.property import Property
from ..structures.cast_operator import CastOperator
from ..structures.interval import Interval
from ..structures.case import Case


class DateAdd(BaseFunction):
obj: Literal['functions.DateAdd'] = 'functions.DateAdd'
property: Union[Constant, Property, BaseFunction, CastOperator]
property: Union[Constant, Property, BaseFunction, CastOperator, Case]
interval: Interval
alias: str = None

Expand Down
3 changes: 2 additions & 1 deletion duckql/functions/date_format.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,11 +11,12 @@
from ..properties.property import Property
from ..properties.constant import Constant
from ..structures.cast_operator import CastOperator
from ..structures.case import Case


class DateFormat(BaseFunction):
obj: Literal['functions.DateFormat'] = 'functions.DateFormat'
property: Union[Property, Constant, BaseFunction, CastOperator]
property: Union[Property, Constant, BaseFunction, CastOperator, Case]
format: str
alias: str = None

Expand Down
3 changes: 2 additions & 1 deletion duckql/functions/date_sub.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,11 +10,12 @@
from ..properties.property import Property
from ..structures.cast_operator import CastOperator
from ..structures.interval import Interval
from ..structures.case import Case


class DateSub(BaseFunction):
obj: Literal['functions.DateSub'] = 'functions.DateSub'
property: Union[Constant, Property, BaseFunction, CastOperator]
property: Union[Constant, Property, BaseFunction, CastOperator, Case]
interval: Interval
alias: str = None

Expand Down
3 changes: 2 additions & 1 deletion duckql/functions/extract.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
from ..properties.property import Property
from ..structures.cast_operator import CastOperator
from ..structures.interval import Interval
from ..structures.case import Case


class Extract(BaseFunction):
Expand Down Expand Up @@ -38,7 +39,7 @@ class Unit(Enum):
YEAR = 'year'

obj: Literal['functions.Extract'] = 'functions.Extract'
property: Union[Constant, Property, BaseFunction, Interval, CastOperator]
property: Union[Constant, Property, BaseFunction, Interval, CastOperator, Case]
unit: Unit
alias: str = None

Expand Down
3 changes: 2 additions & 1 deletion duckql/functions/group_concat.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,12 @@
from ..properties.constant import Constant
from ..properties.property import Property
from ..structures.cast_operator import CastOperator
from ..structures.case import Case


class GroupConcat(BaseFunction):
obj: Literal['functions.GroupConcat'] = 'functions.GroupConcat'
property: Union[Constant, Property, BaseFunction, CastOperator]
property: Union[Constant, Property, BaseFunction, CastOperator, Case]
alias: str = None

def to_sql(self) -> str:
Expand Down
3 changes: 2 additions & 1 deletion duckql/functions/initcap.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,12 @@
from ..properties import Constant
from ..properties.property import Property
from ..structures.cast_operator import CastOperator
from ..structures.case import Case


class InitCap(BaseFunction):
obj: Literal['functions.InitCap'] = 'functions.InitCap'
property: Union[Property, BaseFunction, Constant, CastOperator]
property: Union[Property, BaseFunction, Constant, CastOperator, Case]
alias: str = None

def to_sql(self) -> str:
Expand Down
3 changes: 2 additions & 1 deletion duckql/functions/lower.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,12 @@
from ..properties import Constant
from ..properties.property import Property
from ..structures.cast_operator import CastOperator
from ..structures.case import Case


class Lower(BaseFunction):
obj: Literal['functions.Lower'] = 'functions.Lower'
property: Union[Property, BaseFunction, Constant, CastOperator]
property: Union[Property, BaseFunction, Constant, CastOperator, Case]
alias: str = None

def to_sql(self) -> str:
Expand Down
5 changes: 3 additions & 2 deletions duckql/functions/min_max.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,12 @@
from ..functions.base import BaseFunction
from ..properties.property import Property
from ..structures.cast_operator import CastOperator
from ..structures.case import Case


class Max(BaseFunction):
obj: Literal['functions.Max'] = 'functions.Max'
property: Union[Property, BaseFunction, CastOperator]
property: Union[Property, BaseFunction, CastOperator, Case]
alias: str = None

def to_sql(self) -> str:
Expand All @@ -26,7 +27,7 @@ def to_sql(self) -> str:

class Min(BaseFunction):
obj: Literal['functions.Min'] = 'functions.Min'
property: Union[Property, BaseFunction, CastOperator]
property: Union[Property, BaseFunction, CastOperator, Case]
alias: str = None

def to_sql(self) -> str:
Expand Down
3 changes: 2 additions & 1 deletion duckql/functions/string_agg.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,11 +12,12 @@
from ..properties import Array
from ..properties.property import Property
from ..structures.cast_operator import CastOperator
from ..structures.case import Case


class StringAgg(BaseFunction):
obj: Literal['functions.StringAgg'] = 'functions.StringAgg'
property: Union[Property, BaseFunction, Array, CastOperator, Distinct]
property: Union[Property, BaseFunction, Array, CastOperator, Distinct, Case]
separator: str
alias: str = None

Expand Down
3 changes: 2 additions & 1 deletion duckql/functions/sum.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,12 @@
from ..functions.base import BaseFunction
from ..properties.property import Property
from ..structures.cast_operator import CastOperator
from ..structures.case import Case


class Sum(BaseFunction):
obj: Literal['functions.Sum'] = 'functions.Sum'
property: Union[Property, BaseFunction, CastOperator]
property: Union[Property, BaseFunction, CastOperator, Case]
alias: str = None

def to_sql(self) -> str:
Expand Down
3 changes: 2 additions & 1 deletion duckql/functions/to_char.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,11 +12,12 @@
from ..properties.constant import Constant
from ..structures.cast_operator import CastOperator
from ..structures.interval import Interval
from ..structures.case import Case


class ToChar(BaseFunction):
obj: Literal['functions.ToChar'] = 'functions.ToChar'
property: Union[Property, Constant, BaseFunction, CastOperator, Interval]
property: Union[Property, Constant, BaseFunction, CastOperator, Interval, Case]
format: str
alias: str = None

Expand Down
3 changes: 2 additions & 1 deletion duckql/functions/to_date.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,11 +11,12 @@
from ..properties.property import Property
from ..properties.constant import Constant
from ..structures.cast_operator import CastOperator
from ..structures.case import Case


class ToDate(BaseFunction):
obj: Literal['functions.ToDate'] = 'functions.ToDate'
property: Union[Property, Constant, BaseFunction, CastOperator]
property: Union[Property, Constant, BaseFunction, CastOperator, Case]
format: str
alias: str = None

Expand Down
3 changes: 2 additions & 1 deletion duckql/functions/unaccent.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,14 +9,15 @@
from ..properties import Constant
from ..properties.property import Property
from ..structures.cast_operator import CastOperator
from ..structures.case import Case


class Unaccent(BaseFunction):
"""
TODO: only in PostgreSQL
"""
obj: Literal['functions.Unaccent'] = 'functions.Unaccent'
property: Union[Property, BaseFunction, Constant, CastOperator]
property: Union[Property, BaseFunction, Constant, CastOperator, Case]
alias: str = None

def to_sql(self) -> str:
Expand Down
3 changes: 2 additions & 1 deletion duckql/functions/upper.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,12 @@
from ..properties import Constant
from ..properties.property import Property
from ..structures.cast_operator import CastOperator
from ..structures.case import Case


class Upper(BaseFunction):
obj: Literal['functions.Upper'] = 'functions.Upper'
property: Union[Property, BaseFunction, Constant, CastOperator]
property: Union[Property, BaseFunction, Constant, CastOperator, Case]
alias: str = None

def to_sql(self) -> str:
Expand Down
3 changes: 2 additions & 1 deletion duckql/functions/weekday.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,12 @@
from ..properties.property import Property
from ..properties.constant import Constant
from ..structures.cast_operator import CastOperator
from ..structures.case import Case


class Weekday(BaseFunction):
obj: Literal['functions.Weekday'] = 'functions.Weekday'
property: Union[Property, BaseFunction, Constant, CastOperator]
property: Union[Property, BaseFunction, Constant, CastOperator, Case]
alias: str = None

def to_sql(self) -> str:
Expand Down
4 changes: 3 additions & 1 deletion duckql/structures/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
from .between import Between
from .operator import Operator
from .cast_operator import CastOperator
from .case import Case

__all__ = [
"Join",
Expand All @@ -19,5 +20,6 @@
"Comparision",
"Between",
"Operator",
"CastOperator"
"CastOperator",
"Case"
]
42 changes: 42 additions & 0 deletions duckql/structures/case.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
from typing import List, Union, Optional

from pydantic import BaseModel

try:
from typing import Literal
except ImportError:
from typing_extensions import Literal

from ..base import BaseType
from ..properties.property import Property
from ..properties.constant import Constant
from ..structures.comparision import Comparision
from ..structures.operator import Operator
from ..functions.base import BaseFunction


class Case(BaseType):
# TODO: Docs!
class Condition(BaseModel):
when: Comparision
then: Union[BaseFunction, Property, Constant, Operator]

def __str__(self):
return f"WHEN {self.when} THEN {self.then}"

obj: Literal['structures.Case'] = 'structures.Case'
conditions: List[Condition]
alternative: Optional[Union[BaseFunction, Property, Constant]] = None
alias: str = None

def to_sql(self) -> str:
sql = "CASE " + " ".join(map(str, self.conditions))
if self.alternative:
sql = f"{sql} ELSE {self.alternative}"

sql = f"({sql} END)"

if self.alias is not None:
sql = f"{sql} AS {self.alias}"

return sql
3 changes: 2 additions & 1 deletion duckql/structures/query.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
from typing import List, Union

from .case import Case
from .cast_operator import CastOperator
from ..functions.base import BaseFunction
from pydantic import validator
Expand All @@ -25,7 +26,7 @@ class Config:

obj: Literal['structures.Query'] = 'structures.Query'
entity: Union[str, 'Query']
properties: List[Union[BaseFunction, Property, Distinct, CastOperator]]
properties: List[Union[BaseFunction, Property, Distinct, CastOperator, Case]]
joins: List[Join] = []
conditions: Union[Operator, Comparision] = None
having: Union[Operator, Comparision] = None
Expand Down
26 changes: 26 additions & 0 deletions duckql/structures/tests/test_case.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
from duckql.properties.property import Property
from duckql.properties.constant import Constant
from duckql.structures.comparision import Comparision
from duckql.structures.case import Case


def test_simple():
my_structure = Case(
conditions=[
Case.Condition(
when=Comparision(
properties=[
Property(name='transactions.direction'),
Constant(value='in')
],
operation=Comparision.Operation.EQUAL
),
then=Property(name='transactions.direction')
)
],
alternative=Constant(value=0),
alias='test_case'
)

sql = "(CASE WHEN (transactions.direction = 'in') THEN transactions.direction ELSE 0 END) AS test_case"
assert str(my_structure) == sql
2 changes: 1 addition & 1 deletion duckql/version.py
Original file line number Diff line number Diff line change
@@ -1 +1 @@
__version__ = '0.9.1'
__version__ = '0.10.0'
Loading

0 comments on commit cbd566a

Please sign in to comment.