From 6ba1adfa07712ee7b984225b1b6587e4031b607f Mon Sep 17 00:00:00 2001 From: Alejandro Lopez Date: Thu, 13 Jul 2023 16:12:47 +0300 Subject: [PATCH] [#xx] Add support for SELECT-FILTER expressions Signed-off-by: Alejandro Lopez --- netmap/netmap.go | 51 +++ netmap/parser/Query.g4 | 2 + netmap/parser/Query.interp | Bin 4611 -> 5170 bytes netmap/parser/query_base_visitor.go | 4 + netmap/parser/query_parser.go | 567 +++++++++++++++++++--------- netmap/parser/query_visitor.go | 3 + netmap/policy.go | 71 ++++ netmap/policy_test.go | 25 ++ 8 files changed, 554 insertions(+), 169 deletions(-) diff --git a/netmap/netmap.go b/netmap/netmap.go index e1a5f7d..3e8d680 100644 --- a/netmap/netmap.go +++ b/netmap/netmap.go @@ -158,6 +158,57 @@ func (m NetMap) PlacementVectors(vectors [][]NodeInfo, pivot []byte) ([][]NodeIn return result, nil } +// SelectFilterNodes returns a two-dimensional list of nodes as a result of applying the +// given SelectFilterExpr to the NetMap. +// If the SelectFilterExpr contains only filters, the result contains a single row with the +// result of the last filter application. +// If the SelectFilterExpr contains only selectors, the result contains the selection rows +// of the last select application. +func (m NetMap) SelectFilterNodes(expr *SelectFilterExpr) ([][]NodeInfo, error) { + p := PlacementPolicy{ + filters: expr.filters, + } + + if expr.selector != nil { + p.selectors = append(p.selectors, *expr.selector) + } + + c := newContext(m) + c.setCBF(expr.cbf) + + if err := c.processFilters(p); err != nil { + return nil, err + } + if err := c.processSelectors(p); err != nil { + return nil, err + } + + if expr.selector == nil { + var ret []NodeInfo + lastFilter := expr.filters[len(expr.filters)-1] + for _, ni := range m.nodes { + if c.match(c.processedFilters[lastFilter.GetName()], ni) { + ret = append(ret, ni) + } + } + return [][]NodeInfo{ret}, nil + } + + sel, err := c.getSelection(*c.processedSelectors[expr.selector.GetName()]) + if err != nil { + return nil, err + } + + var ret [][]NodeInfo + for i, ns := range sel { + ret = append(ret, []NodeInfo{}) + for _, n := range ns { + ret[i] = append(ret[i], n) + } + } + return ret, nil +} + // ContainerNodes returns two-dimensional list of nodes as a result of applying // given PlacementPolicy to the NetMap. Each line of the list corresponds to a // replica descriptor. Line order corresponds to order of ReplicaDescriptor list diff --git a/netmap/parser/Query.g4 b/netmap/parser/Query.g4 index abae181..72fa880 100644 --- a/netmap/parser/Query.g4 +++ b/netmap/parser/Query.g4 @@ -6,6 +6,8 @@ options { policy: UNIQUE? repStmt+ cbfStmt? selectStmt* filterStmt* EOF; +selectFilterExpr: cbfStmt? selectStmt? filterStmt* EOF; + repStmt: REP Count = NUMBER1 // number of object replicas (IN Selector = ident)?; // optional selector name diff --git a/netmap/parser/Query.interp b/netmap/parser/Query.interp index df98c281f48e2c2fc4c59a85f2448b44c6d9eadd..a8fb219e6ebe10b7437f9f3f946010b562b52f2d 100644 GIT binary patch literal 5170 zcmbW5TTfd@6oudCSMWw#QOV=G^Hc|%$|@LYLy=ll2*`_xVXbP<{{8wKo|~_$&EqEA-+i*#2@b7q zUtgN=X-D>@Z8j*o{9E&uR)5^CUmKm$<6ZL{J~wawe0lyD9zHft8y~NaLkPE#?mh zYCW;FMy;beWdnP0gfJtO&3ue@ooM`2!wm}tJLLJ5=xZ=#U`@(W< zsR`-JbV4QRN!opBD+vG_6I;-?*aNxD*(nfHmIH|cF!@uIQqZch%A25vvgvU_qqqZ{We^d0 z<+dy_Mq4+IDv}XVXNqJn*~aEH%cxU%u&`t0!*cFPt1yX+9$997$TRjTb;=a`q7_Uu z`2rOn(e(WmdXO5aY#dbTM8h{xsrz{$i&IBw82+;$(W?XRDH5)xCIuz}_Ot>obm3Gr zL*BCoRwaU5*QTfBxa)F*hWl0hzze^^;N=){zd8WQOjY$@+3fX|PF;RDeCG>$qQl+8 zlyiYe9@MeO)?O^iw@)romuX1^OjuQ6An{7(PH+IX#_EfJJivolmy#ZA)d9kxB~a{6 zLQk@$LY3S&r|dj<3kOvV46D*WZ=h5PdrE=#TlTi+0cTLBCJbJ#i#+rYJ!E7N_>I)F ztLaervQa3LL3O|wgIn;xs^pM|RdU$c3r3uw5)s`4Bsj?g*Fwas+(w$Q+QP^q@r3cs z@Mk2g5ogz47D$r$As3g=EZ_8`3Ojd$IhX||S=I^&>$0RtaV5u+N1R>}jex2Md{#%C zo=mzXu?QFoDU`?B7+0x`6$YJ!9<;?zBsTI8QG{4vlE+nc$YX`Bt*kc0g8M=njPkV^ z<5}{!N)UPMC(4hlSP%tFB;iI&?j5Moo@mB$%S5L8DFZ?m_SPUQ2`~#xa!r$^iTo)n zDfxq(I)NRgC??9spP$_-z(ktb+qyxXqy)8{ERvu+%Nak4jswJw2&ixU8)7Zk)}$!0 zBPn*I3wdkTkl2yg!m=T;qckehBt~~vnuY|54Vm_0M}D{`Y_&;P7y><(eRPkDBl~49 zxH2C*mb$*b?T#bq(ke?YTLiGqa+e-n>~Orhu&7(M6eI7iI2v0NT^gmG4Le_}1;MmT z^JQDqx7uTR&&)Aa5xhs7fW;PJ5yQyrDU^iVC(RGv-2pRJBN=*h^+X74RGUwSB3io$v-(`g~IOaOITW>)vw zR%_H!ca_)K8nYHBCJ#MY(*<6|Vb$2n(9pdU4W+Dk%-FQ6P=KOD`mNlC0rvkF1(jPx zdnM|wJ^);d(iH%W6E&t(&X3mYfwQk5Q;n?^>+cyMq`EyctK6*89|_ZNRcC7bmo;MA z*Ix2x?Hm1GVZ_k7V>7E<&Ya3EwOg;_pqHiwC|W-znHGgczU5N-&6j{|Cx$s!jj^ literal 4611 zcmbW5TW{M&5QX3OSLn@c;R2-Y%2O3vDTLaRE6Fv`qA+ZS0gT8O$TAxL`+jF;NpaUe zP!yncXU?9PIkTk6P4-V;tH;jveqZfwww=eDhw9}+czoS%!_i{7ISNP9#VO-*brjLd z#r*fn8PIBW!8l)tvt~H?_=#~nJDZ&-?$c^{u4#U@nGt;SlNP7viaedKH}i$De!%^a z-!Cz}S1#IK*qg+cw};!O?fqS%5sBB!i-1N=%az9U{QTlCyR<+n?DSr#Q>Uq6?*oV8@FE+na+v;xb(Dvr_r3zo}x7>-@x943n zZLvD|zg2H><&T@~YsF1@xUF{KYxVZe)9!P)|6D!peY`peA>8aAKZL*f$DQ)H)9o?! z#u&$);Hu?J=|Vh_z`#D?G(HdU~_*2HW^@X`xwk{3&R z?b35-(wdjo#4>ygjr>T<=qQqevKUc^l|;CAF3WvL?P!`{txrru@wj4ipJ-$Yurac| zF`)^2fY)Y6Ar_3CUEbEf_4t~a_SWmsN!f_YHFOotnxi8$kg`F^m)ViW9cy^LM?TUb zG5>ocJFyc|ko`YqfuM{R1jV-W3N-I=f)FUPoN?u(YA)LZ742t_y8How?O5f?1&T931*KW_V)FA)#17~M zn(KvWz9e#kJXRpy016XJ4x5iga@dnhdNCCWEm0^e+d}!;sydrOX>O?5-gjO^{!q=d z)kL5js~5mf-H_5F6$miYjwQkLJIq=c!q8U^zBb)7i6cCzA`D)F;SaOsxLzSh=A z%8=wqG? z4i$!oobV#Xg@|3hAOwrm=OR0~_DC=98>bLb6mh)7g zfSeF%dlCgwg;g#A6K|X4h^cEb9-5)#L_fOJjE_1Iq#^MFqSAl`!9q(mv3I_pVo~w^Rx#3-9RgcotBEux7h08r0 zmTI!KC^dDwafMpZ1eI9*5>RdHm`VC}+j`6mCqQSDx}HkeQKyEio}r3JQ0+zz`r!wC zSv?*6>?|u>Ib%UT7r{?;*gqeQ*RJTOGQCIj;3TN_ND32B+oLySTebnFFQJN};}!E^ ze*~C{gsL)jdh)%D@8{AEV!~AwPHfrESouNMkAeBo&9df4$x??hJGy6kZ2th&NlNut ztLvGom>Sal+iC6aPu7}Cbbdoz+J~ diff --git a/netmap/parser/query_base_visitor.go b/netmap/parser/query_base_visitor.go index 4badbce..981106f 100644 --- a/netmap/parser/query_base_visitor.go +++ b/netmap/parser/query_base_visitor.go @@ -12,6 +12,10 @@ func (v *BaseQueryVisitor) VisitPolicy(ctx *PolicyContext) interface{} { return v.VisitChildren(ctx) } +func (v *BaseQueryVisitor) VisitSelectFilterExpr(ctx *SelectFilterExprContext) interface{} { + return v.VisitChildren(ctx) +} + func (v *BaseQueryVisitor) VisitRepStmt(ctx *RepStmtContext) interface{} { return v.VisitChildren(ctx) } diff --git a/netmap/parser/query_parser.go b/netmap/parser/query_parser.go index 6357727..db19c93 100644 --- a/netmap/parser/query_parser.go +++ b/netmap/parser/query_parser.go @@ -44,70 +44,77 @@ func queryParserInit() { "STRING", "WS", } staticData.RuleNames = []string{ - "policy", "repStmt", "cbfStmt", "selectStmt", "clause", "filterExpr", - "filterStmt", "expr", "filterKey", "filterValue", "number", "keyword", - "ident", "identWC", + "policy", "selectFilterExpr", "repStmt", "cbfStmt", "selectStmt", "clause", + "filterExpr", "filterStmt", "expr", "filterKey", "filterValue", "number", + "keyword", "ident", "identWC", } staticData.PredictionContextCache = antlr.NewPredictionContextCache() staticData.serializedATN = []int32{ - 4, 1, 23, 138, 2, 0, 7, 0, 2, 1, 7, 1, 2, 2, 7, 2, 2, 3, 7, 3, 2, 4, 7, + 4, 1, 23, 154, 2, 0, 7, 0, 2, 1, 7, 1, 2, 2, 7, 2, 2, 3, 7, 3, 2, 4, 7, 4, 2, 5, 7, 5, 2, 6, 7, 6, 2, 7, 7, 7, 2, 8, 7, 8, 2, 9, 7, 9, 2, 10, 7, - 10, 2, 11, 7, 11, 2, 12, 7, 12, 2, 13, 7, 13, 1, 0, 3, 0, 30, 8, 0, 1, - 0, 4, 0, 33, 8, 0, 11, 0, 12, 0, 34, 1, 0, 3, 0, 38, 8, 0, 1, 0, 5, 0, - 41, 8, 0, 10, 0, 12, 0, 44, 9, 0, 1, 0, 5, 0, 47, 8, 0, 10, 0, 12, 0, 50, - 9, 0, 1, 0, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 3, 1, 58, 8, 1, 1, 2, 1, 2, 1, - 2, 1, 3, 1, 3, 1, 3, 1, 3, 3, 3, 67, 8, 3, 1, 3, 3, 3, 70, 8, 3, 1, 3, - 1, 3, 1, 3, 1, 3, 3, 3, 76, 8, 3, 1, 4, 1, 4, 1, 5, 1, 5, 1, 5, 1, 5, 1, - 5, 1, 5, 1, 5, 1, 5, 1, 5, 1, 5, 1, 5, 3, 5, 91, 8, 5, 1, 5, 1, 5, 1, 5, - 1, 5, 1, 5, 1, 5, 5, 5, 99, 8, 5, 10, 5, 12, 5, 102, 9, 5, 1, 6, 1, 6, - 1, 6, 1, 6, 1, 6, 1, 7, 1, 7, 1, 7, 1, 7, 1, 7, 1, 7, 3, 7, 115, 8, 7, - 1, 8, 1, 8, 3, 8, 119, 8, 8, 1, 9, 1, 9, 1, 9, 3, 9, 124, 8, 9, 1, 10, - 1, 10, 1, 11, 1, 11, 1, 12, 1, 12, 3, 12, 132, 8, 12, 1, 13, 1, 13, 3, - 13, 136, 8, 13, 1, 13, 0, 1, 10, 14, 0, 2, 4, 6, 8, 10, 12, 14, 16, 18, - 20, 22, 24, 26, 0, 3, 1, 0, 14, 15, 1, 0, 20, 21, 2, 0, 6, 8, 10, 12, 142, - 0, 29, 1, 0, 0, 0, 2, 53, 1, 0, 0, 0, 4, 59, 1, 0, 0, 0, 6, 62, 1, 0, 0, - 0, 8, 77, 1, 0, 0, 0, 10, 90, 1, 0, 0, 0, 12, 103, 1, 0, 0, 0, 14, 114, - 1, 0, 0, 0, 16, 118, 1, 0, 0, 0, 18, 123, 1, 0, 0, 0, 20, 125, 1, 0, 0, - 0, 22, 127, 1, 0, 0, 0, 24, 131, 1, 0, 0, 0, 26, 135, 1, 0, 0, 0, 28, 30, - 5, 5, 0, 0, 29, 28, 1, 0, 0, 0, 29, 30, 1, 0, 0, 0, 30, 32, 1, 0, 0, 0, - 31, 33, 3, 2, 1, 0, 32, 31, 1, 0, 0, 0, 33, 34, 1, 0, 0, 0, 34, 32, 1, - 0, 0, 0, 34, 35, 1, 0, 0, 0, 35, 37, 1, 0, 0, 0, 36, 38, 3, 4, 2, 0, 37, - 36, 1, 0, 0, 0, 37, 38, 1, 0, 0, 0, 38, 42, 1, 0, 0, 0, 39, 41, 3, 6, 3, - 0, 40, 39, 1, 0, 0, 0, 41, 44, 1, 0, 0, 0, 42, 40, 1, 0, 0, 0, 42, 43, - 1, 0, 0, 0, 43, 48, 1, 0, 0, 0, 44, 42, 1, 0, 0, 0, 45, 47, 3, 12, 6, 0, - 46, 45, 1, 0, 0, 0, 47, 50, 1, 0, 0, 0, 48, 46, 1, 0, 0, 0, 48, 49, 1, - 0, 0, 0, 49, 51, 1, 0, 0, 0, 50, 48, 1, 0, 0, 0, 51, 52, 5, 0, 0, 1, 52, - 1, 1, 0, 0, 0, 53, 54, 5, 6, 0, 0, 54, 57, 5, 20, 0, 0, 55, 56, 5, 7, 0, - 0, 56, 58, 3, 24, 12, 0, 57, 55, 1, 0, 0, 0, 57, 58, 1, 0, 0, 0, 58, 3, - 1, 0, 0, 0, 59, 60, 5, 9, 0, 0, 60, 61, 5, 20, 0, 0, 61, 5, 1, 0, 0, 0, - 62, 63, 5, 10, 0, 0, 63, 69, 5, 20, 0, 0, 64, 66, 5, 7, 0, 0, 65, 67, 3, - 8, 4, 0, 66, 65, 1, 0, 0, 0, 66, 67, 1, 0, 0, 0, 67, 68, 1, 0, 0, 0, 68, - 70, 3, 24, 12, 0, 69, 64, 1, 0, 0, 0, 69, 70, 1, 0, 0, 0, 70, 71, 1, 0, - 0, 0, 71, 72, 5, 11, 0, 0, 72, 75, 3, 26, 13, 0, 73, 74, 5, 8, 0, 0, 74, - 76, 3, 24, 12, 0, 75, 73, 1, 0, 0, 0, 75, 76, 1, 0, 0, 0, 76, 7, 1, 0, - 0, 0, 77, 78, 7, 0, 0, 0, 78, 9, 1, 0, 0, 0, 79, 80, 6, 5, -1, 0, 80, 81, - 5, 1, 0, 0, 81, 82, 5, 16, 0, 0, 82, 83, 3, 10, 5, 0, 83, 84, 5, 17, 0, - 0, 84, 91, 1, 0, 0, 0, 85, 86, 5, 16, 0, 0, 86, 87, 3, 10, 5, 0, 87, 88, - 5, 17, 0, 0, 88, 91, 1, 0, 0, 0, 89, 91, 3, 14, 7, 0, 90, 79, 1, 0, 0, - 0, 90, 85, 1, 0, 0, 0, 90, 89, 1, 0, 0, 0, 91, 100, 1, 0, 0, 0, 92, 93, - 10, 4, 0, 0, 93, 94, 5, 2, 0, 0, 94, 99, 3, 10, 5, 5, 95, 96, 10, 3, 0, - 0, 96, 97, 5, 3, 0, 0, 97, 99, 3, 10, 5, 4, 98, 92, 1, 0, 0, 0, 98, 95, - 1, 0, 0, 0, 99, 102, 1, 0, 0, 0, 100, 98, 1, 0, 0, 0, 100, 101, 1, 0, 0, - 0, 101, 11, 1, 0, 0, 0, 102, 100, 1, 0, 0, 0, 103, 104, 5, 12, 0, 0, 104, - 105, 3, 10, 5, 0, 105, 106, 5, 8, 0, 0, 106, 107, 3, 24, 12, 0, 107, 13, - 1, 0, 0, 0, 108, 109, 5, 18, 0, 0, 109, 115, 3, 24, 12, 0, 110, 111, 3, - 16, 8, 0, 111, 112, 5, 4, 0, 0, 112, 113, 3, 18, 9, 0, 113, 115, 1, 0, - 0, 0, 114, 108, 1, 0, 0, 0, 114, 110, 1, 0, 0, 0, 115, 15, 1, 0, 0, 0, - 116, 119, 3, 24, 12, 0, 117, 119, 5, 22, 0, 0, 118, 116, 1, 0, 0, 0, 118, - 117, 1, 0, 0, 0, 119, 17, 1, 0, 0, 0, 120, 124, 3, 24, 12, 0, 121, 124, - 3, 20, 10, 0, 122, 124, 5, 22, 0, 0, 123, 120, 1, 0, 0, 0, 123, 121, 1, - 0, 0, 0, 123, 122, 1, 0, 0, 0, 124, 19, 1, 0, 0, 0, 125, 126, 7, 1, 0, - 0, 126, 21, 1, 0, 0, 0, 127, 128, 7, 2, 0, 0, 128, 23, 1, 0, 0, 0, 129, - 132, 3, 22, 11, 0, 130, 132, 5, 19, 0, 0, 131, 129, 1, 0, 0, 0, 131, 130, - 1, 0, 0, 0, 132, 25, 1, 0, 0, 0, 133, 136, 3, 24, 12, 0, 134, 136, 5, 13, - 0, 0, 135, 133, 1, 0, 0, 0, 135, 134, 1, 0, 0, 0, 136, 27, 1, 0, 0, 0, - 17, 29, 34, 37, 42, 48, 57, 66, 69, 75, 90, 98, 100, 114, 118, 123, 131, - 135, + 10, 2, 11, 7, 11, 2, 12, 7, 12, 2, 13, 7, 13, 2, 14, 7, 14, 1, 0, 3, 0, + 32, 8, 0, 1, 0, 4, 0, 35, 8, 0, 11, 0, 12, 0, 36, 1, 0, 3, 0, 40, 8, 0, + 1, 0, 5, 0, 43, 8, 0, 10, 0, 12, 0, 46, 9, 0, 1, 0, 5, 0, 49, 8, 0, 10, + 0, 12, 0, 52, 9, 0, 1, 0, 1, 0, 1, 1, 3, 1, 57, 8, 1, 1, 1, 3, 1, 60, 8, + 1, 1, 1, 5, 1, 63, 8, 1, 10, 1, 12, 1, 66, 9, 1, 1, 1, 1, 1, 1, 2, 1, 2, + 1, 2, 1, 2, 3, 2, 74, 8, 2, 1, 3, 1, 3, 1, 3, 1, 4, 1, 4, 1, 4, 1, 4, 3, + 4, 83, 8, 4, 1, 4, 3, 4, 86, 8, 4, 1, 4, 1, 4, 1, 4, 1, 4, 3, 4, 92, 8, + 4, 1, 5, 1, 5, 1, 6, 1, 6, 1, 6, 1, 6, 1, 6, 1, 6, 1, 6, 1, 6, 1, 6, 1, + 6, 1, 6, 3, 6, 107, 8, 6, 1, 6, 1, 6, 1, 6, 1, 6, 1, 6, 1, 6, 5, 6, 115, + 8, 6, 10, 6, 12, 6, 118, 9, 6, 1, 7, 1, 7, 1, 7, 1, 7, 1, 7, 1, 8, 1, 8, + 1, 8, 1, 8, 1, 8, 1, 8, 3, 8, 131, 8, 8, 1, 9, 1, 9, 3, 9, 135, 8, 9, 1, + 10, 1, 10, 1, 10, 3, 10, 140, 8, 10, 1, 11, 1, 11, 1, 12, 1, 12, 1, 13, + 1, 13, 3, 13, 148, 8, 13, 1, 14, 1, 14, 3, 14, 152, 8, 14, 1, 14, 0, 1, + 12, 15, 0, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 0, 3, 1, + 0, 14, 15, 1, 0, 20, 21, 2, 0, 6, 8, 10, 12, 160, 0, 31, 1, 0, 0, 0, 2, + 56, 1, 0, 0, 0, 4, 69, 1, 0, 0, 0, 6, 75, 1, 0, 0, 0, 8, 78, 1, 0, 0, 0, + 10, 93, 1, 0, 0, 0, 12, 106, 1, 0, 0, 0, 14, 119, 1, 0, 0, 0, 16, 130, + 1, 0, 0, 0, 18, 134, 1, 0, 0, 0, 20, 139, 1, 0, 0, 0, 22, 141, 1, 0, 0, + 0, 24, 143, 1, 0, 0, 0, 26, 147, 1, 0, 0, 0, 28, 151, 1, 0, 0, 0, 30, 32, + 5, 5, 0, 0, 31, 30, 1, 0, 0, 0, 31, 32, 1, 0, 0, 0, 32, 34, 1, 0, 0, 0, + 33, 35, 3, 4, 2, 0, 34, 33, 1, 0, 0, 0, 35, 36, 1, 0, 0, 0, 36, 34, 1, + 0, 0, 0, 36, 37, 1, 0, 0, 0, 37, 39, 1, 0, 0, 0, 38, 40, 3, 6, 3, 0, 39, + 38, 1, 0, 0, 0, 39, 40, 1, 0, 0, 0, 40, 44, 1, 0, 0, 0, 41, 43, 3, 8, 4, + 0, 42, 41, 1, 0, 0, 0, 43, 46, 1, 0, 0, 0, 44, 42, 1, 0, 0, 0, 44, 45, + 1, 0, 0, 0, 45, 50, 1, 0, 0, 0, 46, 44, 1, 0, 0, 0, 47, 49, 3, 14, 7, 0, + 48, 47, 1, 0, 0, 0, 49, 52, 1, 0, 0, 0, 50, 48, 1, 0, 0, 0, 50, 51, 1, + 0, 0, 0, 51, 53, 1, 0, 0, 0, 52, 50, 1, 0, 0, 0, 53, 54, 5, 0, 0, 1, 54, + 1, 1, 0, 0, 0, 55, 57, 3, 6, 3, 0, 56, 55, 1, 0, 0, 0, 56, 57, 1, 0, 0, + 0, 57, 59, 1, 0, 0, 0, 58, 60, 3, 8, 4, 0, 59, 58, 1, 0, 0, 0, 59, 60, + 1, 0, 0, 0, 60, 64, 1, 0, 0, 0, 61, 63, 3, 14, 7, 0, 62, 61, 1, 0, 0, 0, + 63, 66, 1, 0, 0, 0, 64, 62, 1, 0, 0, 0, 64, 65, 1, 0, 0, 0, 65, 67, 1, + 0, 0, 0, 66, 64, 1, 0, 0, 0, 67, 68, 5, 0, 0, 1, 68, 3, 1, 0, 0, 0, 69, + 70, 5, 6, 0, 0, 70, 73, 5, 20, 0, 0, 71, 72, 5, 7, 0, 0, 72, 74, 3, 26, + 13, 0, 73, 71, 1, 0, 0, 0, 73, 74, 1, 0, 0, 0, 74, 5, 1, 0, 0, 0, 75, 76, + 5, 9, 0, 0, 76, 77, 5, 20, 0, 0, 77, 7, 1, 0, 0, 0, 78, 79, 5, 10, 0, 0, + 79, 85, 5, 20, 0, 0, 80, 82, 5, 7, 0, 0, 81, 83, 3, 10, 5, 0, 82, 81, 1, + 0, 0, 0, 82, 83, 1, 0, 0, 0, 83, 84, 1, 0, 0, 0, 84, 86, 3, 26, 13, 0, + 85, 80, 1, 0, 0, 0, 85, 86, 1, 0, 0, 0, 86, 87, 1, 0, 0, 0, 87, 88, 5, + 11, 0, 0, 88, 91, 3, 28, 14, 0, 89, 90, 5, 8, 0, 0, 90, 92, 3, 26, 13, + 0, 91, 89, 1, 0, 0, 0, 91, 92, 1, 0, 0, 0, 92, 9, 1, 0, 0, 0, 93, 94, 7, + 0, 0, 0, 94, 11, 1, 0, 0, 0, 95, 96, 6, 6, -1, 0, 96, 97, 5, 1, 0, 0, 97, + 98, 5, 16, 0, 0, 98, 99, 3, 12, 6, 0, 99, 100, 5, 17, 0, 0, 100, 107, 1, + 0, 0, 0, 101, 102, 5, 16, 0, 0, 102, 103, 3, 12, 6, 0, 103, 104, 5, 17, + 0, 0, 104, 107, 1, 0, 0, 0, 105, 107, 3, 16, 8, 0, 106, 95, 1, 0, 0, 0, + 106, 101, 1, 0, 0, 0, 106, 105, 1, 0, 0, 0, 107, 116, 1, 0, 0, 0, 108, + 109, 10, 4, 0, 0, 109, 110, 5, 2, 0, 0, 110, 115, 3, 12, 6, 5, 111, 112, + 10, 3, 0, 0, 112, 113, 5, 3, 0, 0, 113, 115, 3, 12, 6, 4, 114, 108, 1, + 0, 0, 0, 114, 111, 1, 0, 0, 0, 115, 118, 1, 0, 0, 0, 116, 114, 1, 0, 0, + 0, 116, 117, 1, 0, 0, 0, 117, 13, 1, 0, 0, 0, 118, 116, 1, 0, 0, 0, 119, + 120, 5, 12, 0, 0, 120, 121, 3, 12, 6, 0, 121, 122, 5, 8, 0, 0, 122, 123, + 3, 26, 13, 0, 123, 15, 1, 0, 0, 0, 124, 125, 5, 18, 0, 0, 125, 131, 3, + 26, 13, 0, 126, 127, 3, 18, 9, 0, 127, 128, 5, 4, 0, 0, 128, 129, 3, 20, + 10, 0, 129, 131, 1, 0, 0, 0, 130, 124, 1, 0, 0, 0, 130, 126, 1, 0, 0, 0, + 131, 17, 1, 0, 0, 0, 132, 135, 3, 26, 13, 0, 133, 135, 5, 22, 0, 0, 134, + 132, 1, 0, 0, 0, 134, 133, 1, 0, 0, 0, 135, 19, 1, 0, 0, 0, 136, 140, 3, + 26, 13, 0, 137, 140, 3, 22, 11, 0, 138, 140, 5, 22, 0, 0, 139, 136, 1, + 0, 0, 0, 139, 137, 1, 0, 0, 0, 139, 138, 1, 0, 0, 0, 140, 21, 1, 0, 0, + 0, 141, 142, 7, 1, 0, 0, 142, 23, 1, 0, 0, 0, 143, 144, 7, 2, 0, 0, 144, + 25, 1, 0, 0, 0, 145, 148, 3, 24, 12, 0, 146, 148, 5, 19, 0, 0, 147, 145, + 1, 0, 0, 0, 147, 146, 1, 0, 0, 0, 148, 27, 1, 0, 0, 0, 149, 152, 3, 26, + 13, 0, 150, 152, 5, 13, 0, 0, 151, 149, 1, 0, 0, 0, 151, 150, 1, 0, 0, + 0, 152, 29, 1, 0, 0, 0, 20, 31, 36, 39, 44, 50, 56, 59, 64, 73, 82, 85, + 91, 106, 114, 116, 130, 134, 139, 147, 151, } deserializer := antlr.NewATNDeserializer(nil) staticData.atn = deserializer.Deserialize(staticData.serializedATN) @@ -173,20 +180,21 @@ const ( // Query rules. const ( - QueryRULE_policy = 0 - QueryRULE_repStmt = 1 - QueryRULE_cbfStmt = 2 - QueryRULE_selectStmt = 3 - QueryRULE_clause = 4 - QueryRULE_filterExpr = 5 - QueryRULE_filterStmt = 6 - QueryRULE_expr = 7 - QueryRULE_filterKey = 8 - QueryRULE_filterValue = 9 - QueryRULE_number = 10 - QueryRULE_keyword = 11 - QueryRULE_ident = 12 - QueryRULE_identWC = 13 + QueryRULE_policy = 0 + QueryRULE_selectFilterExpr = 1 + QueryRULE_repStmt = 2 + QueryRULE_cbfStmt = 3 + QueryRULE_selectStmt = 4 + QueryRULE_clause = 5 + QueryRULE_filterExpr = 6 + QueryRULE_filterStmt = 7 + QueryRULE_expr = 8 + QueryRULE_filterKey = 9 + QueryRULE_filterValue = 10 + QueryRULE_number = 11 + QueryRULE_keyword = 12 + QueryRULE_ident = 13 + QueryRULE_identWC = 14 ) // IPolicyContext is an interface to support dynamic dispatch. @@ -414,7 +422,7 @@ func (p *Query) Policy() (localctx IPolicyContext) { var _la int p.EnterOuterAlt(localctx, 1) - p.SetState(29) + p.SetState(31) p.GetErrorHandler().Sync(p) if p.HasError() { goto errorExit @@ -423,7 +431,7 @@ func (p *Query) Policy() (localctx IPolicyContext) { if _la == QueryUNIQUE { { - p.SetState(28) + p.SetState(30) p.Match(QueryUNIQUE) if p.HasError() { // Recognition error - abort rule @@ -432,7 +440,7 @@ func (p *Query) Policy() (localctx IPolicyContext) { } } - p.SetState(32) + p.SetState(34) p.GetErrorHandler().Sync(p) if p.HasError() { goto errorExit @@ -441,18 +449,18 @@ func (p *Query) Policy() (localctx IPolicyContext) { for ok := true; ok; ok = _la == QueryREP { { - p.SetState(31) + p.SetState(33) p.RepStmt() } - p.SetState(34) + p.SetState(36) p.GetErrorHandler().Sync(p) if p.HasError() { goto errorExit } _la = p.GetTokenStream().LA(1) } - p.SetState(37) + p.SetState(39) p.GetErrorHandler().Sync(p) if p.HasError() { goto errorExit @@ -461,12 +469,12 @@ func (p *Query) Policy() (localctx IPolicyContext) { if _la == QueryCBF { { - p.SetState(36) + p.SetState(38) p.CbfStmt() } } - p.SetState(42) + p.SetState(44) p.GetErrorHandler().Sync(p) if p.HasError() { goto errorExit @@ -475,18 +483,18 @@ func (p *Query) Policy() (localctx IPolicyContext) { for _la == QuerySELECT { { - p.SetState(39) + p.SetState(41) p.SelectStmt() } - p.SetState(44) + p.SetState(46) p.GetErrorHandler().Sync(p) if p.HasError() { goto errorExit } _la = p.GetTokenStream().LA(1) } - p.SetState(48) + p.SetState(50) p.GetErrorHandler().Sync(p) if p.HasError() { goto errorExit @@ -495,11 +503,11 @@ func (p *Query) Policy() (localctx IPolicyContext) { for _la == QueryFILTER { { - p.SetState(45) + p.SetState(47) p.FilterStmt() } - p.SetState(50) + p.SetState(52) p.GetErrorHandler().Sync(p) if p.HasError() { goto errorExit @@ -507,7 +515,228 @@ func (p *Query) Policy() (localctx IPolicyContext) { _la = p.GetTokenStream().LA(1) } { - p.SetState(51) + p.SetState(53) + p.Match(QueryEOF) + if p.HasError() { + // Recognition error - abort rule + goto errorExit + } + } + +errorExit: + if p.HasError() { + v := p.GetError() + localctx.SetException(v) + p.GetErrorHandler().ReportError(p, v) + p.GetErrorHandler().Recover(p, v) + p.SetError(nil) + } + p.ExitRule() + return localctx + goto errorExit // Trick to prevent compiler error if the label is not used +} + +// ISelectFilterExprContext is an interface to support dynamic dispatch. +type ISelectFilterExprContext interface { + antlr.ParserRuleContext + + // GetParser returns the parser. + GetParser() antlr.Parser + + // Getter signatures + EOF() antlr.TerminalNode + CbfStmt() ICbfStmtContext + SelectStmt() ISelectStmtContext + AllFilterStmt() []IFilterStmtContext + FilterStmt(i int) IFilterStmtContext + + // IsSelectFilterExprContext differentiates from other interfaces. + IsSelectFilterExprContext() +} + +type SelectFilterExprContext struct { + antlr.BaseParserRuleContext + parser antlr.Parser +} + +func NewEmptySelectFilterExprContext() *SelectFilterExprContext { + var p = new(SelectFilterExprContext) + antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1) + p.RuleIndex = QueryRULE_selectFilterExpr + return p +} + +func InitEmptySelectFilterExprContext(p *SelectFilterExprContext) { + antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1) + p.RuleIndex = QueryRULE_selectFilterExpr +} + +func (*SelectFilterExprContext) IsSelectFilterExprContext() {} + +func NewSelectFilterExprContext(parser antlr.Parser, parent antlr.ParserRuleContext, invokingState int) *SelectFilterExprContext { + var p = new(SelectFilterExprContext) + + antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, parent, invokingState) + + p.parser = parser + p.RuleIndex = QueryRULE_selectFilterExpr + + return p +} + +func (s *SelectFilterExprContext) GetParser() antlr.Parser { return s.parser } + +func (s *SelectFilterExprContext) EOF() antlr.TerminalNode { + return s.GetToken(QueryEOF, 0) +} + +func (s *SelectFilterExprContext) CbfStmt() ICbfStmtContext { + var t antlr.RuleContext + for _, ctx := range s.GetChildren() { + if _, ok := ctx.(ICbfStmtContext); ok { + t = ctx.(antlr.RuleContext) + break + } + } + + if t == nil { + return nil + } + + return t.(ICbfStmtContext) +} + +func (s *SelectFilterExprContext) SelectStmt() ISelectStmtContext { + var t antlr.RuleContext + for _, ctx := range s.GetChildren() { + if _, ok := ctx.(ISelectStmtContext); ok { + t = ctx.(antlr.RuleContext) + break + } + } + + if t == nil { + return nil + } + + return t.(ISelectStmtContext) +} + +func (s *SelectFilterExprContext) AllFilterStmt() []IFilterStmtContext { + children := s.GetChildren() + len := 0 + for _, ctx := range children { + if _, ok := ctx.(IFilterStmtContext); ok { + len++ + } + } + + tst := make([]IFilterStmtContext, len) + i := 0 + for _, ctx := range children { + if t, ok := ctx.(IFilterStmtContext); ok { + tst[i] = t.(IFilterStmtContext) + i++ + } + } + + return tst +} + +func (s *SelectFilterExprContext) FilterStmt(i int) IFilterStmtContext { + var t antlr.RuleContext + j := 0 + for _, ctx := range s.GetChildren() { + if _, ok := ctx.(IFilterStmtContext); ok { + if j == i { + t = ctx.(antlr.RuleContext) + break + } + j++ + } + } + + if t == nil { + return nil + } + + return t.(IFilterStmtContext) +} + +func (s *SelectFilterExprContext) GetRuleContext() antlr.RuleContext { + return s +} + +func (s *SelectFilterExprContext) ToStringTree(ruleNames []string, recog antlr.Recognizer) string { + return antlr.TreesStringTree(s, ruleNames, recog) +} + +func (s *SelectFilterExprContext) Accept(visitor antlr.ParseTreeVisitor) interface{} { + switch t := visitor.(type) { + case QueryVisitor: + return t.VisitSelectFilterExpr(s) + + default: + return t.VisitChildren(s) + } +} + +func (p *Query) SelectFilterExpr() (localctx ISelectFilterExprContext) { + localctx = NewSelectFilterExprContext(p, p.GetParserRuleContext(), p.GetState()) + p.EnterRule(localctx, 2, QueryRULE_selectFilterExpr) + var _la int + + p.EnterOuterAlt(localctx, 1) + p.SetState(56) + p.GetErrorHandler().Sync(p) + if p.HasError() { + goto errorExit + } + _la = p.GetTokenStream().LA(1) + + if _la == QueryCBF { + { + p.SetState(55) + p.CbfStmt() + } + + } + p.SetState(59) + p.GetErrorHandler().Sync(p) + if p.HasError() { + goto errorExit + } + _la = p.GetTokenStream().LA(1) + + if _la == QuerySELECT { + { + p.SetState(58) + p.SelectStmt() + } + + } + p.SetState(64) + p.GetErrorHandler().Sync(p) + if p.HasError() { + goto errorExit + } + _la = p.GetTokenStream().LA(1) + + for _la == QueryFILTER { + { + p.SetState(61) + p.FilterStmt() + } + + p.SetState(66) + p.GetErrorHandler().Sync(p) + if p.HasError() { + goto errorExit + } + _la = p.GetTokenStream().LA(1) + } + { + p.SetState(67) p.Match(QueryEOF) if p.HasError() { // Recognition error - abort rule @@ -647,12 +876,12 @@ func (s *RepStmtContext) Accept(visitor antlr.ParseTreeVisitor) interface{} { func (p *Query) RepStmt() (localctx IRepStmtContext) { localctx = NewRepStmtContext(p, p.GetParserRuleContext(), p.GetState()) - p.EnterRule(localctx, 2, QueryRULE_repStmt) + p.EnterRule(localctx, 4, QueryRULE_repStmt) var _la int p.EnterOuterAlt(localctx, 1) { - p.SetState(53) + p.SetState(69) p.Match(QueryREP) if p.HasError() { // Recognition error - abort rule @@ -660,7 +889,7 @@ func (p *Query) RepStmt() (localctx IRepStmtContext) { } } { - p.SetState(54) + p.SetState(70) var _m = p.Match(QueryNUMBER1) @@ -670,7 +899,7 @@ func (p *Query) RepStmt() (localctx IRepStmtContext) { goto errorExit } } - p.SetState(57) + p.SetState(73) p.GetErrorHandler().Sync(p) if p.HasError() { goto errorExit @@ -679,7 +908,7 @@ func (p *Query) RepStmt() (localctx IRepStmtContext) { if _la == QueryIN { { - p.SetState(55) + p.SetState(71) p.Match(QueryIN) if p.HasError() { // Recognition error - abort rule @@ -687,7 +916,7 @@ func (p *Query) RepStmt() (localctx IRepStmtContext) { } } { - p.SetState(56) + p.SetState(72) var _x = p.Ident() @@ -795,10 +1024,10 @@ func (s *CbfStmtContext) Accept(visitor antlr.ParseTreeVisitor) interface{} { func (p *Query) CbfStmt() (localctx ICbfStmtContext) { localctx = NewCbfStmtContext(p, p.GetParserRuleContext(), p.GetState()) - p.EnterRule(localctx, 4, QueryRULE_cbfStmt) + p.EnterRule(localctx, 6, QueryRULE_cbfStmt) p.EnterOuterAlt(localctx, 1) { - p.SetState(59) + p.SetState(75) p.Match(QueryCBF) if p.HasError() { // Recognition error - abort rule @@ -806,7 +1035,7 @@ func (p *Query) CbfStmt() (localctx ICbfStmtContext) { } } { - p.SetState(60) + p.SetState(76) var _m = p.Match(QueryNUMBER1) @@ -1041,12 +1270,12 @@ func (s *SelectStmtContext) Accept(visitor antlr.ParseTreeVisitor) interface{} { func (p *Query) SelectStmt() (localctx ISelectStmtContext) { localctx = NewSelectStmtContext(p, p.GetParserRuleContext(), p.GetState()) - p.EnterRule(localctx, 6, QueryRULE_selectStmt) + p.EnterRule(localctx, 8, QueryRULE_selectStmt) var _la int p.EnterOuterAlt(localctx, 1) { - p.SetState(62) + p.SetState(78) p.Match(QuerySELECT) if p.HasError() { // Recognition error - abort rule @@ -1054,7 +1283,7 @@ func (p *Query) SelectStmt() (localctx ISelectStmtContext) { } } { - p.SetState(63) + p.SetState(79) var _m = p.Match(QueryNUMBER1) @@ -1064,7 +1293,7 @@ func (p *Query) SelectStmt() (localctx ISelectStmtContext) { goto errorExit } } - p.SetState(69) + p.SetState(85) p.GetErrorHandler().Sync(p) if p.HasError() { goto errorExit @@ -1073,14 +1302,14 @@ func (p *Query) SelectStmt() (localctx ISelectStmtContext) { if _la == QueryIN { { - p.SetState(64) + p.SetState(80) p.Match(QueryIN) if p.HasError() { // Recognition error - abort rule goto errorExit } } - p.SetState(66) + p.SetState(82) p.GetErrorHandler().Sync(p) if p.HasError() { goto errorExit @@ -1089,13 +1318,13 @@ func (p *Query) SelectStmt() (localctx ISelectStmtContext) { if _la == QueryCLAUSE_SAME || _la == QueryCLAUSE_DISTINCT { { - p.SetState(65) + p.SetState(81) p.Clause() } } { - p.SetState(68) + p.SetState(84) var _x = p.Ident() @@ -1104,7 +1333,7 @@ func (p *Query) SelectStmt() (localctx ISelectStmtContext) { } { - p.SetState(71) + p.SetState(87) p.Match(QueryFROM) if p.HasError() { // Recognition error - abort rule @@ -1112,13 +1341,13 @@ func (p *Query) SelectStmt() (localctx ISelectStmtContext) { } } { - p.SetState(72) + p.SetState(88) var _x = p.IdentWC() localctx.(*SelectStmtContext).Filter = _x } - p.SetState(75) + p.SetState(91) p.GetErrorHandler().Sync(p) if p.HasError() { goto errorExit @@ -1127,7 +1356,7 @@ func (p *Query) SelectStmt() (localctx ISelectStmtContext) { if _la == QueryAS { { - p.SetState(73) + p.SetState(89) p.Match(QueryAS) if p.HasError() { // Recognition error - abort rule @@ -1135,7 +1364,7 @@ func (p *Query) SelectStmt() (localctx ISelectStmtContext) { } } { - p.SetState(74) + p.SetState(90) var _x = p.Ident() @@ -1232,12 +1461,12 @@ func (s *ClauseContext) Accept(visitor antlr.ParseTreeVisitor) interface{} { func (p *Query) Clause() (localctx IClauseContext) { localctx = NewClauseContext(p, p.GetParserRuleContext(), p.GetState()) - p.EnterRule(localctx, 8, QueryRULE_clause) + p.EnterRule(localctx, 10, QueryRULE_clause) var _la int p.EnterOuterAlt(localctx, 1) { - p.SetState(77) + p.SetState(93) _la = p.GetTokenStream().LA(1) if !(_la == QueryCLAUSE_SAME || _la == QueryCLAUSE_DISTINCT) { @@ -1464,12 +1693,12 @@ func (p *Query) filterExpr(_p int) (localctx IFilterExprContext) { localctx = NewFilterExprContext(p, p.GetParserRuleContext(), _parentState) var _prevctx IFilterExprContext = localctx var _ antlr.ParserRuleContext = _prevctx // TODO: To prevent unused variable warning. - _startState := 10 - p.EnterRecursionRule(localctx, 10, QueryRULE_filterExpr, _p) + _startState := 12 + p.EnterRecursionRule(localctx, 12, QueryRULE_filterExpr, _p) var _alt int p.EnterOuterAlt(localctx, 1) - p.SetState(90) + p.SetState(106) p.GetErrorHandler().Sync(p) if p.HasError() { goto errorExit @@ -1478,7 +1707,7 @@ func (p *Query) filterExpr(_p int) (localctx IFilterExprContext) { switch p.GetTokenStream().LA(1) { case QueryNOT_OP: { - p.SetState(80) + p.SetState(96) var _m = p.Match(QueryNOT_OP) @@ -1489,7 +1718,7 @@ func (p *Query) filterExpr(_p int) (localctx IFilterExprContext) { } } { - p.SetState(81) + p.SetState(97) p.Match(QueryL_PAREN) if p.HasError() { // Recognition error - abort rule @@ -1497,14 +1726,14 @@ func (p *Query) filterExpr(_p int) (localctx IFilterExprContext) { } } { - p.SetState(82) + p.SetState(98) var _x = p.filterExpr(0) localctx.(*FilterExprContext).F1 = _x } { - p.SetState(83) + p.SetState(99) p.Match(QueryR_PAREN) if p.HasError() { // Recognition error - abort rule @@ -1514,7 +1743,7 @@ func (p *Query) filterExpr(_p int) (localctx IFilterExprContext) { case QueryL_PAREN: { - p.SetState(85) + p.SetState(101) p.Match(QueryL_PAREN) if p.HasError() { // Recognition error - abort rule @@ -1522,14 +1751,14 @@ func (p *Query) filterExpr(_p int) (localctx IFilterExprContext) { } } { - p.SetState(86) + p.SetState(102) var _x = p.filterExpr(0) localctx.(*FilterExprContext).Inner = _x } { - p.SetState(87) + p.SetState(103) p.Match(QueryR_PAREN) if p.HasError() { // Recognition error - abort rule @@ -1539,7 +1768,7 @@ func (p *Query) filterExpr(_p int) (localctx IFilterExprContext) { case QueryREP, QueryIN, QueryAS, QuerySELECT, QueryFROM, QueryFILTER, QueryAT, QueryIDENT, QuerySTRING: { - p.SetState(89) + p.SetState(105) p.Expr() } @@ -1548,12 +1777,12 @@ func (p *Query) filterExpr(_p int) (localctx IFilterExprContext) { goto errorExit } p.GetParserRuleContext().SetStop(p.GetTokenStream().LT(-1)) - p.SetState(100) + p.SetState(116) p.GetErrorHandler().Sync(p) if p.HasError() { goto errorExit } - _alt = p.GetInterpreter().AdaptivePredict(p.BaseParser, p.GetTokenStream(), 11, p.GetParserRuleContext()) + _alt = p.GetInterpreter().AdaptivePredict(p.BaseParser, p.GetTokenStream(), 14, p.GetParserRuleContext()) if p.HasError() { goto errorExit } @@ -1563,25 +1792,25 @@ func (p *Query) filterExpr(_p int) (localctx IFilterExprContext) { p.TriggerExitRuleEvent() } _prevctx = localctx - p.SetState(98) + p.SetState(114) p.GetErrorHandler().Sync(p) if p.HasError() { goto errorExit } - switch p.GetInterpreter().AdaptivePredict(p.BaseParser, p.GetTokenStream(), 10, p.GetParserRuleContext()) { + switch p.GetInterpreter().AdaptivePredict(p.BaseParser, p.GetTokenStream(), 13, p.GetParserRuleContext()) { case 1: localctx = NewFilterExprContext(p, _parentctx, _parentState) localctx.(*FilterExprContext).F1 = _prevctx p.PushNewRecursionContext(localctx, _startState, QueryRULE_filterExpr) - p.SetState(92) + p.SetState(108) if !(p.Precpred(p.GetParserRuleContext(), 4)) { p.SetError(antlr.NewFailedPredicateException(p, "p.Precpred(p.GetParserRuleContext(), 4)", "")) goto errorExit } { - p.SetState(93) + p.SetState(109) var _m = p.Match(QueryAND_OP) @@ -1592,7 +1821,7 @@ func (p *Query) filterExpr(_p int) (localctx IFilterExprContext) { } } { - p.SetState(94) + p.SetState(110) var _x = p.filterExpr(5) @@ -1603,14 +1832,14 @@ func (p *Query) filterExpr(_p int) (localctx IFilterExprContext) { localctx = NewFilterExprContext(p, _parentctx, _parentState) localctx.(*FilterExprContext).F1 = _prevctx p.PushNewRecursionContext(localctx, _startState, QueryRULE_filterExpr) - p.SetState(95) + p.SetState(111) if !(p.Precpred(p.GetParserRuleContext(), 3)) { p.SetError(antlr.NewFailedPredicateException(p, "p.Precpred(p.GetParserRuleContext(), 3)", "")) goto errorExit } { - p.SetState(96) + p.SetState(112) var _m = p.Match(QueryOR_OP) @@ -1621,7 +1850,7 @@ func (p *Query) filterExpr(_p int) (localctx IFilterExprContext) { } } { - p.SetState(97) + p.SetState(113) var _x = p.filterExpr(4) @@ -1633,12 +1862,12 @@ func (p *Query) filterExpr(_p int) (localctx IFilterExprContext) { } } - p.SetState(102) + p.SetState(118) p.GetErrorHandler().Sync(p) if p.HasError() { goto errorExit } - _alt = p.GetInterpreter().AdaptivePredict(p.BaseParser, p.GetTokenStream(), 11, p.GetParserRuleContext()) + _alt = p.GetInterpreter().AdaptivePredict(p.BaseParser, p.GetTokenStream(), 14, p.GetParserRuleContext()) if p.HasError() { goto errorExit } @@ -1788,10 +2017,10 @@ func (s *FilterStmtContext) Accept(visitor antlr.ParseTreeVisitor) interface{} { func (p *Query) FilterStmt() (localctx IFilterStmtContext) { localctx = NewFilterStmtContext(p, p.GetParserRuleContext(), p.GetState()) - p.EnterRule(localctx, 12, QueryRULE_filterStmt) + p.EnterRule(localctx, 14, QueryRULE_filterStmt) p.EnterOuterAlt(localctx, 1) { - p.SetState(103) + p.SetState(119) p.Match(QueryFILTER) if p.HasError() { // Recognition error - abort rule @@ -1799,14 +2028,14 @@ func (p *Query) FilterStmt() (localctx IFilterStmtContext) { } } { - p.SetState(104) + p.SetState(120) var _x = p.filterExpr(0) localctx.(*FilterStmtContext).Expr = _x } { - p.SetState(105) + p.SetState(121) p.Match(QueryAS) if p.HasError() { // Recognition error - abort rule @@ -1814,7 +2043,7 @@ func (p *Query) FilterStmt() (localctx IFilterStmtContext) { } } { - p.SetState(106) + p.SetState(122) var _x = p.Ident() @@ -1993,8 +2222,8 @@ func (s *ExprContext) Accept(visitor antlr.ParseTreeVisitor) interface{} { func (p *Query) Expr() (localctx IExprContext) { localctx = NewExprContext(p, p.GetParserRuleContext(), p.GetState()) - p.EnterRule(localctx, 14, QueryRULE_expr) - p.SetState(114) + p.EnterRule(localctx, 16, QueryRULE_expr) + p.SetState(130) p.GetErrorHandler().Sync(p) if p.HasError() { goto errorExit @@ -2004,7 +2233,7 @@ func (p *Query) Expr() (localctx IExprContext) { case QueryAT: p.EnterOuterAlt(localctx, 1) { - p.SetState(108) + p.SetState(124) p.Match(QueryAT) if p.HasError() { // Recognition error - abort rule @@ -2012,7 +2241,7 @@ func (p *Query) Expr() (localctx IExprContext) { } } { - p.SetState(109) + p.SetState(125) var _x = p.Ident() @@ -2022,14 +2251,14 @@ func (p *Query) Expr() (localctx IExprContext) { case QueryREP, QueryIN, QueryAS, QuerySELECT, QueryFROM, QueryFILTER, QueryIDENT, QuerySTRING: p.EnterOuterAlt(localctx, 2) { - p.SetState(110) + p.SetState(126) var _x = p.FilterKey() localctx.(*ExprContext).Key = _x } { - p.SetState(111) + p.SetState(127) p.Match(QuerySIMPLE_OP) if p.HasError() { // Recognition error - abort rule @@ -2037,7 +2266,7 @@ func (p *Query) Expr() (localctx IExprContext) { } } { - p.SetState(112) + p.SetState(128) var _x = p.FilterValue() @@ -2149,8 +2378,8 @@ func (s *FilterKeyContext) Accept(visitor antlr.ParseTreeVisitor) interface{} { func (p *Query) FilterKey() (localctx IFilterKeyContext) { localctx = NewFilterKeyContext(p, p.GetParserRuleContext(), p.GetState()) - p.EnterRule(localctx, 16, QueryRULE_filterKey) - p.SetState(118) + p.EnterRule(localctx, 18, QueryRULE_filterKey) + p.SetState(134) p.GetErrorHandler().Sync(p) if p.HasError() { goto errorExit @@ -2160,14 +2389,14 @@ func (p *Query) FilterKey() (localctx IFilterKeyContext) { case QueryREP, QueryIN, QueryAS, QuerySELECT, QueryFROM, QueryFILTER, QueryIDENT: p.EnterOuterAlt(localctx, 1) { - p.SetState(116) + p.SetState(132) p.Ident() } case QuerySTRING: p.EnterOuterAlt(localctx, 2) { - p.SetState(117) + p.SetState(133) p.Match(QuerySTRING) if p.HasError() { // Recognition error - abort rule @@ -2297,8 +2526,8 @@ func (s *FilterValueContext) Accept(visitor antlr.ParseTreeVisitor) interface{} func (p *Query) FilterValue() (localctx IFilterValueContext) { localctx = NewFilterValueContext(p, p.GetParserRuleContext(), p.GetState()) - p.EnterRule(localctx, 18, QueryRULE_filterValue) - p.SetState(123) + p.EnterRule(localctx, 20, QueryRULE_filterValue) + p.SetState(139) p.GetErrorHandler().Sync(p) if p.HasError() { goto errorExit @@ -2308,21 +2537,21 @@ func (p *Query) FilterValue() (localctx IFilterValueContext) { case QueryREP, QueryIN, QueryAS, QuerySELECT, QueryFROM, QueryFILTER, QueryIDENT: p.EnterOuterAlt(localctx, 1) { - p.SetState(120) + p.SetState(136) p.Ident() } case QueryNUMBER1, QueryZERO: p.EnterOuterAlt(localctx, 2) { - p.SetState(121) + p.SetState(137) p.Number() } case QuerySTRING: p.EnterOuterAlt(localctx, 3) { - p.SetState(122) + p.SetState(138) p.Match(QuerySTRING) if p.HasError() { // Recognition error - abort rule @@ -2423,12 +2652,12 @@ func (s *NumberContext) Accept(visitor antlr.ParseTreeVisitor) interface{} { func (p *Query) Number() (localctx INumberContext) { localctx = NewNumberContext(p, p.GetParserRuleContext(), p.GetState()) - p.EnterRule(localctx, 20, QueryRULE_number) + p.EnterRule(localctx, 22, QueryRULE_number) var _la int p.EnterOuterAlt(localctx, 1) { - p.SetState(125) + p.SetState(141) _la = p.GetTokenStream().LA(1) if !(_la == QueryNUMBER1 || _la == QueryZERO) { @@ -2547,12 +2776,12 @@ func (s *KeywordContext) Accept(visitor antlr.ParseTreeVisitor) interface{} { func (p *Query) Keyword() (localctx IKeywordContext) { localctx = NewKeywordContext(p, p.GetParserRuleContext(), p.GetState()) - p.EnterRule(localctx, 22, QueryRULE_keyword) + p.EnterRule(localctx, 24, QueryRULE_keyword) var _la int p.EnterOuterAlt(localctx, 1) { - p.SetState(127) + p.SetState(143) _la = p.GetTokenStream().LA(1) if !((int64(_la) & ^0x3f) == 0 && ((int64(1)<<_la)&7616) != 0) { @@ -2663,8 +2892,8 @@ func (s *IdentContext) Accept(visitor antlr.ParseTreeVisitor) interface{} { func (p *Query) Ident() (localctx IIdentContext) { localctx = NewIdentContext(p, p.GetParserRuleContext(), p.GetState()) - p.EnterRule(localctx, 24, QueryRULE_ident) - p.SetState(131) + p.EnterRule(localctx, 26, QueryRULE_ident) + p.SetState(147) p.GetErrorHandler().Sync(p) if p.HasError() { goto errorExit @@ -2674,14 +2903,14 @@ func (p *Query) Ident() (localctx IIdentContext) { case QueryREP, QueryIN, QueryAS, QuerySELECT, QueryFROM, QueryFILTER: p.EnterOuterAlt(localctx, 1) { - p.SetState(129) + p.SetState(145) p.Keyword() } case QueryIDENT: p.EnterOuterAlt(localctx, 2) { - p.SetState(130) + p.SetState(146) p.Match(QueryIDENT) if p.HasError() { // Recognition error - abort rule @@ -2794,8 +3023,8 @@ func (s *IdentWCContext) Accept(visitor antlr.ParseTreeVisitor) interface{} { func (p *Query) IdentWC() (localctx IIdentWCContext) { localctx = NewIdentWCContext(p, p.GetParserRuleContext(), p.GetState()) - p.EnterRule(localctx, 26, QueryRULE_identWC) - p.SetState(135) + p.EnterRule(localctx, 28, QueryRULE_identWC) + p.SetState(151) p.GetErrorHandler().Sync(p) if p.HasError() { goto errorExit @@ -2805,14 +3034,14 @@ func (p *Query) IdentWC() (localctx IIdentWCContext) { case QueryREP, QueryIN, QueryAS, QuerySELECT, QueryFROM, QueryFILTER, QueryIDENT: p.EnterOuterAlt(localctx, 1) { - p.SetState(133) + p.SetState(149) p.Ident() } case QueryWILDCARD: p.EnterOuterAlt(localctx, 2) { - p.SetState(134) + p.SetState(150) p.Match(QueryWILDCARD) if p.HasError() { // Recognition error - abort rule @@ -2840,7 +3069,7 @@ errorExit: func (p *Query) Sempred(localctx antlr.RuleContext, ruleIndex, predIndex int) bool { switch ruleIndex { - case 5: + case 6: var t *FilterExprContext = nil if localctx != nil { t = localctx.(*FilterExprContext) diff --git a/netmap/parser/query_visitor.go b/netmap/parser/query_visitor.go index 960dc2f..7550d99 100644 --- a/netmap/parser/query_visitor.go +++ b/netmap/parser/query_visitor.go @@ -11,6 +11,9 @@ type QueryVisitor interface { // Visit a parse tree produced by Query#policy. VisitPolicy(ctx *PolicyContext) interface{} + // Visit a parse tree produced by Query#selectFilterExpr. + VisitSelectFilterExpr(ctx *SelectFilterExprContext) interface{} + // Visit a parse tree produced by Query#repStmt. VisitRepStmt(ctx *RepStmtContext) interface{} diff --git a/netmap/policy.go b/netmap/policy.go index 323050e..d706556 100644 --- a/netmap/policy.go +++ b/netmap/policy.go @@ -560,6 +560,44 @@ func (p *PlacementPolicy) DecodeString(s string) error { return nil } +// SelectFilterExpr is an expression containing only selectors and filters. +// It's useful to evaluate their effect before being used in a policy. +type SelectFilterExpr struct { + cbf uint32 + selector *netmap.Selector + filters []netmap.Filter +} + +// DecodeString decodes a string into a SelectFilterExpr. +// Returns an error if s is malformed. +func DecodeSelectFilterString(s string) (*SelectFilterExpr, error) { + var v policyVisitor + + input := antlr.NewInputStream(s) + lexer := parser.NewQueryLexer(input) + lexer.RemoveErrorListeners() + lexer.AddErrorListener(&v) + stream := antlr.NewCommonTokenStream(lexer, 0) + + pp := parser.NewQuery(stream) + pp.BuildParseTrees = true + + pp.RemoveErrorListeners() + pp.AddErrorListener(&v) + sfExpr := pp.SelectFilterExpr().Accept(&v) + + if len(v.errors) != 0 { + return nil, v.errors[0] + } + + parsed, ok := sfExpr.(*SelectFilterExpr) + if !ok { + return nil, fmt.Errorf("unexpected parsed instance type %T", sfExpr) + } + + return parsed, nil +} + var ( // errUnknownFilter is returned when a value of FROM in a query is unknown. errUnknownFilter = errors.New("filter not found") @@ -636,6 +674,39 @@ func (p *policyVisitor) VisitPolicy(ctx *parser.PolicyContext) any { return pl } +func (p *policyVisitor) VisitSelectFilterExpr(ctx *parser.SelectFilterExprContext) any { + if len(p.errors) != 0 { + return nil + } + + sfExpr := new(SelectFilterExpr) + + if cbfStmt := ctx.CbfStmt(); cbfStmt != nil { + cbf, ok := cbfStmt.(*parser.CbfStmtContext).Accept(p).(uint32) + if !ok { + return nil + } + sfExpr.cbf = cbf + } + + if selStmt := ctx.SelectStmt(); selStmt != nil { + sel, ok := selStmt.Accept(p).(*netmap.Selector) + if !ok { + return nil + } + sfExpr.selector = sel + } + + filtStmts := ctx.AllFilterStmt() + sfExpr.filters = make([]netmap.Filter, 0, len(filtStmts)) + + for _, f := range filtStmts { + sfExpr.filters = append(sfExpr.filters, *f.Accept(p).(*netmap.Filter)) + } + + return sfExpr +} + func (p *policyVisitor) VisitCbfStmt(ctx *parser.CbfStmtContext) any { cbf, err := strconv.ParseUint(ctx.GetBackupFactor().GetText(), 10, 32) if err != nil { diff --git a/netmap/policy_test.go b/netmap/policy_test.go index 98ce5f2..f954eec 100644 --- a/netmap/policy_test.go +++ b/netmap/policy_test.go @@ -78,3 +78,28 @@ func TestPlacementPolicyEncoding(t *testing.T) { require.Equal(t, v, v2) }) } + +func TestDecodeSelectFilterExpr(t *testing.T) { + for _, s := range []string{ + "SELECT 1 FROM *", + "FILTER Color EQ 'Red' AS RedNode", + ` + FILTER Color EQ 'Red' AS RedNode + FILTER @RedNode AND Shape EQ 'Cirle' AS RedCircleNode + `, + ` + SELECT 1 FROM RedCircleNode + FILTER Color EQ 'Red' AS RedNode + FILTER @RedNode AND Shape EQ 'Cirle' AS RedCircleNode + `, + ` + CBF 1 + SELECT 1 FROM RedCircleNode + FILTER Color EQ 'Red' AS RedNode + FILTER @RedNode AND Shape EQ 'Cirle' AS RedCircleNode + `, + } { + _, err := DecodeSelectFilterString(s) + require.NoError(t, err) + } +} -- 2.45.2