Merge branch 'master' into optimize

This commit is contained in:
lazio579 2018-12-13 15:54:07 +08:00
commit 9b55834beb
6 changed files with 191 additions and 27 deletions

View File

@ -613,18 +613,18 @@ stl_prefix(A) ::= seltablist(A) joinop(Y). {
}
}
stl_prefix(A) ::= . {A = 0;}
seltablist(A) ::= stl_prefix(A) nm(Y) dotnm(D) as(Z) index_hint on_opt(N) using_opt(U). {
seltablist(A) ::= stl_prefix(A) nm(Y) dotnm(D) as(Z) index_hint(I) on_opt(N) using_opt(U). {
if (D.n)
A = sql_src_list_append(A,&D,&Y,&Z,0,N,U);
A = sql_src_list_append(A,&D,&Y,I,&Z,0,N,U);
else
A = sql_src_list_append(A,&Y,0,&Z,0,N,U);
A = sql_src_list_append(A,&Y,0,I,&Z,0,N,U);
}
seltablist(A) ::= stl_prefix(A) nm(Y) dotnm(D) LP exprlist(E) RP as(Z)
on_opt(N) using_opt(U). {
if (D.n)
A = sql_src_list_append(A,&D,&Y,&Z,0,N,U);
A = sql_src_list_append(A,&D,&Y,0,&Z,0,N,U);
else
A = sql_src_list_append(A,&Y,0,&Z,0,N,U);
A = sql_src_list_append(A,&Y,0,0,&Z,0,N,U);
sql_src_item_t* item = g_ptr_array_index(A, A->len-1);
item->func_arg = E;
}
@ -632,14 +632,14 @@ seltablist(A) ::= stl_prefix(A) nm(Y) dotnm(D) LP exprlist(E) RP as(Z)
seltablist(A) ::= stl_prefix(A) LP select(S) RP
as(Z) on_opt(N) using_opt(U). {
context->clause_flags |= CF_SUBQUERY;
A = sql_src_list_append(A,0,0,&Z,S,N,U);
A = sql_src_list_append(A,0,0,0,&Z,S,N,U);
}
seltablist(A) ::= stl_prefix(A) LP seltablist(F) RP
as(Z) on_opt(N) using_opt(U). {
if (A==0 && Z.n==0 && N==0 && U==0) {
A = F;
} else if (F->len == 1) {
A = sql_src_list_append(A,0,0,&Z,0,N,U);
A = sql_src_list_append(A,0,0,0,&Z,0,N,U);
if (A) {
printf("not implemented");//TODO;
}
@ -657,9 +657,9 @@ dotnm(A) ::= DOT nm(X). {A = X;}
%destructor fullname { sql_src_list_free($$);}
fullname(A) ::= nm(B) dotnm(C). {
if (C.n)
A = sql_src_list_append(0,&C,&B,0,0,0,0);
A = sql_src_list_append(0,&C,&B,0,0,0,0,0);
else
A = sql_src_list_append(0,&B,0,0,0,0,0);
A = sql_src_list_append(0,&B,0,0,0,0,0,0);
}
%type joinop {int}
@ -780,7 +780,7 @@ where_sym ::= WHERE. {
//
update_stmt ::= UPDATE table_reference(X) SET update_list(Y) where_opt(W) orderby_opt(O) limit_opt(L). {
sql_update_t* p = sql_update_new();
p->table = X;
p->table_reference = X;
p->set_list = Y;
p->where_clause = W;
p->orderby_clause = O;
@ -840,19 +840,73 @@ simple_ident_q(A) ::= ID(X) DOT ID(Y) DOT ID(Z). {
}
%type table_reference {sql_src_list_t*}
%destructor table_reference {sql_src_list_free($$);}
table_reference(A) ::= fullname(A) as index_hint.
index_hint ::= .
index_hint ::= USE INDEX|KEY index_for LP index_list RP.
index_hint ::= IGNORE INDEX|KEY index_for LP index_list RP.
index_hint ::= FORCE INDEX|KEY index_for LP index_list RP.
%type table_reference {sql_table_reference_t*}
%destructor table_reference {sql_table_reference_free($$);}
table_reference(A) ::= fullname(F) as index_hint(I). {
sql_table_reference_t * tr = sql_table_reference_new();
tr->table_list = F;
tr->index_hint = I;
A = tr;
}
%type index_hint { sql_index_hint_t* }
%destructor index_hint { sql_index_hint_free($$); }
index_hint(I) ::= . {
I = 0;
}
index_hint(I) ::= USE INDEX index_for LP index_list(L) RP. {
sql_index_hint_t *ih = sql_index_hint_new();
ih->type = IH_USE_INDEX;
ih->names = L;
I = ih;
}
index_hint(I) ::= USE KEY index_for LP index_list(L) RP. {
sql_index_hint_t *ih = sql_index_hint_new();
ih->type = IH_USE_KEY;
ih->names = L;
I = ih;
}
index_hint(I) ::= IGNORE INDEX index_for LP index_list(L) RP. {
sql_index_hint_t *ih = sql_index_hint_new();
ih->type = IH_IGNORE_INDEX;
ih->names = L;
I = ih;
}
index_hint(I) ::= IGNORE KEY index_for LP index_list(L) RP. {
sql_index_hint_t *ih = sql_index_hint_new();
ih->type = IH_IGNORE_KEY;
ih->names = L;
I = ih;
}
index_hint(I) ::= FORCE INDEX index_for LP index_list(L) RP. {
sql_index_hint_t *ih = sql_index_hint_new();
ih->type = IH_FORCE_INDEX;
ih->names = L;
I = ih;
}
index_hint(I) ::= FORCE KEY index_for LP index_list(L) RP. {
sql_index_hint_t *ih = sql_index_hint_new();
ih->type = IH_FORCE_KEY;
ih->names = L;
I = ih;
}
index_for ::= .
index_for ::= FOR JOIN.
index_for ::= FOR ORDER BY.
index_for ::= FOR GROUP BY.
index_list ::= index_list COMMA ID.
index_list ::= ID|PRIMARY.
%type index_list { sql_id_list_t* }
%destructor index_list { sql_id_list_free($$); }
index_list(L) ::= index_list(L) COMMA index_name(N). {
L = sql_id_list_append(L, &N);
}
index_list(L) ::= index_name(N). {
L = sql_id_list_append(0, &N);
}
%type index_name {sql_token_t}
index_name(N) ::= ID(N).
index_name(N) ::= PRIMARY(N).
////////////////////////// The INSERT command /////////////////////////////////
//

View File

@ -580,9 +580,9 @@ dotnm(A) ::= DOT nm(X). {A = X;}
%destructor fullname { sql_src_list_free($$);}
fullname(A) ::= nm(B) dotnm(C). {
if (C.n)
A = sql_src_list_append(0,&C,&B,0,0,0,0);
A = sql_src_list_append(0,&C,&B,0,0,0,0,0);
else
A = sql_src_list_append(0,&B,0,0,0,0,0);
A = sql_src_list_append(0,&B,0,0,0,0,0,0);
}
%type joinop {int}

View File

@ -348,6 +348,45 @@ sql_construct_select(sql_select_t *select, int explain)
g_string_append(s, src->table_alias);
g_string_append(s, " ");
}
if (src->index_hint) {
switch (src->index_hint->type) {
case IH_USE_INDEX: {
g_string_append(s, " USE INDEX ( ");
break;
}
case IH_USE_KEY: {
g_string_append(s, " USE KEY ( ");
break;
}
case IH_IGNORE_INDEX: {
g_string_append(s, " IGNORE INDEX ( ");
break;
}
case IH_IGNORE_KEY: {
g_string_append(s, " IGNORE KEY ( ");
break;
}
case IH_FORCE_INDEX: {
g_string_append(s, " FORCE INDEX ( ");
break;
}
case IH_FORCE_KEY: {
g_string_append(s, " FORCE KEY ( ");
break;
}
}
gint len = src->index_hint->names->len;
gint i = 0;
for(i=0; i<len; i++) {
g_string_append(s, g_ptr_array_index(src->index_hint->names, i));
if(i != (len -1)) {
g_string_append(s, " , ");
}
}
g_string_append(s, " ) ");
}
if (src->on_clause) {
g_string_append(s, " ON ");
append_sql_expr(s, src->on_clause);

View File

@ -611,8 +611,8 @@ sql_update_free(sql_update_t *p)
{
if (!p)
return;
if (p->table)
sql_src_list_free(p->table);
if (p->table_reference)
sql_table_reference_free(p->table_reference);
if (p->set_list)
sql_expr_list_free(p->set_list);
if (p->where_clause) /* The WHERE clause */
@ -657,6 +657,8 @@ sql_src_item_free(void *p)
struct sql_src_item_t *item = (struct sql_src_item_t *)p;
if (item->table_name)
g_free(item->table_name);
if (item->index_hint)
sql_index_hint_free(item->index_hint);
if (item->table_alias)
g_free(item->table_alias);
if (item->dbname)
@ -691,12 +693,13 @@ sql_drop_database_free(sql_drop_database_t *p)
sql_src_list_t *
sql_src_list_append(sql_src_list_t *p, sql_token_t *tname,
sql_token_t *dbname, sql_token_t *alias, sql_select_t *subquery,
sql_token_t *dbname, sql_index_hint_t *index_hint, sql_token_t *alias, sql_select_t *subquery,
sql_expr_t *on_clause, sql_id_list_t *using_clause)
{
struct sql_src_item_t *item = g_new0(sql_src_item_t, 1);
if (item) {
item->table_name = tname ? sql_token_dup(*tname) : NULL;
item->index_hint = index_hint;
item->table_alias = alias ? sql_token_dup(*alias) : NULL;
item->dbname = dbname ? sql_token_dup(*dbname) : NULL;
item->select = subquery;
@ -1015,3 +1018,40 @@ sql_expr_equals(const sql_expr_t *p1, const sql_expr_t *p2)
}
return FALSE;
}
void
sql_index_hint_free(sql_index_hint_t* p)
{
if (p && p->names) {
sql_id_list_free(p->names);
}
if (p)
g_free(p);
}
sql_index_hint_t*
sql_index_hint_new()
{
return g_new0(sql_index_hint_t, 1);
}
void
sql_table_reference_free(sql_table_reference_t* p)
{
if (!p) {
return;
}
if (p->table_list) {
sql_src_list_free(p->table_list);
}
if (p->index_hint) {
sql_index_hint_free(p->index_hint);
}
g_free(p);
}
sql_table_reference_t *
sql_table_reference_new()
{
return g_new0(sql_table_reference_t, 1);
}

View File

@ -156,6 +156,29 @@ enum sql_aggregate_type_t {
FT_MIN,
};
enum sql_index_hint_type_t {
IH_USE_INDEX,
IH_USE_KEY,
IH_IGNORE_INDEX,
IH_IGNORE_KEY,
IH_FORCE_INDEX,
IH_FORCE_KEY
};
struct sql_index_hint_t {
uint8_t type;
sql_id_list_t *names;
};
typedef struct sql_index_hint_t sql_index_hint_t;
struct sql_table_reference_t {
sql_src_list_t* table_list;
sql_index_hint_t *index_hint;
};
typedef struct sql_table_reference_t sql_table_reference_t;
struct sql_expr_t {
uint16_t op; /* Operation performed by this node */
char *token_text; /* Token value. Zero terminated and dequoted */
@ -207,7 +230,7 @@ struct sql_delete_t {
};
struct sql_update_t {
sql_src_list_t *table;
sql_table_reference_t *table_reference;
sql_expr_list_t *set_list;
sql_expr_t *where_clause;
sql_column_list_t *orderby_clause;
@ -236,6 +259,7 @@ struct sql_column_t {
struct sql_src_item_t {
char *dbname; /* Name of database holding this table */
char *table_name; /* Name of the table */
sql_index_hint_t *index_hint;
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 */
@ -304,7 +328,8 @@ int sql_expr_list_find_exact_aggregate(sql_expr_list_t *list, const char *target
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_token_t *dbname, sql_index_hint_t *index_hint,
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);
@ -352,4 +377,10 @@ enum sql_aggregate_type_t sql_aggregate_type(const char *s);
gboolean sql_expr_equals(const sql_expr_t *, const sql_expr_t *);
void sql_index_hint_free(sql_index_hint_t* p);
sql_index_hint_t *sql_index_hint_new();
void sql_table_reference_free(sql_table_reference_t* p);
sql_table_reference_t *sql_table_reference_new();
#endif /* SQL_EXPRESSION_H */

View File

@ -1088,7 +1088,7 @@ routing_update(sql_context_t *context, sql_update_t *update,
char *default_db, sharding_plan_t *plan, GPtrArray *groups, guint32 fixture)
{
char *db = default_db;
sql_src_list_t *tables = update->table;
sql_src_list_t *tables = update->table_reference->table_list;
sql_src_item_t *table = g_ptr_array_index(tables, 0);
if (table->dbname) {
db = table->dbname;