• 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-2022 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 
34 #include <iowow/iwpool.h>
35 #include <iowow/iwxstr.h>
36 
37 #include <errno.h>
38 #include <stdbool.h>
39 #include <setjmp.h>
40 
41 typedef uint16_t jqp_string_flavours_t;
42 /** Query string parameter placeholder */
43 #define JQP_STR_PLACEHOLDER ((jqp_string_flavours_t) 0x01U)
44 /** Query filter anchor */
45 #define JQP_STR_ANCHOR ((jqp_string_flavours_t) 0x02U)
46 /** Projection field **/
47 #define JQP_STR_PROJFIELD ((jqp_string_flavours_t) 0x04U)
48 /** Projection alias (all) **/
49 #define JQP_STR_PROJALIAS ((jqp_string_flavours_t) 0x08U)
50 /** String is quoted */
51 #define JQP_STR_QUOTED ((jqp_string_flavours_t) 0x10U)
52 /** Star (*) string */
53 #define JQP_STR_STAR ((jqp_string_flavours_t) 0x20U)
54 /** Boolean negation/mode applied to it */
55 #define JQP_STR_NEGATE ((jqp_string_flavours_t) 0x40U)
56 /** Double star (**) string */
57 #define JQP_STR_DBL_STAR ((jqp_string_flavours_t) 0x80U)
58 /** Projection JOIN */
59 #define JQP_STR_PROJOIN ((jqp_string_flavours_t) 0x100U)
60 /** Projection path */
61 #define JQP_STR_PROJPATH ((jqp_string_flavours_t) 0x200U)
62 
63 
64 typedef uint8_t jqp_int_flavours_t;
65 #define JQP_INT_SKIP  ((jqp_int_flavours_t) 0x01U)
66 #define JQP_INT_LIMIT ((jqp_int_flavours_t) 0x02U)
67 
68 typedef enum {
69   JQP_QUERY_TYPE = 1,
70   JQP_EXPR_NODE_TYPE,
71   JQP_FILTER_TYPE,
72   JQP_NODE_TYPE,
73   JQP_EXPR_TYPE,
74   JQP_STRING_TYPE,
75   JQP_INTEGER_TYPE,
76   JQP_DOUBLE_TYPE,
77   JQP_OP_TYPE,
78   JQP_JOIN_TYPE,
79   JQP_PROJECTION_TYPE,
80   JQP_JSON_TYPE,
81 } jqp_unit_t;
82 
83 typedef enum {
84   JQP_NODE_FIELD = 1,
85   JQP_NODE_ANY,
86   JQP_NODE_ANYS,
87   JQP_NODE_EXPR,
88 } jqp_node_type_t;
89 
90 typedef enum {
91   // Do not reorder members
92   JQP_JOIN_AND = 1,
93   JQP_JOIN_OR,
94   JQP_OP_EQ,
95   JQP_OP_GT,
96   JQP_OP_GTE,
97   JQP_OP_LT,
98   JQP_OP_LTE,
99   JQP_OP_IN,
100   JQP_OP_NI,
101   JQP_OP_RE,
102   JQP_OP_PREFIX,
103 } jqp_op_t;
104 
105 struct JQP_AUX;
106 
107 typedef union _JQP_UNIT JQPUNIT;
108 
109 #define JQP_EXPR_NODE_FLAG_PK 0x01U
110 
111 #define JQP_EXPR_NODE_HEAD    \
112   jqp_unit_t type;            \
113   struct JQP_EXPR_NODE *next; \
114   struct JQP_JOIN *join;      \
115   void *opaque;               \
116   uint8_t flags;
117 
118 typedef struct JQP_EXPR_NODE { // Base for JQP_FILTER
119   JQP_EXPR_NODE_HEAD
120   struct JQP_EXPR_NODE *chain;
121 } JQP_EXPR_NODE;
122 
123 typedef struct JQP_EXPR_NODE_PK {
124   JQP_EXPR_NODE_HEAD
125   struct JQP_EXPR_NODE *chain; // Not used, plased for JQP_EXPR_NODE compatibility
126   const char *anchor;
127   JQPUNIT    *argument;
128 } JQP_EXPR_NODE_PK;
129 
130 typedef struct JQP_FILTER {
131   JQP_EXPR_NODE_HEAD
132   const char      *anchor;
133   struct JQP_NODE *node;
134 } JQP_FILTER;
135 
136 typedef struct JQP_JSON {
137   jqp_unit_t       type;
138   struct _JBL_NODE jn;
139   void *opaque;
140 } JQP_JSON;
141 
142 typedef struct JQP_NODE {
143   jqp_unit_t       type;
144   jqp_node_type_t  ntype;
145   struct JQP_NODE *next;
146   JQPUNIT *value;
147   int      start; // Used in query matching
148   int      end;   // Used in query matching
149 } JQP_NODE;
150 
151 typedef struct JQP_STRING {
152   jqp_unit_t type;
153   jqp_string_flavours_t flavour;
154   const char *value;
155   struct JQP_STRING *next;
156   struct JQP_STRING *subnext;
157   struct JQP_STRING *placeholder_next;
158   void *opaque;
159 } JQP_STRING;
160 
161 typedef struct JQP_INTEGER {
162   jqp_unit_t type;
163   jqp_int_flavours_t flavour;
164   int64_t value;
165   void   *opaque;
166 } JQP_INTEGER;
167 
168 typedef struct JQP_DOUBLE {
169   jqp_unit_t type;
170   jqp_int_flavours_t flavour;
171   double value;
172   void  *opaque;
173 } JQP_DOUBLE;
174 
175 typedef struct JQP_OP {
176   jqp_unit_t type;
177   bool       negate;
178   jqp_op_t   value;
179   struct JQP_OP *next;
180   void *opaque;
181 } JQP_OP;
182 
183 typedef struct JQP_JOIN {
184   jqp_unit_t type;
185   bool       negate;
186   jqp_op_t   value;
187 } JQP_JOIN;
188 
189 typedef struct JQP_EXPR {
190   jqp_unit_t       type;
191   struct JQP_JOIN *join;
192   struct JQP_OP   *op;
193   JQPUNIT *left;
194   JQPUNIT *right;
195   struct JQP_EXPR *next;
196   bool prematched;
197 } JQP_EXPR;
198 
199 typedef struct JQP_PROJECTION {
200   jqp_unit_t type;
201   struct JQP_STRING     *value;
202   struct JQP_PROJECTION *next;
203   int16_t pos;          // Current matching position, used in jql.c#_jql_project
204   int16_t cnt;          // Number of projection sections, used in jql.c#_jql_project
205 
206 #define JQP_PROJECTION_FLAG_EXCLUDE 0x01U
207 #define JQP_PROJECTION_FLAG_INCLUDE 0x02U
208 #define JQP_PROJECTION_FLAG_JOINS   0x04U
209   uint8_t flags;
210 } JQP_PROJECTION;
211 
212 typedef struct JQP_QUERY {
213   jqp_unit_t      type;
214   struct JQP_AUX *aux;
215 } JQP_QUERY;
216 
217 //--
218 
219 union _JQP_UNIT {
220   jqp_unit_t       type;
221   struct JQP_QUERY query;
222   struct JQP_EXPR_NODE    exprnode;
223   struct JQP_EXPR_NODE_PK exprnode_pk;
224   struct JQP_FILTER       filter;
225   struct JQP_NODE    node;
226   struct JQP_EXPR    expr;
227   struct JQP_JOIN    join;
228   struct JQP_OP      op;
229   struct JQP_STRING  string;
230   struct JQP_INTEGER intval;
231   struct JQP_DOUBLE  dblval;
232   struct JQP_JSON    json;
233   struct JQP_PROJECTION projection;
234 };
235 
236 typedef enum {
237   STACK_UNIT = 1,
238   STACK_STRING,
239   STACK_INT,
240   STACK_FLOAT,
241 } jqp_stack_t;
242 
243 typedef struct JQP_STACK {
244   jqp_stack_t       type;
245   struct JQP_STACK *next;
246   struct JQP_STACK *prev;
247   union {
248     JQPUNIT *unit;
249     char    *str;
250     int64_t  i64;
251     double   f64;
252   };
253 } JQP_STACK;
254 
255 #define JQP_AUX_STACKPOOL_NUM 128
256 
257 typedef uint8_t jqp_query_mode_t;
258 
259 #define JQP_QRY_COUNT        ((jqp_query_mode_t) 0x01U)
260 #define JQP_QRY_NOIDX        ((jqp_query_mode_t) 0x02U)
261 #define JQP_QRY_APPLY_DEL    ((jqp_query_mode_t) 0x04U)
262 #define JQP_QRY_INVERSE      ((jqp_query_mode_t) 0x08U)
263 #define JQP_QRY_APPLY_UPSERT ((jqp_query_mode_t) 0x10U)
264 
265 #define JQP_QRY_AGGREGATE (JQP_QRY_COUNT)
266 
267 typedef struct JQP_AUX {
268   int     pos;
269   int     stackn;
270   int     num_placeholders;
271   int     orderby_num;                  /**< Number of order-by blocks */
272   iwrc    rc;
273   jmp_buf fatal_jmp;
274   const char *buf;
275   IWXSTR     *xerr;
276   IWPOOL     *pool;
277   struct JQP_QUERY *query;
278   JQP_STACK *stack;
279   jql_create_mode_t mode;
280   //
281   struct JQP_EXPR_NODE  *expr;
282   struct JQP_PROJECTION *projection;
283   JQP_STRING *start_placeholder;
284   JQP_STRING *end_placeholder;
285   JQP_STRING *orderby;
286   JBL_PTR    *orderby_ptrs;           /**< Order-by pointers, orderby_num - number of pointers allocated */
287   JQP_OP     *start_op;
288   JQP_OP     *end_op;
289   JQPUNIT    *skip;
290   JQPUNIT    *limit;
291   JBL_NODE    apply;
292   const char *apply_placeholder;
293   const char *first_anchor;
294   jqp_query_mode_t qmode;
295   bool      negate;
296   bool      has_keep_projections;
297   bool      has_exclude_all_projection;
298   JQP_STACK stackpool[JQP_AUX_STACKPOOL_NUM];
299 } JQP_AUX;
300 
301 iwrc jqp_aux_create(JQP_AUX **auxp, const char *input);
302 
303 void jqp_aux_destroy(JQP_AUX **auxp);
304 
305 iwrc jqp_parse(JQP_AUX *aux);
306 
307 iwrc jqp_print_query(const JQP_QUERY *q, jbl_json_printer pt, void *op);
308 
309 iwrc jqp_alloc_orderby_pointers(const JQP_QUERY *q, JBL_PTR *optr, size_t *nptr);
310 
311 iwrc jqp_print_filter_node_expr(const JQP_EXPR *e, jbl_json_printer pt, void *op);
312 
313 #endif
314