• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // -V::802
2 #pragma once
3 #ifndef JQP_H
4 #define JQP_H
5 
6 /**************************************************************************************************
7  * EJDB2
8  *
9  * MIT License
10  *
11  * Copyright (c) 2012-2021 Softmotions Ltd <info@softmotions.com>
12  *
13  * Permission is hereby granted, free of charge, to any person obtaining a copy
14  * of this software and associated documentation files (the "Software"), to deal
15  * in the Software without restriction, including without limitation the rights
16  * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
17  *  copies of the Software, and to permit persons to whom the Software is
18  * furnished to do so, subject to the following conditions:
19  *
20  * The above copyright notice and this permission notice shall be included in all
21  * copies or substantial portions of the Software.
22  *
23  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
24  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
25  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
26  * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
27  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
28  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
29  * SOFTWARE.
30  *************************************************************************************************/
31 
32 #include "jql.h"
33 #include "jbl.h"
34 #include <errno.h>
35 #include <stdbool.h>
36 #include <setjmp.h>
37 #include <ejdb2/iowow/iwpool.h>
38 #include <ejdb2/iowow/iwxstr.h>
39 
40 typedef uint16_t jqp_string_flavours_t;
41 /** Query string parameter placeholder */
42 #define JQP_STR_PLACEHOLDER ((jqp_string_flavours_t) 0x01U)
43 /** Query filter anchor */
44 #define JQP_STR_ANCHOR ((jqp_string_flavours_t) 0x02U)
45 /** Projection field **/
46 #define JQP_STR_PROJFIELD ((jqp_string_flavours_t) 0x04U)
47 /** Projection alias (all) **/
48 #define JQP_STR_PROJALIAS ((jqp_string_flavours_t) 0x08U)
49 /** String is quoted */
50 #define JQP_STR_QUOTED ((jqp_string_flavours_t) 0x10U)
51 /** Star (*) string */
52 #define JQP_STR_STAR ((jqp_string_flavours_t) 0x20U)
53 /** Boolean negation/mode applied to it */
54 #define JQP_STR_NEGATE ((jqp_string_flavours_t) 0x40U)
55 /** Double star (**) string */
56 #define JQP_STR_DBL_STAR ((jqp_string_flavours_t) 0x80U)
57 /** Projection JOIN */
58 #define JQP_STR_PROJOIN ((jqp_string_flavours_t) 0x100U)
59 
60 
61 typedef uint8_t jqp_int_flavours_t;
62 #define JQP_INT_SKIP  ((jqp_int_flavours_t) 0x01U)
63 #define JQP_INT_LIMIT ((jqp_int_flavours_t) 0x02U)
64 
65 typedef enum {
66   JQP_QUERY_TYPE = 1,
67   JQP_EXPR_NODE_TYPE,
68   JQP_FILTER_TYPE,
69   JQP_NODE_TYPE,
70   JQP_EXPR_TYPE,
71   JQP_STRING_TYPE,
72   JQP_INTEGER_TYPE,
73   JQP_DOUBLE_TYPE,
74   JQP_OP_TYPE,
75   JQP_JOIN_TYPE,
76   JQP_PROJECTION_TYPE,
77   JQP_JSON_TYPE,
78 } jqp_unit_t;
79 
80 typedef enum {
81   JQP_NODE_FIELD = 1,
82   JQP_NODE_ANY,
83   JQP_NODE_ANYS,
84   JQP_NODE_EXPR,
85 } jqp_node_type_t;
86 
87 typedef enum {
88   // Do not reorder members
89   JQP_JOIN_AND = 1,
90   JQP_JOIN_OR,
91   JQP_OP_EQ,
92   JQP_OP_GT,
93   JQP_OP_GTE,
94   JQP_OP_LT,
95   JQP_OP_LTE,
96   JQP_OP_IN,
97   JQP_OP_NI,
98   JQP_OP_RE,
99   JQP_OP_PREFIX,
100 } jqp_op_t;
101 
102 struct JQP_AUX;
103 
104 typedef union _JQP_UNIT JQPUNIT;
105 
106 #define JQP_EXPR_NODE_FLAG_PK 0x01U
107 
108 #define JQP_EXPR_NODE_HEAD    \
109   jqp_unit_t type;            \
110   struct JQP_EXPR_NODE *next; \
111   struct JQP_JOIN *join;      \
112   void *opaque;               \
113   uint8_t flags;
114 
115 typedef struct JQP_EXPR_NODE { // Base for JQP_FILTER
116   JQP_EXPR_NODE_HEAD
117   struct JQP_EXPR_NODE *chain;
118 } JQP_EXPR_NODE;
119 
120 typedef struct JQP_EXPR_NODE_PK {
121   JQP_EXPR_NODE_HEAD
122   struct JQP_EXPR_NODE *chain; // Not used, plased for JQP_EXPR_NODE compatibility
123   const char *anchor;
124   JQPUNIT    *argument;
125 } JQP_EXPR_NODE_PK;
126 
127 typedef struct JQP_FILTER {
128   JQP_EXPR_NODE_HEAD
129   const char      *anchor;
130   struct JQP_NODE *node;
131 } JQP_FILTER;
132 
133 typedef struct JQP_JSON {
134   jqp_unit_t       type;
135   struct _JBL_NODE jn;
136   void *opaque;
137 } JQP_JSON;
138 
139 typedef struct JQP_NODE {
140   jqp_unit_t       type;
141   jqp_node_type_t  ntype;
142   struct JQP_NODE *next;
143   JQPUNIT *value;
144   int      start; // Used in query matching
145   int      end;   // Used in query matching
146 } JQP_NODE;
147 
148 typedef struct JQP_STRING {
149   jqp_unit_t type;
150   jqp_string_flavours_t flavour;
151   const char *value;
152   struct JQP_STRING *next;
153   struct JQP_STRING *subnext;
154   struct JQP_STRING *placeholder_next;
155   void *opaque;
156 } JQP_STRING;
157 
158 typedef struct JQP_INTEGER {
159   jqp_unit_t type;
160   jqp_int_flavours_t flavour;
161   int64_t value;
162   void   *opaque;
163 } JQP_INTEGER;
164 
165 typedef struct JQP_DOUBLE {
166   jqp_unit_t type;
167   jqp_int_flavours_t flavour;
168   double value;
169   void  *opaque;
170 } JQP_DOUBLE;
171 
172 typedef struct JQP_OP {
173   jqp_unit_t type;
174   bool       negate;
175   jqp_op_t   value;
176   struct JQP_OP *next;
177   void *opaque;
178 } JQP_OP;
179 
180 typedef struct JQP_JOIN {
181   jqp_unit_t type;
182   bool       negate;
183   jqp_op_t   value;
184 } JQP_JOIN;
185 
186 typedef struct JQP_EXPR {
187   jqp_unit_t       type;
188   struct JQP_JOIN *join;
189   struct JQP_OP   *op;
190   JQPUNIT *left;
191   JQPUNIT *right;
192   struct JQP_EXPR *next;
193   bool prematched;
194 } JQP_EXPR;
195 
196 typedef struct JQP_PROJECTION {
197   jqp_unit_t type;
198   struct JQP_STRING     *value;
199   struct JQP_PROJECTION *next;
200   int16_t pos;          // Current matching position, used in jql.c#_jql_project
201   int16_t cnt;          // Number of projection sections, used in jql.c#_jql_project
202 
203 #define JQP_PROJECTION_FLAG_EXCLUDE 0x01U
204 #define JQP_PROJECTION_FLAG_INCLUDE 0x02U
205 #define JQP_PROJECTION_FLAG_JOINS   0x04U
206   uint8_t flags;
207 } JQP_PROJECTION;
208 
209 typedef struct JQP_QUERY {
210   jqp_unit_t      type;
211   struct JQP_AUX *aux;
212 } JQP_QUERY;
213 
214 //--
215 
216 union _JQP_UNIT {
217   jqp_unit_t       type;
218   struct JQP_QUERY query;
219   struct JQP_EXPR_NODE    exprnode;
220   struct JQP_EXPR_NODE_PK exprnode_pk;
221   struct JQP_FILTER       filter;
222   struct JQP_NODE    node;
223   struct JQP_EXPR    expr;
224   struct JQP_JOIN    join;
225   struct JQP_OP      op;
226   struct JQP_STRING  string;
227   struct JQP_INTEGER intval;
228   struct JQP_DOUBLE  dblval;
229   struct JQP_JSON    json;
230   struct JQP_PROJECTION projection;
231 };
232 
233 typedef enum {
234   STACK_UNIT = 1,
235   STACK_STRING,
236   STACK_INT,
237   STACK_FLOAT,
238 } jqp_stack_t;
239 
240 typedef struct JQP_STACK {
241   jqp_stack_t       type;
242   struct JQP_STACK *next;
243   struct JQP_STACK *prev;
244   union {
245     JQPUNIT *unit;
246     char    *str;
247     int64_t  i64;
248     double   f64;
249   };
250 } JQP_STACK;
251 
252 #define JQP_AUX_STACKPOOL_NUM 128
253 
254 typedef uint8_t jqp_query_mode_t;
255 
256 #define JQP_QRY_COUNT        ((jqp_query_mode_t) 0x01U)
257 #define JQP_QRY_NOIDX        ((jqp_query_mode_t) 0x02U)
258 #define JQP_QRY_APPLY_DEL    ((jqp_query_mode_t) 0x04U)
259 #define JQP_QRY_INVERSE      ((jqp_query_mode_t) 0x08U)
260 #define JQP_QRY_APPLY_UPSERT ((jqp_query_mode_t) 0x10U)
261 
262 #define JQP_QRY_AGGREGATE (JQP_QRY_COUNT)
263 
264 typedef struct JQP_AUX {
265   int     pos;
266   int     stackn;
267   int     num_placeholders;
268   int     orderby_num;                  /**< Number of order-by blocks */
269   iwrc    rc;
270   jmp_buf fatal_jmp;
271   const char *buf;
272   IWXSTR     *xerr;
273   IWPOOL     *pool;
274   struct JQP_QUERY *query;
275   JQP_STACK *stack;
276   jql_create_mode_t mode;
277   //
278   struct JQP_EXPR_NODE  *expr;
279   struct JQP_PROJECTION *projection;
280   JQP_STRING *start_placeholder;
281   JQP_STRING *end_placeholder;
282   JQP_STRING *orderby;
283   JBL_PTR    *orderby_ptrs;           /**< Order-by pointers, orderby_num - number of pointers allocated */
284   JQP_OP     *start_op;
285   JQP_OP     *end_op;
286   JQPUNIT    *skip;
287   JQPUNIT    *limit;
288   JBL_NODE    apply;
289   const char *apply_placeholder;
290   const char *first_anchor;
291   jqp_query_mode_t qmode;
292   bool      negate;
293   bool      has_keep_projections;
294   bool      has_exclude_all_projection;
295   JQP_STACK stackpool[JQP_AUX_STACKPOOL_NUM];
296 } JQP_AUX;
297 
298 iwrc jqp_aux_create(JQP_AUX **auxp, const char *input);
299 
300 void jqp_aux_destroy(JQP_AUX **auxp);
301 
302 iwrc jqp_parse(JQP_AUX *aux);
303 
304 iwrc jqp_print_query(const JQP_QUERY *q, jbl_json_printer pt, void *op);
305 
306 iwrc jqp_alloc_orderby_pointers(const JQP_QUERY *q, JBL_PTR *optr, size_t *nptr);
307 
308 iwrc jqp_print_filter_node_expr(const JQP_EXPR *e, jbl_json_printer pt, void *op);
309 
310 #endif
311