3é±éã§DBMSãææããŸãã æ¯æ¥å°ãã®æéã建ç¯ã«è²»ããã ãã§ãã æ®ãã®æéã¯ãçµæã«ç±å¿ã«åãçµã¿ãæ°çŸè¡ã®ã³ãŒããå°å·ããŠåå
¥åããŸãã
ããŒãã£ãŒã®æ³åã«ãããšãéžæãããããžã§ã¯ããè€æ°ããå Žåã¯ãææ¡ãããŠãããããžã§ã¯ãã®ãã¡æãé£ãããã®ãåŒãåããŸãã ããã¯ãããŒã¿ããŒã¹ç®¡çã·ã¹ãã ïŒDBMSïŒã®ã³ãŒã¹ã®æåŸã®ã¿ã¹ã¯ã§çºçããŸããã
åé¡ã®å£°æ
äœæ¥æ瀺æžã«ãããšãVanilla Python 3.6ã§DBMSããŒãããäœæããå¿
èŠããããŸããïŒãµãŒãããŒãã£ã©ã€ãã©ãªãªãïŒã æçµè£œåã«ã¯æ¬¡ã®ããããã£ãå¿
èŠã§ãã
- ããŒã¿ããŒã¹ãåäžã®ãã¡ã€ã«ã«ãã€ããªåœ¢åŒã§ä¿åããŸã
- DDLïŒæŽæ°ãæµ®åãããã³å¯å€é·æåïŒNïŒã®3ã€ã®ããŒã¿åããµããŒãããŸãã ç°¡åã«ããããã«ããããã¯ãã¹ãŠåºå®é·ã§ãã
- DMLïŒåºæ¬çãªSQLæäœããµããŒãããŸãã
- æ¿å
¥
- æŽæ°
- åé€
- WHEREããã³JOINã䜿çšããSELECTã ã©ã®JOINã«æ£ç¢ºã«åå ãããã¯ç€ºãããŠããªããããCROSSãšINNERã®äž¡æ¹ãè¡ã£ãå Žåã«åããŠ
- 100'000ã¬ã³ãŒãã«èãã
èšèšã¢ãããŒã
DBMSããŒãããéçºããããšã¯ãéèŠãªã¿ã¹ã¯ã®ããã«æããŸããïŒå¥åŠãªããšã«ããã®ããã«ãªããŸããïŒã ãããã£ãŠãæã
-ecat3ãš
@ratijas-ã¯ãã®åé¡ã«ç§åŠçã«ã¢ãããŒãããŸããã ããŒã ã«ã¯2人ããããŸããïŒèªåèªèº«ãšç§ã®äººå¡ã¯èæ
®ããŠããŸããïŒãã€ãŸããã¿ã¹ã¯ãå®éã«å®è¡ããããããã¿ã¹ã¯ã調æŽããŠå®è£
ã調æŽããæ¹ãã¯ããã«ç°¡åã§ãã ã«ããã®çµããã«ã次ã®ããšãèµ·ãããŸããã
ææŠãã | è«è² æ¥è
|
---|
ããŒãµãŒ+ AST + REPL | ratijasãããããçš®é¡ã®lex / yaccã«ã€ããŠè€æ°ã®èšç®æ©ãæžãã |
åºæ¬ãã¡ã€ã«æ§é | ãã¡ã€ã«ã·ã¹ãã ã§ecat3ãé£ã¹ãç¬ |
ãšã³ãžã³ ïŒäœã¬ãã«ã®ããŒã¿ããŒã¹æäœïŒ | ecat3 |
ã€ã³ã¿ãŒãã§ãŒã¹ ïŒé«ã¬ãã«ã®æ¥çïŒ | äžç·ã« |
åœåã¯2é±éãå²ãåœãŠãããŠãããããåã
ã®ã¿ã¹ã¯ã1é±éã§å®äºããããšã«ãªã£ãŠãããæ®ãã®æéã¯å
±åã§æ¥çãšãã¹ãã«å
ãŠãããŸãã
æ£åŒãªéšåãçµäºããããå®çšã«ç§»ããŸãããã DBMSã¯ææ°ãã€é©åãªãã®ã§ãªããã°ãªããŸããã çŸä»£ã®ã€ãããªã¹ã§ã¯ããã¬ã°ã©ã ã®ã¡ãã»ã³ãžã£ãŒããã£ããããããããã³ã/ã¹ã©ãã·ã¥ã¿ã°ãã䜿çšããã°ã«ãŒãéä¿¡ãé¢é£ããŠããŸãïŒããã¯ïŒããã·ã¥ã¿ã°ã®ãããªãã®ã§ã/ã¹ã©ãã·ã¥ã§å§ãŸããŸãïŒã ãããã£ãŠãSQLã«ãã䌌ãã¯ãšãªèšèªã§ã¯å€§æåãšå°æåãåºå¥ãããªãã ãã§ãªãã倧æåãšå°æåãåºå¥ãããŸããã ããã«ã倧åŠçãšåæ§ã«ãåèšèªã®ã¹ããŒãã¡ã³ãïŒã¹ããŒãã¡ã³ãïŒã¯ã/ãããããã§çµããå¿
èŠããããŸãã ïŒãã¡ãããç»é²ç°¿ã«é¢ä¿ãªãããã®ãããªç¶æ³ã§äžè¬çã«èª°ãããã®ç»é²ç°¿ãæ°ã«ããŸããïŒïŒ
å
žåçãª/æ¥äž/ãã£ãã ããã§ãååã®ã¢ã€ãã¢ãçãŸããŸããïŒ
dropSQL ã å®éã«
/ãããã 'thã¯ã倧åŠããã®åŠçã®è¿œæŸãšåŒã°ããŠããŸãã äœããã®çç±ã§ããã®èšèã¯ç§ãã¡ã®ã€ãããªã¹ã§åºãŸã£ãŠããŸãã ïŒå¥ã®å±æçŸè±¡ïŒèªéçããŸãã¯ããæ£ç¢ºã«ã¯ã/èªéçãããããç§ãã¡ã¯ç¹å¥ãªã±ãŒã¹ã®ããã«ãããäºçŽããŸãããïŒ
ãŸããdropSQLææ³ãBNFã«å解ããŸããïŒãããŠãç¡é§ãªããšã«ãå·Šååž°ã¯éé ããŒãµãŒã«ã¯é©ããŠããŸããïŒã
BNFææ³dropSQLå®å
šçã¯ãã¡ã/stmt : /create_stmt | /drop_stmt | /insert_stmt | /update_stmt | /delete_stmt | /select_stmt ; /create_stmt : "/create" "table" existence /table_name "(" /columns_def ")" "/drop" ; existence : /* empty */ | "if" "not" "exists" ; /table_name : /identifier ; /columns_def : /column_def | /columns_def "," /column_def ; /column_def : /column_name type /primary_key ; ...
補åãªã³ã©ã€ã³ãã«ãã®æå¹ãªdropSQLã³ãã³ãã®äŸ /create table t(a integer, b float, c varchar(42)) /drop /insert into t (a, c, b) values (42, 'morty', 13.37), (?1, ?2, ?3) /drop /select *, a, 2 * b, c /as d from t Alias /where (a < 100) /and (c /= '') /drop /update t set c = 'rick', a = a + 1 /drop /delete from t where c > 'r' /drop /drop table if exists t /drop
ç§ãã¡ã¯çµæã®ããã«åããŸãïŒ äŸå€ãªãïŒ
Rustãã¡ã€ã³èšèªãšããŠæ°ã¶æéãããåŸãç§ã¯æ¬åœã«äŸå€åŠçã§åã³è¡ãè©°ãŸããããããŸããã§ããã äŸå€ã«å¯Ÿããæçœãªè°è«ã¯ãããããæããã®ã«è²»çšãããããšããããšã§ããããã£ããã¯æ±ãã«ããã§ãã Pythonã¯ãJavaèªäœãšã¯ç°ãªããType AnnotationsãåããããŒãžã§ã³3.6ã§ããã¡ãœããããé£ã³åºãå¯èœæ§ã®ããäŸå€ã®ã¿ã€ããæå®ã§ããªããšããäºå®ã«ãã£ãŠç¶æ³ãæªåããŠããŸãã ã€ãŸããã¡ãœããã®ã·ã°ããã£ãèŠããšãã¡ãœããã«äœãæåŸ
ã§ããããæããã«ãªãã¯ãã§ãã ããã§ã¯ããããã®ã¿ã€ãããenum ErrorããšåŒã°ãã1ã€ã®å±æ ¹ã®äžã§çµã¿åãããŠã¿ãŸããã ãããŠãã®äžã«ãResultãšããå¥ã®ãå±æ ¹ããäœæããŸãã 以äžã§èª¬æããŸãã ãã¡ãããæšæºã©ã€ãã©ãªã«ã¯ãççºãã§ããå ŽæããããŸãã ããããã³ãŒãå
ã®ãã®ãããªåŒã³åºãã¯ããã¹ãŠã®åŽããtry'iã«ãã£ãŠç¢ºå®ã«èª²ãããŸããããã«ãããäŸå€ãæžãããŠãšã©ãŒãè¿ããããå®è¡äžã®ç·æ¥äºæ
ã®çºçãæå°éã«æããããŸãã
ãã®ãããçµæã®ä»£æ°åïŒhelloãRustïŒãèªè»¢è»ã«ä¹ããããšã決å®ãããŸããã 代æ°åã®pythonã§ã¯ããã¹ãŠãæªãã§ãã æšæºã®
enumã©ã€ãã©ãªã®ã¢ãžã¥ãŒã«ã¯ãããããªå°è
žã®ãããªãã®ã§ãã
ææªã®OOPã®äŒçµ±ã§ã¯ãç¶æ¿ã䜿çšããŠçµæã³ã³ã¹ãã©ã¯ã¿ãŒOkãšErrãå®çŸ©ããŸãã ãããŠãéçåä»ããå¿ããªãã§ãã ããïŒ
ãŸããç§ã¯ãã§ã«3çªç®ã®ããŒãžã§ã³ãæã£ãŠããŸãïŒæçµçã«Pythonã§éçåä»ããããŠãããã§ããïŒ ïŒïŒ
result.py import abc from typing import * class Result(Generic[T, E], metaclass=abc.ABCMeta): """ enum Result< T > { Ok(T), Err(E), } """
ãããïŒ æ©èœçãªå€æããäœãããå°ããªãœãŒã¹ã§å³ä»ãããŸãã ãã¹ãŠãå¿
èŠãªããã§ã¯ãããŸããã®ã§ãå¿
èŠæå°éããšã£ãŠãã ããã
result.pyïŒç¶ãïŒ class Result(Generic[T, E], metaclass=abc.ABCMeta): ... def ok_or(self, default: T) -> T: ... def err_or(self, default: E) -> E: ... def map(self, f: Callable[[T], U]) -> 'Result[U, E]':
ãããŠããã«äœ¿çšäŸïŒ
çµæã®äŸ def try_int(x: str) -> Result[int, str]: try: return Ok(int(x)) except ValueError as e: return Err(str(e)) def fn(arg: str) -> None: r = try_int(arg)
ãã®ã¹ã¿ã€ã«ã§ã®èœæžãã¯ãåãââã£ã¬ã³ãžã«å¯ŸããŠ3è¡å¿
èŠã§ãã ãããããã®åŸãã©ã®ãšã©ãŒãçºçããå¯èœæ§ããããã©ã®ãããªãšã©ãŒãçºçããããæ確ã«ç解ã§ããŸãã ããã«ãã³ãŒãã¯åãã¬ãã«ã®ãã¹ãã§ç¶ç¶ãããŸãã ã¡ãœããã«åããŒã¹ã®åçš®ã®åŒã³åºããå«ãŸããå Žåãããã¯éåžžã«éèŠãªå質ã§ãã
ããŒãµãŒãIResultããšã©ãŒ:: {空ãäžå®å
šãæ§æ}ãREPLã9600ããŒããã¹ãŠãã¹ãŠ
ããŒãµãŒã¯éçºæéã®ããªãã®éšåãå ããŸããã é©åã«èšèšãããããŒãµãŒã¯ã補åã®ããã³ããšã³ãã䜿çšããå©äŸ¿æ§ããŠãŒã¶ãŒã«æäŸããå¿
èŠããããŸãã ããŒãµãŒã®æãéèŠãªã¿ã¹ã¯ã¯æ¬¡ã®ãšããã§ãã
- ãšã©ãŒå ±åãã¯ãªã¢ãã
- ã€ã³ã¿ã©ã¯ãã£ããªã€ã³ã¯ãªã¡ã³ã¿ã«ã©ã€ã³å
¥åããŸãã¯ããåçŽã«REPL
ãå
šäœã®ãæšæºPythonã©ã€ãã©ãªã ãã§ãªããããŒãµãŒäœæã®æ§ãããªç¥èããããããè¢ããŸããäžããŠæåã®ååž°äžéããŒãµãŒïŒEngãRecursive descent parserïŒãäœæããå¿
èŠãããããšã«æ°ä»ããŸããã ããã¯é·ãéå±ãªããžãã¹ã§ãããç¶æ³ãé«åºŠã«å¶åŸ¡ã§ããŸãã
çããããã¹ãæåã®è³ªåã®1ã€ïŒééããã©ããããïŒ ã©ããªãã-ãã§ã«äžã§èãåºããã ããããééãã¯äœã§ããïŒ ããšãã°ãã/ create tableãã®åŸã«ãif not existsããååšããå Žåãããã°ãååšããªãå ŽåããããŸã-ããã¯ééãã§ããïŒ ãããããªããã©ã®ãããªïŒ ã©ãã§åŠçããå¿
èŠããããŸããïŒ ïŒãäžæåæ¢ãããã³ã¡ã³ãã§ãªãã·ã§ã³ãææ¡ããŸããïŒ
ããŒãµãŒ
ã®æåã®ããŒãžã§ã³ã¯ã 2ã€ã®ã¿ã€ãã®ãšã©ãŒãåºå¥ããŸããïŒäºæãããïŒ1ã€ãæåŸ
ããŸãããäœãä»ã®ãã®ãåãåããŸããïŒããã³EOFïŒãã¡ã€ã«ã®çµããïŒåã®ãµãã¯ã©ã¹ãšããŠã REPLã«å°éãããŸã§ã¯ããã¹ãŠåé¡ãããŸããã ãã®ãããªããŒãµãŒã¯ãéšåçãªå
¥åïŒã³ãã³ãã®éå§ïŒãšäœãååšããªãããšïŒEOFã端æ«ããã®å¯Ÿè©±åå
¥åã«ã€ããŠèšãã°ïŒãåºå¥ããŸããã ããã1é±éåŸãè©Šè¡é¯èª€ãç¹°ãè¿ããŠããã¡ã€ã³é åãæºããã¹ããŒã ãèŠã€ããããšãã§ããŸããã
ã¹ããŒã ã¯ããã¹ãŠãã¹ããªãŒã ã§ãããããŒãµãŒã¯ã¹ããªãŒã äžã®ãããããª
nextïŒïŒã¡ãœããã§ãããšãããã®ã§ãã ãŸãããšã©ãŒã¯ã©ã¹ã¯ïŒResultãªã©ã®ïŒä»£æ°ã«æžãæããå¿
èŠãããã
EOFã®ä»£ããã«
Emptyãªãã·ã§ã³ãš
Incompleteãªãã·ã§ã³ãå°å
¥ãããŸãã
æ°ããã¿ã€ãã®ãšã©ãŒ class Error(metaclass=abc.ABCMeta): """ enum Error { Empty, Incomplete, Syntax { expected: str, got: str }, } """ def empty_to_incomplete(self) -> 'Error': if isinstance(self, Empty): return Incomplete() else: return self class Empty(Error): ... class Incomplete(Error): ... class Syntax(Error): def __init__(self, expected: str, got: str) -> None: ...
ã¹ããªãŒã ã€ã³ã¿ãŒãã§ãŒã¹ class Stream(Generic[T], metaclass=abc.ABCMeta): def current(self) -> IResult[T]: ... def next(self) -> IResult[T]: ... def collect(self) -> IResult[List[T]]: ... def peek(self) -> IResult[T]: ... def back(self, n: int = 1) -> None: ... @abc.abstractmethod def next_impl(self) -> IResult[T]: ...
ãããŒã¯æœè±¡åã§ãã ã¹ããªãŒã ã¯ãã©ã®èŠçŽ ãçæããããæ°ã«ããŸããã ã¹ããªãŒã ã¯ãã€åæ¢ããããç¥ã£ãŠããŸãã ã¹ããªãŒã ãå®è£
ããããã«å¿
èŠãªããšã¯ãæœè±¡ã¡ãœãã
next_implïŒïŒ-> IResult [T]ã®ã¿ãæžãæããããšã§ãã ãã®ã¡ãœãããè¿ããã®ã¯äœã§ããïŒ ããŒã¯ã³ã¹ããªãŒã ã®äŸãèããŠã¿ãŸãããã
次ã¯äœã§ãã | äŸïŒå
¥åïŒ | çµæã¿ã€ã | äŸïŒçµæïŒ |
---|
ãã¹ãŠãããŸããããå¥ã®èŠçŽ | / tããåé€... | IOkïŒããŒã¯ã³ïŒ | IOkïŒåé€ïŒïŒïŒ |
ã®ã£ãããšã³ã¡ã³ãã®ã¿ãæ®ã£ãŠããŸã | \ n-ã¯ã
-ã«ã
-ããããïŒ | IErrïŒç©ºïŒïŒïŒ | IErrïŒç©ºïŒïŒïŒ |
ãã£ãšäœãã®å§ãŸã | 'æåå... ïŒéãåŒçšç¬ŠãªãïŒ | IErrïŒäžå®å
šïŒïŒïŒ | IErrïŒäžå®å
šïŒïŒïŒ |
ããªãã¯ç§ã«ããã€ãã®ã²ãŒã ãããã | ïŒ$ïŒ
| IErrïŒæ§æïŒ...ïŒïŒ | IErrïŒæ§æïŒexpected = 'token'ãgot = 'ïŒ'ïŒïŒ |
ã¹ããªãŒã ã¯
éå±€æ§é ã«ãªã£ãŠã
ãŸã ã åã¬ãã«ã«ã¯ç¬èªã®ãããã¡ãŒãå«ãŸããŠãããå¿
èŠã«å¿ããŠå
èªã¿ïŒ
peekïŒïŒ-> IResult [T] ïŒããã³ããŒã«ããã¯ïŒ
backïŒnïŒint = 1ïŒ-> None ïŒãå¯èœã§ãã
ãããŠãæè¯ã®éšåã¯ãã¹ããªãŒã ããã¹ãŠã®
IOkïŒèŠçŽ
ïŒã® 1ã€ã®å€§ããªãªã¹ãã«ã
ã¢ã»ã³ãã« ãã§ããããšã§ããããã«ããã
nextïŒïŒ -ãã¡ããæåã®
IErrïŒïŒãŸã§ãåŸãããŸãã
IErrã«
Emptyãå«ãŸããŠããå Žåã«ã®ã¿ããªã¹ãã¯äœãè¿ããŸããã ããã§ãªãå Žåããšã©ãŒã¯ããé«ãã¹ããŒãããŸãã ãã®èšèšã«ãããREPLãç°¡åãã€ãšã¬ã¬ã³ãã«æ§ç¯ã§ããŸãã
REPL Foundation class Repl: def reset(self): self.buffer = '' self.PS = self.PS1 def start(self): self.reset() while True: self.buffer += input(self.PS) self.buffer += '\n' stmts = Statements.from_str(self.buffer).collect() if stmts.is_ok(): ...
ãã£ã©ã¯ã¿ãŒ
ãã®ã¹ããªãŒã ã¯ãæååã®æåãééããŸãã å¯äžã®ã¿ã€ãã®ãšã©ãŒïŒè¡ã®æåŸã
空ã§ãã
ããŒã¯ã³
ããŒã¯ã³ãããŒã 圌ã®ããã«ããŒã ã¯ã¬ã¯ãµãŒã§ãã ãšã©ãŒãéãåŒçšç¬Šã®ãªãè¡ãããã³ãã¹ãŠããããŸã...
åããŒã¯ãŒããåå¥ã«å«ãããŒã¯ã³ã®åã¿ã€ãã¯ãæœè±¡ããŒã¯ã³ã¯ã©ã¹ã®åå¥ã®ããªã¢ã³ãã¯ã©ã¹ã§è¡šãããŸãïŒãŸãã¯ãåæåããŒã¯ã³ãšèããæ¹ãããã§ããããïŒïŒããã¯ãã¹ããŒãã¡ã³ãããŒãµãŒãããŒã¯ã³ãç¹å®ã®ã¿ã€ãã«ãã£ã¹ãããã®ã«äŸ¿å©ã§ãã
å
žåçãªåå¥è§£æéš def next_impl(self, ...) -> IResult[Token]: ... char = self.characters.current().ok() if char == ',': self.characters.next() return IOk(Comma()) elif char == '(': self.characters.next() return IOk(LParen()) elif ...
声æ
ã¯ã©ã€ããã¯ã¹ãããŒãµãŒã æ°åã®åèªã®ä»£ããã«ãããã€ãã®ã¹ããããïŒ
ã¹ããªãŒã /statements.py class Statements(Stream[AstStmt]): def __init__(self, tokens: Stream[Token]) -> None: super().__init__() self.tokens = tokens @classmethod def from_str(cls, source: str) -> 'Statements': return Statements(Tokens.from_str(source)) def next_impl(self) -> IResult[AstStmt]: t = self.tokens.peek() if not t: return Err(t.err()) tok = t.ok() if isinstance(tok, Create): return CreateTable.from_sql(self.tokens) if isinstance(tok, Drop): return DropTable.from_sql(self.tokens) if isinstance(tok, Insert): return InsertInto.from_sql(self.tokens) if isinstance(tok, Delete): return DeleteFrom.from_sql(self.tokens) if isinstance(tok, Update): return UpdateSet.from_sql(self.tokens) if isinstance(tok, Select): return SelectFrom.from_sql(self.tokens) return Err(Syntax('/create, /drop, /insert, /delete, /update or /select', str(tok)))
ast / delete_from.py class DeleteFrom(AstStmt): def __init__(self, table: Identifier, where: Optional[Expression]) -> None: super().__init__() self.table = table self.where = where @classmethod def from_sql(cls, tokens: Stream[Token]) -> IResult['DeleteFrom']: """ /delete_stmt : "/delete" "from" /table_name /where_clause /drop ; """
REPLãæ£ããæ©èœããããã«ã¯ãæåã®ããŒãµãŒãé€ããã¿ã€ãã
Emptyã®ãšã©ãŒã¯ãã¹ãŠããŒãµãŒã
Incompleteã«å€æããå¿
èŠãããããšã«æ³šæããããšãéèŠã§ãã ããã«ã¯è£å©é¢æ°
empty_to_incompleteïŒïŒ-> ErrorããããŸã ã ãã¯ãã§ã¯ãããŸããããã¯ã
ã¯ãããŸãããtïŒif IErrïŒt.errïŒïŒãEmpty_to_incompleteïŒïŒïŒã¯ãã³ãŒãããŒã¹ã§å°ãªããšã50åçºçããäœãå®è¡ãããŸããã çå£ã«ãããæç¹ã§ãSyshnyããªããã»ããµã䜿çšãããã£ãã®ã§ãã
ãããã€ããªåœ¢åŒ
ã°ããŒãã«ã«ãããŒã¿ããŒã¹ãã¡ã€ã«ã¯ãããã¯ã«åå²ããããã¡ã€ã«ãµã€ãºã¯ãããã¯ã®ãµã€ãºã®åæ°ã«ãªããŸãã ããã©ã«ãã®ãããã¯ãµã€ãºã¯12 KiBã§ããããªãã·ã§ã³ã§18ã24ããŸãã¯36 KiBã«å¢ããããšãã§ããŸãã ããªããéè¡ã®æªé䞻矩è
ã§ãããããªããéåžžã«å€§ããªããŒã¿ãæã£ãŠãããªããããªãã¯ããã42 KiBãŸã§äžããããšããã§ããŸãã
ãããã¯ã«ã¯æåããçªå·ãä»ããããŸãã ãŒããããã¯ã«ã¯ãããŒã¿ããŒã¹å
šäœã«é¢ããã¡ã¿ããŒã¿ãå«ãŸããŠããŸãã ãã®èåŸã«ã¯ãããŒãã«ã¡ã¿ããŒã¿çšã®16ãããã¯ããããŸãã ãããã¯ïŒ17ã¯ããŒã¿ãããã¯ã§å§ãŸããŸãã
ãããã¯ãžã®ãã€ã³ã¿ã¯ã
ãããã¯ã·ãŒã±ã³ã¹çªå·ãšåŒã°ããŸãã
çŸåš
ãããŒã¿ããŒã¹ã¡ã¿ããŒã¿ã¯ããã»ã©å€ã
ã¯ãããŸãããååã¯æ倧256ãã€ãã§ãããŒã¿ãããã¯ã®æ°ã§ãã
ããŒãã«ã®ã¡ã¿ãããã¯ã¯æãå°é£ã§ãã ããã«ã¯ãããŒãã«ã®ååããã¹ãŠã®åãšãã®ã¿ã€ãã®ãªã¹ããã¬ã³ãŒãæ°ãããã³ããŒã¿ãããã¯ãžã®ãã€ã³ã¿ãŒãä¿åãããŸãã
ããŒãã«ã®æ°ã¯ã³ãŒãã§åºå®ãããŠããŸãã ãã ããããŒã¿ããŒã¹ã®ã¡ã¿ãããã¯ã«ããŒãã«ã®ã¡ã¿ãããã¯ãžã®ãã€ã³ã¿ãæ ŒçŽãããšãããã¯æ¯èŒçç°¡åã«ä¿®æ£ã§ããŸãã
ãããã¯ãžã®
ãã€ã³ã¿ã¯ãiããŒãå
ã®
ãã€ã³ã¿ã®åçã§æ©èœã
ãŸã ã Tanenbaumãšä»ã®äœå人ãã®å°æ¬ããã人ã
ã¯ããã®ããšã«ã€ããŠçŸããæžããŸããã ãããã£ãŠãããŒãã«ã¯ããŒã¿ãããã¯ããããŒãžããšèŠãªããŸãã éãã¯ãããŒãã«ã®èŠ³ç¹ããé çªã«æ¥ãããŒãžããç¥ãéã眮ãããã«ãã¡ã€ã«å
ã«ç©ççã«é
眮ãããããšã§ãã OSã®ä»®æ³ã¡ã¢ãªãšã®é¡äŒŒæ§ã®æç»ãããŒãžïŒä»®æ³ããŒãžçªå·ããããã¯ïŒç©çããŒãžçªå·ã
ããŒã¿ãããã¯èªäœã«ã¯ç¹å®ã®æ§é ã¯ãããŸããã ãããããã€ã³ã¿ã«ãã£ãŠæ瀺ãããé åºã§çµåããããšãåºå®é·ã®ã¬ã³ãŒãïŒã¬ã³ãŒã/ã¿ãã«ïŒã®é£ç¶ã¹ããªãŒã ãšããŠè¡šç€ºãããŸãã ãããã£ãŠãã¬ã³ãŒãã®ã·ãªã¢ã«çªå·ãç¥ãããããæœåºãŸãã¯æžã蟌ãããšã¯ãã»ãŒäžå®æéOïŒ1
* ïŒã®æäœã§ãããå¿
èŠã«å¿ããŠæ°ãããããã¯ã®å²ãåœãŠãæžäŸ¡ããŸãã
ã¬ã³ãŒãã®æåã®ãã€ãã«ã¯ããã®ã¬ã³ãŒããçããŠãããåé€ããããã«é¢ããæ
å ±ãå«ãŸããŠããŸãã ããŒã¿ã®ããã¯ãšã¢ã³ããã¯ã«é¢ããæ®ãã®äœæ¥ã¯ãæšæºã®
structã¢ãžã¥ãŒã«ã«ãã£ãŠè¡ãããŸãã
/æŽæ°æäœã¯åžžã«ãã€ã³ãã¬ãŒã¹ããäžæžããã/ deleteã¯æåã®ãã€ãã®ã¿ã眮ãæããŸãã VACUUMæäœã¯ãµããŒããããŠããŸããã
ããŒãã«æäœãRowSetãããã³çµåã«ã€ããŠ
ããŒãã®ããã€ãã®ããã§2ã€ã®äžçã®ãã¹ãããã£ãããšåºå®ããæã§ãã
å·ŠåŽã®MC -ASTãããã¬ãã«ããŒãïŒAstStmtãµãã¯ã©ã¹ïŒã ãããã®å®è¡ã¯ãããŒã¿ããŒã¹ãžã®æ¥ç¶ã®ã³ã³ããã¹ãã§çºçããŸãã äœçœ®åŒæ°ããµããŒããããŠããŸã-ãªã¯ãšã¹ãæ¬æã®åŒã«ãããïŒNãããŒã¯ã³ãããšãã°ãã/ delete from student / where name =ïŒ1 / dropãã
åŒèªäœã¯ååž°çã§ããããã®èšç®ã¯ç§åŠçãªãã¬ãŒã¯ã¹ã«ãŒãæ§æããŸããã
å³åŽã®MCã¯ãããŒãã«å
ã®ã·ãŒã±ã³ã¹çªå·ãèå¥åãšããŠäœ¿çšããŠãã¬ã³ãŒãã1ã€ãã€æäœããããŒã¿ããŒã¹ãã©ã€ããŒã§ãã 圌ãç¥ã£ãŠããã®ã¯ãã©ã®ããŒãã«ãååšããã©ã®ããã«ããŒãã«ãæäœããããç¥ã£ãŠããããšã ãã§ãã
è¡ããïŒ
åµé æ§ã«é¢ãã圌ãã®æåã®å
±åã·ã³ã°ã«ã æ°ããããŒãã«ãäœæããã®ã¯ãæåã®ç©ºã®èšè¿°åã§ãã16ãèŠã€ããŠããã«ååãšåã®ãªã¹ããå
¥åããã®ãšåããããç°¡åã§ãã
次ã«ãã·ã³ããªãã¯å
/ããããã®ãã©ãã¯ã ãã¢ã¬ã³ãŒãã®ããŒã ããŒãžã§ã³ã§ã¯ã次ã®ããšãèµ·ãããŸãã1ïŒååã§ããŒãã«èšè¿°åãèŠã€ããŸãã 2ïŒãŒãã«ãªã»ããããŸãã 誰ãããŒã¿ããŒãžã®æªãªãªãŒã¹ãããã¯ãæ°ã«ããŸããïŒ
æ¿å
¥ã¯åã®é åºã«éåããŠãããããæžã蟌ã¿çšã®ã¿ãã«ãéä¿¡ããåã«ãç¹å¥ãªãã£ã«ã¿ãŒ
transition_vectorãééããŸãã
ããã«ãããŒãã«ãšã³ããªã®æäœã«ã€ããŠèª¬æããŸãã®ã§ãããã«å¯©å€
RowSetã玹ä»ããŸãã
ç空äžã®çç¶RowSet class RowSet(metaclass=abc.ABCMeta): @abc.abstractmethod def columns(self) -> List[Column]: """ Describe columns in this row set. """ @abc.abstractmethod def iter(self) -> Iterator['Row']: """ Return a generator which yields rows from the underlying row stream or a table. """
ãã®ç£ã®äž»ãªç¹å®ã®äºçš®
-TableRowSet-ã¯ããã¹ãŠã®ã©ã€ãïŒåé€ãããŠããªãïŒã¬ã³ãŒããé çªã«éžæããŸãã dropSQLã®ä»ã®çš®é¡ã®RowSetã¯ãå¿
èŠãªæå°ã®
é¢ä¿ä»£æ°ãå®è£
ããŸãã
é¢ä¿ä»£æ°æŒç®å | æå® | ã¯ã©ã¹ |
---|
æ圱 | Ï ïŒIDãNAMEïŒ expr | ProjectionRowSet |
ååãå€æŽ | Ïa / b expr | ProjectionRowSet +
RenameTableRowSet |
ãµã³ããªã³ã° | Ï ïŒPRICE> 90ïŒ expr | FilteredRowSet |
ãã«ã«ãç© | 補åÃ販売è
| CrossJoinRowSet |
å
éšçµå ïŒæ¡åŒµæ©èœãšåŒã³ãŸãïŒ | Ï ïŒæ¡ä»¶ïŒ ïŒA x BïŒ | InnerJoinRowSet =
FilteredRowSetïŒ
CrossJoinRowSetïŒ...ïŒïŒ |
ããã«ãããã°ã©ã å¯èœãªMockRowSetããããŸãã ãã¹ãã«é©ããŠããŸãã ãŸãããã®å©ããåããŠãã
/ autism ããšåŒã°ãã
ãã¹ã¿ãŒããŒãã«ã«ã¢ã¯ã»ã¹ã§ããŸãã
çŸããã¯ãããŸããŸãªRowSetsãèªç±ã«çµã¿åãããããšãã§ããããšã§ãããåŠçãããŒãã«ãéžæãããšã€ãªã¢ã¹ãSããæå®ããã/ where scholarship> '12k'ããé€å€ããå¥ã®ããŒãã«ãcoursesããéžæããã/ onïŒcourse / sid = S / idïŒ/ andïŒcourse / grade <'B'ïŒ "ãproject into" S / idãS / first_name / as / name "-ããã¯æ¬¡ã®éå±€ã§è¡šãããŸãã
ProjectionRowSet([S/id, S/first_name/as/name]) FilteredRowSet((course/sid = S/id) /and (course/grade < 'B')) CrossJoinRowSet FilteredRowSet(scholarship > '12k') RenameTableRowSet('S') TableRowSet('student') TableRowSet('courses')
ãã®ããããã®ãããªåŒ·åãªæ¥œåšãè£
åããŠã16äžçŽã®ãªã¥ãŒãé³æ¥œã«æ»ããŸã...
4çªç®ã®ãã©ãã¯
/ selectã«ã€ããŠããã以äžè¿œå ãããã®ã¯ãããŸããã RowSetsã®äº€é¿æ²ã¯ãéãé
äºãããããªãã®ã§ãã ããã«ãããå®è£
ã¯éåžžã«ç°¡æœã«ãªããŸããã
å®è£
/éžæ...ãã class SelectFrom(AstStmt): ... def execute(self, db: 'fs.DBFile', args: ARGS_TYPE = ()) -> Result['RowSet', str]: r = self.table.row_set(db) if not r: return Err(r.err()) rs = r.ok() for join in self.joins: r = join.join(rs, db, args) if not r: return Err(r.err()) rs = r.ok() if self.where is not None: rs = FilteredRowSet(rs, self.where, args) rs = ProjectionRowSet(rs, self.columns, args) return Ok(rs)
æåŸã®2ã€ïŒ
/ updateããã³
/ deleteã¯ãåä»»è
ã®å®çžŸã䜿çšããŸãã ããã«ã/ updateã¯ãäžèšã®transition_vectorã«äŒŒãææ³ã䜿çšããŸãã
ãããªã³ã³ãµãŒãïŒ ãæž
èŽããããšãããããŸããïŒ ã«ãŒãã³ïŒ..
ãŠã£ãã·ã¥ãªã¹ã
ãŸã å®çŸããŠããªã倢ïŒ
- ãµããŒã/ããŒãµãŒã ãã§ãªãäž»ããŒ
- åé
æŒç®å
- ãã¹ããããã¯ãšãª
- åŒã®åæšè«
- Pythonçšã®äŸ¿å©ãªAPI
ããã¯ãã¬ãŒãã³ã°ãããžã§ã¯ãã§ãã£ããããç§ãã¡ã¯ããã«å¯ŸããŠãããŒãåŸãããšãã§ããŸããã§ããã ããããslocã®çµ±èšããå€æãããšã圌ãã¯ä»ã§ã¯èµ€ãã£ãã¢ãé£ã¹ãããšãã§ããŸããã
Sloccountã¬ããŒã Have a non-directory at the top, so creating directory top_dir Creating filelist for dropSQL Creating filelist for tests Creating filelist for util Categorizing files. Finding a working MD5 command.... Found a working MD5 command. Computing results. SLOC Directory SLOC-by-Language (Sorted) 2764 dropSQL python=2764 675 tests python=675 28 util python=28 Totals grouped by language (dominant language first): python: 3467 (100.00%) Total Physical Source Lines of Code (SLOC) = 3,467 Development Effort Estimate, Person-Years (Person-Months) = 0.74 (8.85) (Basic COCOMO model, Person-Months = 2.4 * (KSLOC**1.05)) Schedule Estimate, Years (Months) = 0.48 (5.73) (Basic COCOMO model, Months = 2.5 * (person-months**0.38)) Estimated Average Number of Developers (Effort/Schedule) = 1.55 Total Estimated Cost to Develop = $ 99,677 (average salary = $56,286/year, overhead = 2.40). SLOCCount, Copyright (C) 2001-2004 David A. Wheeler SLOCCount is Open Source Software/Free Software, licensed under the GNU GPL. SLOCCount comes with ABSOLUTELY NO WARRANTY, and you are welcome to redistribute it under certain conditions as specified by the GNU GPL license; see the documentation for details. Please credit this data as "generated using David A. Wheeler's 'SLOCCount'."
è¬èŸ
- ã€ãããªã¹å€§åŠã®å±
å¿å°ã®è¯ãç°å¢ãšçŽ æŽãããåºäŒã
- ã³ã³ãã€ã©å
šè¬ã«é¢ããã³ãŒã¹ãç¹ã«ããŒãµãŒã«é¢ããè¬çŸ©ã«ã€ããŠã¯ãYevgeny Zuevææ
- DBMSã³ãŒã¹ã«ã€ããŠã¯ãManuel MazzaraææãšTA Ruslanææã«ã / GodBlessMazzara
ãããŠæ¬¡åã¯ããã€ãã©ã€ã³ãšãã©ã³ã¶ã¯ã·ã§ã³ãéçŽããéãªã¬ãŒã·ã§ãã«ã¢ãŒããå®è£
ããŸãã ãããŠãããåŒã³åºã-/ noDropSQLïŒ