/* $%BEGINLICENSE%$ Copyright (c) 2007, 2012, Oracle and/or its affiliates. All rights reserved. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 2 of the License. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA $%ENDLICENSE%$ */ #ifndef SQL_EXPRESSION_H #define SQL_EXPRESSION_H #include #include #include #include enum sql_join_type_t { JT_INNER = 0x01, /* Any kind of inner or cross join */ JT_CROSS = 0x02, /* Explicit use of the CROSS keyword */ JT_NATURAL = 0x04, /* True for a "natural" join */ JT_LEFT = 0x08, /* Left outer join */ JT_RIGHT = 0x10, /* Right outer join */ JT_OUTER = 0x20, /* The "OUTER" keyword is present */ JT_ERROR = 0x40, /* unknown or unsupported join type */ }; #define MAX_AGGR_FUNS 8 typedef struct group_aggr_t { uint8_t type; int pos; unsigned int fun_type; } group_aggr_t; typedef struct sql_token_t sql_token_t; typedef struct sql_expr_t sql_expr_t; typedef GPtrArray sql_expr_list_t; typedef GPtrArray sql_id_list_t; typedef GPtrArray sql_src_list_t; typedef struct sql_src_item_t sql_src_item_t; typedef struct sql_expr_span_t sql_expr_span_t; typedef struct sql_select_t sql_select_t; typedef struct sql_delete_t sql_delete_t; typedef struct sql_update_t sql_update_t; typedef struct sql_insert_t sql_insert_t; typedef enum sql_stmt_type_t sql_stmt_type_t; typedef struct sql_column_t sql_column_t; typedef GPtrArray sql_column_list_t; enum sql_stmt_type_t { STMT_UNKOWN, STMT_SELECT, STMT_INSERT, STMT_UPDATE, STMT_DELETE, STMT_COMMON_DDL, STMT_SHOW, STMT_SET, STMT_SET_NAMES, STMT_SET_TRANSACTION, STMT_ROLLBACK, STMT_COMMIT, STMT_CALL, STMT_START, STMT_EXPLAIN_TABLE, STMT_USE, STMT_SAVEPOINT, STMT_SHOW_COLUMNS, STMT_SHOW_CREATE, STMT_SHOW_WARNINGS, }; struct sql_token_t { const char *z; /* pointer to token text, not NUL-terminated */ uint32_t n; /* length of token text in bytes */ }; enum sql_var_scope_t { SCOPE_GLOBAL, SCOPE_SESSION, SCOPE_USER, /* SET TRANSACTION ...without explicit scope keyword, only affect next transaction, it's transient */ SCOPE_TRANSIENT, SCOPE_NONE }; enum sql_trx_feature_t { TF_READ_ONLY = 1, TF_READ_WRITE, /* isolation levels */ TF_SERIALIZABLE, TF_REPEATABLE_READ, TF_READ_COMMITTED, TF_READ_UNCOMMITTED, }; enum sql_clause_flag_t { CF_READ = 0x01, CF_WRITE = 0x02, CF_FORCE_MASTER = 0x04, CF_FORCE_SLAVE = 0x08, CF_DDL = 0x10, CF_LOCAL_QUERY = 0x20, CF_DISTINCT_AGGR = 0x40, CF_SUBQUERY = 0x80, CF_AGGREGATE = 0x0100, }; enum sql_sort_order_t { SQL_SO_ASC, SQL_SO_DESC, }; enum sql_expr_flags_t { EP_FUNCTION = 0x01, EP_INTERVAL = 0x02, EP_EXISTS = 0x04, EP_BETWEEN = 0x08, EP_ATOMIC = 0x10, EP_LAST_INSERT_ID = 0x20, EP_DISTINCT = 0x40, EP_SHARD_COND = 0x80, EP_JOIN_LINK = 0x0100, EP_NOT = 0x0200, EP_CASE_WHEN = 0x0400, EP_ORDER_BY = 0x0800, EP_AGGREGATE = 0x1000, }; enum sql_func_type_t { FT_UNKNOWN = 0, FT_COUNT, FT_SUM, FT_AVG, FT_MAX, FT_MIN, }; struct sql_expr_t { uint16_t op; /* Operation performed by this node */ char *token_text; /* Token value. Zero terminated and dequoted */ uint64_t num_value; /* Non-negative integer value */ sql_expr_t *left; sql_expr_t *right; sql_expr_list_t *list; /* op = IN, EXISTS, SELECT, CASE, FUNCTION, BETWEEN */ sql_select_t *select; /* EP_xIsSelect and op = IN, EXISTS, SELECT */ int height; /* Height of the tree headed by this node */ char *alias; enum sql_expr_flags_t flags; enum sql_var_scope_t var_scope; /* variable scope: SESSION(default) or GLOBAL */ const char *start; /* first char of expr in original sql */ const char *end; /* one char past the end of expr in orig sql */ }; enum select_flag_t { SF_DISTINCT = 0x01, SF_ALL = 0x02, SF_CALC_FOUND_ROWS = 0x04, SF_MULTI_VALUE = 0x08, SF_REWRITE_ORDERBY = 0x10, }; struct sql_select_t { uint8_t op; /* One of: TK_UNION TK_ALL TK_INTERSECT TK_EXCEPT */ uint32_t flags; /* Various SF_* values */ sql_expr_list_t *columns; /* The fields of the result */ sql_src_list_t *from_src; /* The FROM clause */ sql_expr_t *where_clause; sql_expr_list_t *groupby_clause; sql_expr_t *having_clause; sql_column_list_t *orderby_clause; sql_select_t *prior; /* Prior select in a compound select statement */ sql_select_t *next; /* Next select to the left in a compound */ sql_expr_t *limit; /* LIMIT expression. NULL means not used. */ sql_expr_t *offset; /* OFFSET expression. NULL means not used. */ int lock_read; }; struct sql_delete_t { sql_src_list_t *from_src; /* The FROM clause */ sql_expr_t *where_clause; sql_column_list_t *orderby_clause; sql_expr_t *limit; /* LIMIT expression. NULL means not used. */ sql_expr_t *offset; /* OFFSET expression. NULL means not used. */ }; struct sql_update_t { sql_src_list_t *table; sql_expr_list_t *set_list; sql_expr_t *where_clause; sql_column_list_t *orderby_clause; sql_expr_t *limit; /* LIMIT expression. NULL means not used. */ sql_expr_t *offset; /* OFFSET expression. NULL means not used. */ }; struct sql_insert_t { int is_replace; sql_src_list_t *table; sql_select_t *sel_val; /* [1] select... [2] values(...) */ sql_id_list_t *columns; sql_expr_list_t *update_list; /* ON DUPLICATE KEY UPDATE ... */ const char *columns_start; /* [start, end) span of columns */ const char *columns_end; }; struct sql_column_t { sql_expr_t *expr; char *type; enum sql_sort_order_t sort_order; char *alias; }; struct sql_src_item_t { char *dbname; /* Name of database holding this table */ char *table_name; /* Name of the table */ char *table_alias; /* The "B" part of a "A AS B" phrase. zName is the "A" */ sql_select_t *select; /* A SELECT statement used in place of a table name */ uint8_t jointype; /* Type of join between this table and the previous */ sql_expr_t *on_clause; /* The ON clause of a join */ sql_id_list_t *pUsing; /* The USING clause of a join */ sql_expr_list_t *func_arg; /* Arguments to table-valued-function */ }; /* One entry for each identifier on the list */ typedef struct sql_set_transaction_t { enum sql_var_scope_t scope; enum sql_trx_feature_t rw_feature; enum sql_trx_feature_t level; } sql_set_transaction_t; char *sql_token_dup(sql_token_t); void sql_string_dequote(char *str); sql_expr_t *sql_expr_new(int op, const sql_token_t *token); sql_expr_t *sql_expr_dup(const sql_expr_t *); void sql_expr_attach_subtrees(sql_expr_t *p, sql_expr_t *left, sql_expr_t *right); void sql_expr_free(void *p); void sql_expr_print(sql_expr_t *p, int depth); gboolean sql_expr_get_int(sql_expr_t *p, gint64 *value); gboolean sql_expr_is_boolean(sql_expr_t *p, gboolean *value); #define sql_expr_id(A) \ (A ? ((A->op == TK_ID)?A->token_text:NULL) : NULL) gboolean sql_expr_is_id(const sql_expr_t *p, const char *name); gboolean sql_expr_is_function(const sql_expr_t *p, const char *func_name); gboolean sql_expr_is_dotted_name(const sql_expr_t *p, const char *prefix, const char *suffix); void sql_expr_get_dotted_names(const sql_expr_t *p, char *db, int db_len, char *table, int tb_len, char *col, int col_len); gboolean sql_expr_is_field_name(const sql_expr_t *p); sql_expr_list_t *sql_expr_list_append(sql_expr_list_t *list, sql_expr_t *expr); sql_expr_t *sql_expr_list_find(sql_expr_list_t *list, const char *name); sql_expr_t *sql_expr_list_find_fullname(sql_expr_list_t *list, const sql_expr_t *expr); int sql_expr_list_find_aggregates(sql_expr_list_t *list, group_aggr_t * aggr_array); int sql_expr_list_find_aggregate(sql_expr_list_t *list); void sql_expr_list_free(sql_expr_list_t *list); sql_src_list_t *sql_src_list_append(sql_src_list_t *, sql_token_t *tname, sql_token_t *dbname, sql_token_t *alias, sql_select_t *subquery, sql_expr_t *on_clause, sql_id_list_t *using_clause); void sql_src_list_free(sql_src_list_t *p); sql_id_list_t *sql_id_list_append(sql_id_list_t *p, sql_token_t *id_name); void sql_id_list_free(sql_id_list_t *p); sql_select_t *sql_select_new(); void sql_select_free(sql_select_t *); sql_delete_t *sql_delete_new(); void sql_delete_free(sql_delete_t *); sql_update_t *sql_update_new(); void sql_update_free(sql_update_t *); sql_insert_t *sql_insert_new(); void sql_insert_free(sql_insert_t *); char *sql_get_token_name(int op); sql_column_list_t *sql_column_list_append(sql_column_list_t *, sql_column_t *); void sql_column_list_free(sql_column_list_t *); sql_column_t *sql_column_new(); void sql_column_free(void *); int sql_join_type(sql_token_t kw); void sql_statement_free(void *clause, sql_stmt_type_t stmt_type); gboolean sql_is_quoted_string(const char *s); enum sql_func_type_t sql_func_type(const char *s); gboolean sql_expr_equals(const sql_expr_t *, const sql_expr_t *); #endif /* SQL_EXPRESSION_H */