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