å¥ã®ããžãã¹æ©èœãããã°ã©ãã³ã°ãããšãã«ãããŒã¿ããŒã¹ãæžããããåçã®é¡ãèªèãããããã¬ãŒã ã¯ãŒã¯ãäœæããããèå³æ·±ãã¢ã«ãŽãªãºã ãå®è£
ããããã人ãå°çäžã«ããããšããããããŸãã ãªãç§ã®ä»äºã§ãããŒã¿ããŒã¹ãããããŒãã«ããå¥ã®ããŒãã«ã«ã·ããããhttpãµãŒãã¹ãåŒã³åºããhtmlãã©ãŒã ã課ããä»ã®ãããžãã¹ããŒãã«ãã«çµããã®ã§ããããã äœãééã£ãããšãããŠããã®ã§ããããããããšãééã£ãäŒç€Ÿã§åããŠããã®ã§ããããïŒ
è¯ããã¥ãŒã¹ã¯ãèå³æ·±ãã¿ã¹ã¯ãã©ãã§ãç§ãã¡ãåãå²ãã§ããããšã§ãã 匷ã欲æãšåæ°ã®ããä»äºã¯ãç®æšãžã®éã®ããé©ãããŸã-ã©ããªèŠæš¡ã®ä»äºã§ãããªãã®åŒ·ã¿ã«ãªããŸããã¡ããã©ãããå§ããŠãã ããã
æè¿ã1Cã¯ãšãªèšèªããŒãµãŒãšãã®éåžžã®SQLãžã®å€æããã°ã©ã ãäœæããŸããã ããã«ããã1Cã®åå ãªãã«1Cãžã®ãªã¯ãšã¹ããåŠçããããšãã§ããŸãã:)æ£èŠè¡šçŸã®æå°äœæ¥ããŒãžã§ã³ã¯2é±éã§ããã å¥ã®æã¯ãææ³ãéããŠæ¬æ ŒçãªããŒãµãŒã«è²»ããããããŸããŸãª1Cãªããžã§ã¯ãã®ããŒã¿ããŒã¹æ§é ã®ãã¥ã¢ã³ã¹ãåŒãåºããç¹å®ã®æŒç®åãšé¢æ°ãå®è£
ããŸããã ãã®çµæããœãªã¥ãŒã·ã§ã³ã¯ã»ãŒãã¹ãŠã®èšèªæ§æããµããŒããããœãŒã¹ã³ãŒãã¯
GitHubã«æçš¿ãã
ãŸã ã
ã«ããã®äžã§ããªããããå¿
èŠãªã®ããã©ã®ããã«ããŠãããå¯èœã«ãªã£ãã®ãã説æããèå³æ·±ãæè¡çãªè©³çŽ°ã«ã觊ããŸãã
ã©ã®ããã«ãã¹ãŠãå§ãŸããŸãããïŒ
ç§ãã¡ã¯
倧èŠæš¡ãªäŒèšäŒç€ŸButtonã§åããŠããŸãã 1005人ã®ã¯ã©ã€ã¢ã³ãã75人ã®äŒèšå£«ã11人ã®éçºè
ãããŸãã åœç€Ÿã®äŒèšå£«ã¯ã
1CïŒäŒèšã·ã¹ãã ã«æ°åã®é¡§å®¢ããŒã¹ã®èšé²ãä¿æããŠã
ãŸã ã ããŒã¿ããŒã¹ã管çããã«ã¯ãã¯ã©ãŠããã¯ãããžãŒ1cFreshã䜿çšããŸããããŒã¿ããŒã¹ã®ããŒã¿ã¯PostgreSQLã«ä¿åãããŸãã

äŒèšå£«ã®ä»äºã§æãé£ãã段éã¯å ±åã§ãã 1Cã¯ã¬ããŒããäœæã§ããããã«èŠããŸããããã®ããã«ã¯ããŒã¿ããŒã¹ã®çŸåšã®ç¶æ
ãå¿
èŠã§ãã 誰ãããã¹ãŠã®äž»èŠãªææžãã·ã¹ãã ã«å
¥åããéè¡ååŒæ现æžãã€ã³ããŒãããå¿
èŠãªäŒèšææžãäœæããŠå®æœããå¿
èŠããããŸãã ããã«ãç§ãã¡ã®ææã®å·ã§ã®å ±åã®ç· ãåãã¯å³å¯ã«å¶éãããŠãããããäŒèšå£«ã¯éåžžãç ããªãæéã®ãã¬ãã·ã£ãŒããå¥ã®ãã¬ãã·ã£ãŒã«çããŠããŸãã
äŒèšå£«ã¯ã©ãããã°äººçã楜ã«ããããšãã§ããã®ã ãããšèããŸããäŒèšããŒã¹ã®è»œåŸ®ãªãšã©ãŒãåå ã§ãå€ãã®ã¬ããŒãã®åé¡ãçºçããããšãå€æããŸããã
- ååŒçžæãŸãã¯å¥çŽã®è€è£œã
- äžæ¬¡ææžã®è€è£œ;
- TINã®ãªãååŒçžæ;
- é ãéå»ãŸãã¯æªæ¥ã®æ¥ä»ãå«ãããã¥ã¡ã³ãã

ãªã¹ããããåé¡ã¯ã1Cã¯ãšãªèšèªã䜿çšããŠç°¡åã«èŠã€ããããšãã§ãããããã¯ã©ã€ã¢ã³ãããŒã¿ããŒã¹ã®èªåç£æ»ãè¡ããšããã¢ã€ãã¢ãæµ®äžããŸããã ç§ãã¡ã¯ããã€ãã®ãªã¯ãšã¹ããæžãããã¹ãŠã®1CããŒã¹ã§æ¯æ©ããããå®è¡ãå§ããŸããã Googleã®äŸ¿å©ãªãã¬ãŒãã§äŒèšå£«ã«çºèŠãããåé¡ã瀺ããããããå¯èœãªæ¹æ³ã§ãã¬ãŒãã空ã«ããŠããããšãæ±ããŸããã
æšæºã®COM API 1Cãä»ããŠãããã®èŠæ±ãå®è¡ããããšã¯ãå§ãã§ããŸããã ãŸããçŽ1,000åã®ããŒã¿ããŒã¹ãååŸããåããŒã¿ããŒã¹ã§ãã¹ãŠã®ã¯ãšãªãå®è¡ããã«ã¯10æéããããŸãã 第äºã«ãããã¯1CãµãŒããŒã倧å¹
ã«ããŒãããŸããããã¯éåžžãçãã¯ãããŸããã ç£æ»ã®ããã«ãçŸåšã®äººã
ã®æ¥ã
ã®ä»äºãé
ãããããšã¯äžå¿«ã§ãã
äžæ¹ãå
žåçãª1Cãªã¯ãšã¹ãã¯æ¬¡ã®ããã«ãªããŸãã
select doc. as Date, doc. as Number, doc.. as Inn, doc.. as CounterpartyInn, (doc..) as CounterpartyType, doc. as Description, doc. as Sum from . doc where not doc.. and doc. and doc. = (..) and (doc.) = (&Now)
SQLã«éåžžã«äŒŒãŠãããšããäºå®ã«ããããããããã®ãããªããšã¯ããŒã¿ããŒã¹ãçŽæ¥ååŸããŠå®è¡ããã ãã§ã¯æ©èœããŸããã

ããã«ã¯ã3ã€ã®æ¬åœã®çç±ããããŸãã
- ããŒã¿ããŒã¹å
ã®ããŒãã«ãšåã®ããžãã¯ããŒã ã ããã¯ã 1CãèŠæ±ããã®ååãžã®å¯Ÿå¿ãææžåãããããç°¡åã«è§£æ±ºãããŸãã
- ãã¹ããããããããã£ã ããšãã°ãSQLã®
doc..
ã¯left join
2ã€ã®ããŒãã«.
to doc..
ãš.
ã®left join
察å¿ããŠããŸãã ,
ãªã©ã®1Cåºæã®æŒç®åãšé¢æ° ã ãŸããé©åãªDBMSèšèšã«ããã«å€æããå¿
èŠããããŸãã
ããããã¹ãŠå®çŸããã®ã§ã1Cæ¹èšããã®ã¯ãšãªãéåžžã®SQLã«å€æãããã¹ãŠã®ç©çPostgreSQLãµãŒããŒã§äžŠåã«å®è¡ããçµæãçµåããŠMS SQLã®å¥ã®ããŒãã«ã«å
¥ãã
ãŠãŒãã£ãªãã£ãäœæããŸããã ãã®çµæãããŒã¿åéæéã¯10æéãã3åã«ççž®ãããŸããã
æ£èŠè¡šçŸ
æåã®ããŒãžã§ã³ã§ã¯ããªã¯ãšã¹ãå€æããžãã¯ãå®å
šã«æ£èŠè¡šçŸã§å®è£
ããŸããã COM API 1Cã«ã¯ãããŒã¿ããŒã¹ã®GetStorageæ§é é¢æ°ããããŸãã 1Cã¯ãšãªã®ãªããžã§ã¯ããšããããã£ã«å¯Ÿå¿ããããŒãã«ãšãã£ãŒã«ãã«é¢ããæ
å ±ãè¿ããŸãã ããã€ãã®æ£èŠè¡šçŸãã³ãã¬ãŒãã䜿çšããŠãããååãå¥ã®ååã«çœ®ãæããŸããã ãªããžã§ã¯ããšããããã£ãžã®ãã¹ãŠã®åŒã³åºãã«ãšã€ãªã¢ã¹ãããã°ãããã¯éåžžã«ç°¡åã«å®çŸã§ããŸããã
ãã¹ãŠã®é¢åã®ã»ãšãã©ã¯ãæ·»ä»ããããã£ã«ãã£ãŠæäŸãããŸããã 1Cã¯ããããé¢é£ããŒãã«ã«æ ŒçŽããããã
from
æ§é å
ã®ãªããžã§ã¯ãã®å
ã®ååããå¿
èŠãªãã¹ãŠã®
left join-
ãååšãããµãã¯ãšãªã«çœ®ãæããå¿
èŠ
left join-
ã
ããããã£ã®ååãå€æŽããå·Š
join
ãçæããããšã«å ããŠããã©ã³ã¹ã¬ãŒã¿ãŒã¯å€ãã®å€æã䜿çšããŸããã ãã®ãããããšãã°ãå
ã®ã¯ãšãªã®ãã¹ãŠã®
join
ã¯ããã£ãŒã«ã
(area)
ç䟡æ§ã«é¢ããè¿œå æ¡ä»¶ãæäŸããå¿
èŠããããŸããã äºå®ã1ã€ã®PostgreSQLããŒã¿ããŒã¹ã«ã¯è€æ°ã®1Cã¯ã©ã€ã¢ã³ãããŒã¿ããŒã¹ãããã1ã€ã®ã¯ã©ã€ã¢ã³ãã®ããŒã¿ã¯ã1Cã
regionãšåŒã¶ç¹å¥ãªèå¥åã«ãã£ãŠå¥ã®ã¯ã©ã€ã¢ã³ãã®ããŒã¿ãšç°ãªããŸãã ããŒã¿ããŒã¹ã§ã¯ã1Cã¯äžé£ã®ããã©ã«ãã€ã³ããã¯ã¹ãäœæããŸãã ãã¹ãŠã®èŠæ±ã¯åãã¯ã©ã€ã¢ã³ãå
ã§å®è¡ããããããããŒã®æåã®ã³ã³ããŒãã³ãã§ãããã¹ãŠã«é åããããŸãã ã¯ãšãªãæšæºã€ã³ããã¯ã¹ã䜿çšããããããèšè¿°ãããšãã«èæ
®ããªãããã«ãã¯ãšãªããããŒããã£ã¹ããããšãã«ãã®æ¡ä»¶ãèªåçã«è¿œå ãå§ããŸããã
æ£èŠè¡šçŸã䜿çšããããšãæ£ãã決å®ã§ãã
ããšãå€æããŸãã ãããã«ãããæçµçµæãè¿
éã«ååŸãããã®äºæ¥å
šäœããäœãæçšãªãã®ãåŸãããããšãç解ã§ããããã§ãã ãã®æ¹æ³ã§ãæãç°¡åã«å©çšã§ããæ段ã§ãæŠå¿µãšå®éšã®èšŒæãè¡ãããšããã¹ãŠã®äººã«æšå¥šããŸãã ãããŠãæ£èŠè¡šçŸãããããã¹ããæ±ããšããããç°¡åã§å¹æçãªãã®ã¯äœã§ããïŒ
ãã¡ãããæ¬ ç¹ããããŸãã æåã®æçœãªããšã¯ãã³ãŒããŒã®åãåããšæ§æã®å¶éã§ãã ããããã£ãšããŒãã«ã®æ£èŠè¡šçŸã¯ã¯ãšãªã§ãšã€ãªã¢ã¹ãå¿
èŠãšããäžè¬ã«ãããšãã°å®æ°æååãªã©ãä»ã®æ§æèŠçŽ ã«èª€ã£ãŠè¿œãã€ãå¯èœæ§ããããŸãã
å¥ã®åé¡ã¯ãããã¹ã解æããžãã¯ã®æ··ä¹±ãšãå¿
èŠãªã«ãŒã«ã«åŸã£ããã®å€æã§ãã æ¯åãæ°ããæ©èœãå®è£
ãããšããæ£èŠè¡šçŸãšè¡ã®
IndexOf
åŒã³åºããçµã¿åãããæ°ããå°çã®ãããªãã®ãçºæããå¿
èŠããããŸãããããã«ãããå
ã®ãªã¯ãšã¹ãã®å¯Ÿå¿ããèŠçŽ ãåé¢ãããŸãã
ãã®ãããããšãã°ããã¹ãŠã®joinã«ãã¡ã€ã³ã®ç䟡æ§ã®æ¡ä»¶ãè¿œå ããã³ãŒããèŠããŸããã
private string PatchJoin(string joinText, int joinPosition, string alias) { var fromPosition = queryText.LastIndexOf("from", joinPosition, StringComparison.OrdinalIgnoreCase); if (fromPosition < 0) throw new InvalidOperationException("assertion failure"); var tableMatch = tableNameRegex.Match(queryText, fromPosition); if (!tableMatch.Success) throw new InvalidOperationException("assertion failure"); var mainTableAlias = tableMatch.Groups[3].Value; var mainTableEntity = GetQueryEntity(mainTableAlias); var joinTableEntity = GetQueryEntity(alias); var condition = string.Format("{0}.{1} = {2}.{3} and ", mainTableAlias, mainTableEntity.GetAreaColumnName(), alias, joinTableEntity.GetAreaColumnName()); return joinText + condition; }
ã³ãŒãã§ã¯ã
ColumnReference
ãš
JoinClause
ã
ColumnReference
ãå
ã®ãªã¯ãšã¹ãã®ãªããžã§ã¯ãã¢ãã«ãåŠçãããã£ãã®ã§ããããªã¯ãšã¹ãããã¹ãã®æ£èŠè¡šçŸã§èŠã€ãã£ããµãã¹ããªã³ã°ãšãªãã»ããã®ã¿ããããŸããã
ãã®ãªãã·ã§ã³ã¯ãåã®ãªãã·ã§ã³ãããã¯ããã«ã·ã³ãã«ã§ç解ããããããã«èŠããããšã«åæããŸãã
private void PatchJoin(SelectClause selectClause, JoinClause joinClause) { joinClause.Condition = new AndExpression { Left = new EqualityExpression { Left = new ColumnReferenceExpression { Name = PropertyNames.area, Table = selectClause.Source }, Right = new ColumnReferenceExpression { Name = PropertyNames.area, Table = joinClause.Source } }, Right = joinClause.Condition }; }
ãã®ãããªãªããžã§ã¯ãã¢ãã«ã¯ã
æœè±¡æ§æããªãŒ ïŒ
AST ïŒãšåŒã°ã
ãŸã ã
AST
èå³æ·±ãããšã«ãå
ã®ã¯ãšãªã解æãããšãã§ã¯ãªããSQLã§çµæããã©ãŒããããããšãã«ãASTãåããŠè¡šç€ºãããŸããã äºå®ã¯ããã¹ããããããããã£ã®ãµãã¯ãšãªãæ§ç¯ããããã®ããžãã¯ã¯éåžžã«æŽç·Žããããã®ã§ããããããç°¡çŽ åããããã«ïŒãããŠ
SRPã«åŸã£ãŠïŒãããã»ã¹å
šäœã2ã€ã®æ®µéã«åå²ããŸããïŒæåã«ãµãã¯ãšãªãèšè¿°ãããªããžã§ã¯ãã®ããªãŒãäœæãã次ã«SQLã§åå¥ã«ã·ãªã¢ã«åããŸãã ããæç¹ã§ããããASTã§ããããšã«æ°ä»ããŸãããæ£èŠè¡šçŸã®åé¡ã解決ããã«ã¯ãå
ã®ãªã¯ãšã¹ãã«å¯ŸããŠäœæããæ¹æ³ãåŠã¶å¿
èŠããããŸãã
ASTãšããçšèª
㯠ã解æã®ãã¥ã¢ã³ã¹ãè°è«ããããã«åºã䜿çšãããŠããŸãã ãã®ããŒã¿æ§é ã¯ãéåžžãååž°æ§ãšã«ãŒãã
ãªããšããç¹æ§ãåããããã°ã©ãã³ã°èšèªã«å
žåçãªæ§é ããã説æããããã
ããªãŒãšåŒã°ããŸãïŒãã ããããã¯
åžžã«åœãŠã¯ãŸãããã§ã¯ãã
ãŸãã ïŒã
ããšãã°ã次ã®ã¯ãšãªãæ€èšããŠãã ããã
select p.surname as 'person surname' from persons p where p.name = ''
ASTã®åœ¢åŒã§ã¯ã次ã®ããã«ãªããŸãã
å³ã§ã¯ãããŒã-ã¯ã©ã¹ã®ã€ã³ã¹ã¿ã³ã¹ãç¢å°ãããã³çœ²å-ãããã®ã¯ã©ã¹ã®ããããã£ããã®ãããªãªããžã§ã¯ãã¢ãã«ã¯ã次ã®ããã«ã³ãŒããä»ããŠã¢ã»ã³ãã«ã§ããŸãã
var table = new TableDeclarationClause { Name = "PersonsTable", Alias = "t" }; var selectClause = new SelectClause { FromExpression = table, WhereExpression = new EqualityExpression { Left = new ColumnReferenceExpression { Table = table, Name = "name" }, Right = new LiteralExpression { Value = "" } } }; selectClause.Fields.Add(new SelectFieldExpression { Expression = new ColumnReferenceExpression { Table = table, Name = "surname" } });
äžèšã®ASTã®äŸãå¯äžã®æ£ããäŸã§ã¯ãªãããšã«æ³šæããŠãã ããã ã¯ã©ã¹ã®ç¹å®ã®æ§é ãšã¯ã©ã¹éã®é¢ä¿ã¯ãã¿ã¹ã¯ã®è©³çŽ°ã«ãã£ãŠæ±ºãŸããŸãã
ASTã®äž»ãªç®æšã¯ ãåé¡ã®è§£æ±ºãä¿é²ããå
žåçãªæäœã®ããã©ãŒãã³ã¹ãå¯èœãªéã䟿å©ã«ããããšã§ãã ãããã£ãŠãç®çã®èšèªã®æ§é ãèšè¿°ããã®ãããç°¡åã§èªç¶ã§ããã°ããã»ã©è¯ãã§ãã
æ£èŠè¡šçŸããASTãžã®ç§»è¡ã«ãããå€ãã®ããã¯ãåãé€ããã³ãŒããããããããããç解ããããããããšãã§ããŸããã åæã«ãä»ãç§ãã¡ã®ãŠãŒãã£ãªãã£ã¯ããœãŒã¹èšèªã®ãã¹ãŠã®æ§æã«ã€ããŠç¥ã£ãŠããŠãããªãŒã«é©åãªããŒããäœæããå¿
èŠããããŸãã ãããè¡ãã«ã¯ãã¯ãšãªèšèª1Cã®ææ³ãšãã®ããã®ããŒãµãŒãäœæããå¿
èŠããããŸããã
ææ³
ãã®ãããããæç¹ã§ãå
ã®ãªã¯ãšã¹ãã®ASTãå¿
èŠã§ããããšãæããã«ãªããŸããã ã€ã³ã¿ãŒãããã«ã¯SQLã解æããŠASTãäœæã§ããå€ãã®ã©ã€ãã©ãªããããŸãããããèŠããšããããã¯
ææã§ããããSQLã®ãµãã»ããã®ã¿ããµããŒãããŠããããšãããããŸãã ããã«ãSQLã®1Cæ¹èšã®èªèã«ããããã©ã®ããã«é©åããããã¯æ確ã§ã¯ãããŸããã
ãã®ãããç¬èªã®ããŒãµãŒãäœæããããšã«ããŸããã ããŒãµãŒã¯éåžžãèªèãããèšèªã®ææ³ãèšè¿°ããããšããå§ããŸãã
圢åŒææ³ã¯ãããã°ã©ãã³ã°èšèªã®æ§é ãèšè¿°ããããã®å€å
žçãªããŒã«ã§ãã ããã¯ãæšè«ã®ã«ãŒã«ãã€ãŸãåèšèªæ§é ã®ååž°çãªå®çŸ©ã«åºã¥ããŠããŸãã
ããšãã°ããããã®ã«ãŒã«ã¯ç®è¡åŒã®èšèªãèšè¿°ã§ããŸãã
E â number | (E) | E + E | E - E | E * E | E / E
ãã®ãããªã¬ã³ãŒãã¯ã次ã®ããã«èªã¿åãããšãã§ããŸãã
- ä»»æã®æ°å€
(number)
ã¯åŒ(E)
ã§ãã - åŒãè§ãã£ãã§å²ãŸããŠããå Žåãè§ãã£ããšå
±ã«ããããã¹ãŠåŒã§ãã
- ç®è¡æŒç®ã§æ¥ç¶ããã2ã€ã®åŒãåŒãæ§æããŸãã
åºåèŠåãå®çŸ©ãããŠããã·ã³ãã«ã¯ãéçµç«¯èšå·ãšåŒã°ããŸãã ã«ãŒã«ãå®çŸ©ãããŠããããèšèªã®èŠçŽ ã§ããã·ã³ãã«-
ã¿ãŒããã« ã ã«ãŒã«ãé©çšãããšãé端æ«ããã端æ«ã®ã¿ãæ®ããŸã§ãä»ã®é端æ«ãšç«¯æ«ã§æ§æãããæååãååŸã§ããŸãã äžèšã®äŸã§ã¯ã
E
ã¯éçµç«¯èšå·ã§ãããæå
+, -, *, /
ãããã³
number
ã¯ãç®è¡åŒã®èšèªã圢æããçµç«¯èšå·ã§ãã
ç¹å¥ãªããŒã«ããããŸã-ããŒãµãŒãžã§ãã¬ãŒã¿ãŒã¯ãææ³ã®åœ¢åŒã§æå®ãããèšèªã®èª¬æã«åŸã£ãŠããã®èšèªãèªèããã³ãŒããçæã§ããŸãã ãããã®äžã§æãæåãªã®ã¯ã
yacc ã
bison ãããã³
antlrã§ãã CïŒçšã®äžè¬çã§ã¯ãªã
Ironyã©ã€ãã©ãªããããŸãã
Habréã«ã¯åœŒå¥³
ã«é¢ããå°ããª
èšäºãæ¢ã«ãããŸãããã
Scott Hanselmanã圌女ã«ã€ããŠ
æçš¿ããŠããŸãã
Ironyã©ã€ãã©ãªã®äž»ãªæ©èœã¯ãæŒç®åã®ãªãŒããŒããŒãã䜿çšããŠãææ³èŠåã
C#
çŽæ¥èšè¿°ã§ããããšã§ãã çµæã¯ãã«ãŒã«ãèšè¿°ããå€å
žçãªåœ¢åŒã«éåžžã«é¡äŒŒãã圢åŒã®ãéåžžã«çŽ æŽããã
DSLã§ãã
var e = new NonTerminal("expression"); var number = new NumberLiteral("number"); e.Rule = e + "+" + e | e + "-" + e | e + "*" + e | e + "/" + e | "(" + e + ")" | number;
ã·ã³ãã«
| ã¯ãä»»æã®ã«ãŒã«ãªãã·ã§ã³ïŒè«çORïŒãé©çšã§ããããšãæå³ããŸãã
+èšå·ã¯é£çµã§ãããæåã¯äºãã«ç¶ãå¿
èŠããããŸãã
ã¢ã€ãããŒã¯ã
解æããªãŒãš
æœè±¡æ§æããªãŒã®æŠå¿µãåé¢ããŸãã
解æããªãŒã¯ãææ³èŠåã®äžè²«ããé©çšã®çµæã§ããããã¹ãèªèããã»ã¹ã®ææç©ã§ãã éçµç«¯èšå·ã¯ãã®å
éšããŒãã«é
眮ããã察å¿ããã«ãŒã«ã®å³éšåã®ã·ã³ãã«ã¯åå«ã«åé¡ãããŸãã
ããšãã°ãã«ãŒã«ãé©çšãããšãã®åŒ
1+(2+3)
ïŒ
e 1 ïŒ EâE + E
e 2 ïŒ EâïŒEïŒ
e 3 ïŒ Eâçªå·
ãã®ãããªè§£æããªãŒã«å¯Ÿå¿ããŸãã
Parse Treeã¯èšèªã«äŸåãããåäžã®
ParseTreeNode
ã¯ã©ã¹ã«ãã£ãŠIronyã§èšè¿°ãããŸãã
å察ã«ã
æœè±¡æ§æããªãŒã¯ç¹å®ã®ã¿ã¹ã¯ã«ãã£ãŠå®å
šã«æ±ºå®ããããã®ã¿ã¹ã¯ã«åºæã®ã¯ã©ã¹ãšãããã®éã®é¢ä¿ã§æ§æãããŸãã
ããšãã°ãäžèšã®ææ³ã®ASTã¯ã1ã€ã®
BinaryOperator
ã¯ã©ã¹ã®ã¿ã§æ§æãããå ŽåããããŸãã
public enum OperatorType { Plus, Minus, Mul, Div } public class BinaryOperator { public object Left { get; set; } public object Right { get; set; } public OperatorType Type { get; set; } }
Left
ããããã£ãš
Right
ããããã£ã¯
object
åã§ãã æ°å€ãŸãã¯å¥ã®
BinaryOperator
åç
§ã§ããŸãã
ã¢ã€ãããŒã䜿çšãããšãææ³ã®ã«ãŒã«ãé©çšããªãããèããæ ¹ã«åãã£ãŠé çªã«ASTãäœæã§ããŸãã ãããè¡ãã«ã¯ãåé
AstNodeCreator
ããªã²ãŒãã
AstNodeCreator
ã§ããŸãããã®é端æ«ã«é¢é£ä»ããããã«ãŒã«ã®ãããããé©çšããããšãã«IronyãåŒã³åºããŸãã ãã®ããªã²ãŒãã¯ãéä¿¡ããã
ParseTreeNode
åºã¥ããŠããã«å¯Ÿå¿ããASTããŒããäœæãã
ParseTreeNode
ãªã³ã¯ãæ»ã
ParseTreeNode
ãŸãã ããªã²ãŒããåŒã³åºããããŸã§ã«ãParse Treeã®ãã¹ãŠã®åããŒãã¯æ¢ã«åŠçãããŠããã
AstNodeCreator
ã¯ãã§ã«åŒã³åºãããŠãããããããªã²ãŒãã®æ¬æã§ã¯ãæ¢ã«èªã¿èŸŒãŸããŠããåããŒãã®
AstNode
ããããã£ã䜿çšã§ããŸãã
ãã®ããã«ã«ãŒã
AstNode
ã«å°éãããšãASTã«ãŒãããŒãã
AstNode
ããã®å Žåã¯
SqlQuery
ã§åœ¢æãããŸãã
äžèšã®ç®è¡åŒã®ææ³ã§ã¯ãAstNodeCreatorã¯æ¬¡ã®ããã«ãªããŸãã
var e = new NonTerminal("expression", delegate(AstContext context, ParseTreeNode node) {
ãã®ãããIronyã®å©ããåããŠãæåã®èŠæ±ã«å¿ããŠASTãæ§ç¯ããæ¹æ³ãåŠã³ãŸããã æçµçãªåæã§ã¯ãçµæã®SQLã¯ãšãªASTããœãŒã¹ASTããååŸããå¿
èŠããããããASTå€æçšã®ã³ãŒããå¹ççã«æ§é åããæ¹æ³ã¯1ã€ã ãã§ãã Visitorãã¿ãŒã³ã¯ããã«åœ¹ç«ã¡ãŸãã
蚪åè
Visitor ïŒãŸãã¯
double dispatch ïŒãã¿ãŒã³ã¯
GoFã§æãè€éãªãã¿ãŒã³ã®1ã€ã§ããããããã£ãŠãããããã»ãšãã©äœ¿çšãããªããã¿ãŒã³ã®1ã€ã§ãã ç§ãã¡ã®çµéšã§ã¯ãããŸããŸãªASTã®å€æã®ããã«ã1ã€ã®ã¢ã¯ãã£ããªäœ¿çšããèŠãŠããŸããã å
·äœçãªäŸã¯ã.NETã®
ExpressionVisitorã¯ã©ã¹ã§ããããã¯ã
linqãããã€ããŒãå®è¡
ããå ŽåããŸãã¯ã³ã³ãã€ã©ãŒã«ãã£ãŠçæããã
åŒããªãŒããããã«ä¿®æ£
ããå Žåã«å¿
ã
çºçããŸãã
蚪åè
ã¯ã©ã®ãããªåé¡ã解決ããŸããïŒASTã§äœæ¥ãããšãã«ããããªããã°ãªããªãæãèªç¶ã§å¿
èŠãªããšã¯ãASTãæååã«å€æããããšã§ãã ããšãã°ãASTãåãäžããŸãããã·ã¢ã®ããŒãã«åãè±èªã«çœ®ãæãã
left join-
ãçæãã1CæŒç®åãããŒã¿ããŒã¹æŒç®åã«å€æããåŸãPostgreSQLã§å®è¡ããããã«éä¿¡ã§ããæååãåºåã§ååŸããå¿
èŠããããŸãã
ãã®åé¡ã®å¯èœãªè§£æ±ºçã¯æ¬¡ã®ãšããã§ãã
internal class SelectClause : ISqlElement {
ãã®ã³ãŒãã«ã€ããŠã次ã®2ã€ã®éèŠãªç¹ã確èªã§ããŸãã
- ååž°ãæ©èœãããã«ã¯ãããªãŒã®ãã¹ãŠã®ããŒãã«
BuildSql
ã¡ãœãããå¿
èŠã§ãã BuildSql
ã¡ãœããã¯ããã¹ãŠã®åããŒãã§BuildSql
ãåŒã³åºããŸãã
次ã«ãå¥ã®ã¿ã¹ã¯ãæ€èšããŸãã PostgreSQLã€ã³ããã¯ã¹ãååŸããããã«ãã¡ã€ã³ããŒãã«ãšçµåããããã¹ãŠã®ãã£ãŒã«ãã®
area
ãã£ãŒã«ãã®ç䟡æ¡ä»¶ãè¿œå ããå¿
èŠããããšããŸãã ãããè¡ãã«ã¯ããªã¯ãšã¹ãå
ã®ãã¹ãŠã®
JoinClause
ã確èªããå¿
èŠããããŸãããå¯èœæ§ã®ãããµãã¯ãšãªãèãããšãä»ã®ãã¹ãŠã®ããŒãã確èªããå¿
èŠããããŸãã
ããã¯ãäžèšãšåãã³ãŒãæ§é ã«åŸãå Žåã次ã®ããšãè¡ãå¿
èŠãããããšãæå³ããŸãã
- ããªãŒã®ãã¹ãŠã®ããŒãã«
AddAreaToJoinClause
ã¡ãœãããè¿œå ããŸãã JoinClause
ãé€ããã¹ãŠã®ããŒãã§ã®å®è£
ã¯ãåå«ã«åŒã³åºãã転éããå¿
èŠããããŸãã
ãã®ã¢ãããŒãã®åé¡ã¯æããã§ããããªãŒäžã§ããŸããŸãªè«çæäœãè¡ãã»ã©ãããŒãã«ååšããã¡ãœãããå¢ãããããã®ã¡ãœããéã§ã³ããŒã¢ã³ãããŒã¹ããå¢ããŸãã
蚪åè
ã¯ãã®åé¡ã次ã®æ¹æ³ã§
解決ããŸã ã
- è«çæŒç®ã¯ããŒãäžã®ã¡ãœããã§ã¯ãªããªããŸãããåå¥ã®ãªããžã§ã¯ã
SqlVisitor
æœè±¡ã¯ã©ã¹ã®ç¶æ¿è
ã«ãªããŸãïŒæ¬¡ã®å³ãåç
§ïŒã - åããŒãã¿ã€ãã¯ã
VisitSelectClause(SelectClause clause)
ãVisitJoinClause(JoinClause clause)
ãªã©ãããŒã¹SqlVisitor-
åå¥ã®Visit
ã¡ãœããã«å¯Ÿå¿ããŠããŸãã BuildSql
ããã³AddAreaToJoinClause
ã¯ã1ã€ã®äžè¬çãªAccept
ã¡ãœããã«çœ®ãæããããŸãã- åããŒãã¯ããã©ã¡ãŒã¿ãŒãšããŠæäŸããã
SqlVisitor-
ã®å¯Ÿå¿ããã¡ãœããã«è»¢éããããšã§å®è£
ããŸãã - å
·äœçãªæäœã¯
SqlVisitor
ããç¶æ¿ãããèå³ã®ããã¡ãœããã®ã¿ãåå®çŸ©ããŸãã - ããŒã¹
SqlVisitor-
ã®Visit
ã¡ãœããã®å®è£
ã¯ããã¹ãŠã®åããŒãã®Visit
ãåŒã³åºãã ãã§ãã³ãŒãã®éè€ãæé€ããŸãã
SQLã®ã·ãªã¢ã«åã®äŸã¯ã次ã®ããã«é©åããŸãã
internal interface ISqlElement { void Accept(SqlVisitor visitor); } internal class SqlVisitor { public virtual void Visit(ISqlElement sqlElement) { sqlElement.Accept(this); } public virtual void VisitSelectClause(SelectClause selectClause) { }
ããã«ãã£ã¹ããããšããååã¯ããã®ã¹ããŒã ãéåžžã«æ£ç¢ºã«èª¬æããŠããŸãã
- æåã®ãã£ã¹ãããã¯ãç¹å®ã®ããŒãã§
Visit
ããAccept
ã«åãæ¿ãããšãã«SqlVisitor
ã¯ã©ã¹ã§çºçããŸãããã®æç¹ã§ãããŒãã®ã¿ã€ããSqlVisitor
ããŸãã - ããŒãã®
Accept
ããSqlVisitor
ç¹å®ã®ã¡ãœããã«åãæ¿ãããšã2çªç®ã®ãã£ã¹ããããæåã«ç¶ããŸããããã§ãéžæããããŒãã«é©çšããå¿
èŠãããæäœãSqlVisitor
ãŸãã
åèš
ãã®èšäºã§ã¯ãã¯ãšãªèšèª1Cã®ç¿»èš³è
ãSQLã¯ãšãªã«æºåããããã®ã¬ã·ãã«ã€ããŠè©³ãã説æããŠããŸãã æ£èŠè¡šçŸã䜿ã£ãå®éšãè¡ã£ãŠãå®çšçãªãããã¿ã€ããååŸãããã®ãã®ãæçšã§ãããå
ã«é²ã䟡å€ãããããšã確èªããŸããã ãããŠãæ¥ãããããšèŠçãªãã«ã³ãŒããèŠãããšãäžå¯èœã«ãªããæ£èŠè¡šçŸãšãžã£ã°ãªã³ã°ããŠãæãŸããçµæãåŸãããªãã£ããšããç§ãã¡ã¯æ·±å»ãªäžæ©ãèžã¿åºããŸãã-ASTãšææ³ã«åãæ¿ããŸããã ããã«ã蚪åè
ã®å©ããåããŠãASTãå€æããæ¹æ³ãåŠã³ãŸãããããã«ãããããèšèªããå¥ã®èšèªãžã®ç¿»èš³ã®ããžãã¯ãå®çŸããŸããã
ç§ãã¡ãäžäººã§ãã®ããã«è¡ããã
ãã©ãŽã³ããã¯ãéãå¿
èŠãããªãã£ãããšã¯æ³šç®ã«å€ããŸãã ASTã®è§£æãšæ§ç¯ã«ã¯ãå®æããIronyã©ã€ãã©ãªã䜿çšããŸãããããã«ãããè»èŒªãåçºæããã®ã§ã¯ãªããé©çšãããåé¡ã®è§£æ±ºã«ããã«é²ãããšãã§ããŸããã
äŒç€Ÿã®å®éã®çµæã¯ãããŒã¿ã®åä¿¡é床ã10æéãã3åã«ççž®ããããšã§ãã ããã«ãããã¢ããªã¹ãã¯ãã¯ã©ã€ã¢ã³ãã®ããžãã¹ãšäŒèšå£«ã®ä»äºã«é¢ãã仮説ãè¿
éã«å®éšãããã¹ãããããšãã§ããŸããã å€ãã®ã¯ã©ã€ã¢ã³ããããããããã®ããŒã¿ããŒã¹ã¯5ã€ã®ç©çPostgreSQLãµãŒããŒã«åæ£ãããŠãããããããã¯ç¹ã«äŸ¿å©ã§ãã
äžèšã®ãã¹ãŠãèŠçŽããŸãã- å®éšãè¡ããå¯èœãªéãè¿
éãã€å®äŸ¡ã«æŠå¿µå®èšŒãååŸããŸãã
- éå¿çãªç®æšãèšå®ããå°ããªã¹ãããã§ãããã«åãã£ãŠé²ã¿ãåŸã
ã«æ©åšãç®çã®ç¶æ
ã«ä»äžããŸãã
- ã»ãšãã©ã®ã¿ã¹ã¯ã«ã¯ãæ¢è£œã®ãœãªã¥ãŒã·ã§ã³ããŸãã¯å°ãªããšãåºç€ãæ¢ã«ãããŸãã
- 解æãšææ³ã¯ãéåžžã®ããžãã¹ã¢ããªã±ãŒã·ã§ã³ã«é©çšã§ããŸãã
- ç¹å®ã®åé¡ã解決ãããšãäžè¬çãªè§£æ±ºçãèªåçã«åŸãããŸãã
ã©ã€ãã©ãªã³ãŒããšäœ¿çšäŸ
ãGitHubã§ãåŸ
ã¡ããŠããŸã ã
äœæã«ã¯ã以äžãèªãããšããå§ãããŸãã