Changeset: 7fe10e6fa740 for MonetDB
URL: https://dev.monetdb.org/hg/MonetDB?cmd=changeset;node=7fe10e6fa740
Modified Files:
sql/server/rel_select.c
sql/server/sql_mvc.c
sql/server/sql_mvc.h
sql/server/sql_parser.y
sql/test/miscellaneous/Tests/groupby_expressions.sql
sql/test/miscellaneous/Tests/groupby_expressions.stable.err
sql/test/miscellaneous/Tests/groupby_expressions.stable.out
Branch: groupby-expressions
Log Message:
Using symbol comparison instead of string comparison for group by expressions.
This simplifies search for expressions in the projection phase.
diffs (truncated from 303 to 300 lines):
diff --git a/sql/server/rel_select.c b/sql/server/rel_select.c
--- a/sql/server/rel_select.c
+++ b/sql/server/rel_select.c
@@ -3120,14 +3120,6 @@ rel_unop(mvc *sql, sql_rel **rel, symbol
sql_subtype *t = NULL;
int type = (ek.card == card_loader)?F_LOADER:((ek.card ==
card_none)?F_PROC:F_FUNC);
- if (*rel && (*rel)->card == CARD_AGGR) { //group by expression case,
handle it before
- sql_exp *exp = stack_get_groupby_expression(sql, se);
- if (sql->errstr[0] != '\0')
- return NULL;
- if (exp)
- return exp_column(sql->sa, exp_relname(exp),
exp_name(exp), exp_subtype(exp), exp->card, has_nil(exp), is_intern(exp));
- }
-
if (sname)
s = mvc_bind_schema(sql, sname);
@@ -3435,14 +3427,6 @@ rel_binop(mvc *sql, sql_rel **rel, symbo
if (!s)
return NULL;
- if (*rel && (*rel)->card == CARD_AGGR) { //group by expression case,
handle it before
- sql_exp *exp = stack_get_groupby_expression(sql, se);
- if (sql->errstr[0] != '\0')
- return NULL;
- if (exp)
- return exp_column(sql->sa, exp_relname(exp),
exp_name(exp), exp_subtype(exp), exp->card, has_nil(exp), is_intern(exp));
- }
-
l = rel_value_exp(sql, rel, dl->next->data.sym, f, iek);
r = rel_value_exp(sql, rel, dl->next->next->data.sym, f, iek);
if (!l || !r)
@@ -3520,14 +3504,6 @@ rel_nop(mvc *sql, sql_rel **rel, symbol
exp_kind iek = {type_value, card_column, FALSE};
int err = 0;
- if (*rel && (*rel)->card == CARD_AGGR) { //group by expression case,
handle it before
- sql_exp *exp = stack_get_groupby_expression(sql, se);
- if (sql->errstr[0] != '\0')
- return NULL;
- if (exp)
- return exp_column(sql->sa, exp_relname(exp),
exp_name(exp), exp_subtype(exp), exp->card, has_nil(exp), is_intern(exp));
- }
-
for (; ops; ops = ops->next, nr_args++) {
sql_exp *e = rel_value_exp(sql, rel, ops->data.sym, fs, iek);
sql_subtype *tpe;
@@ -3826,18 +3802,6 @@ rel_aggr(mvc *sql, sql_rel **rel, symbol
d = l->h->next->next;
}
- if (*rel && (*rel)->card == CARD_AGGR) { //group by expression case,
handle it before
- sql_exp *exp = stack_get_groupby_expression(sql, se);
- if (sql->errstr[0] != '\0')
- return NULL;
- if (exp) {
- sql_exp *res = exp_column(sql->sa, exp_relname(exp),
exp_name(exp), exp_subtype(exp), exp->card, has_nil(exp), is_intern(exp));
- if (distinct)
- set_distinct(res);
- return res;
- }
- }
-
if (sname)
s = mvc_bind_schema(sql, sname);
return _rel_aggr( sql, rel, distinct, s, aname, d, f);
@@ -5093,6 +5057,22 @@ rel_value_exp2(mvc *sql, sql_rel **rel,
if (THRhighwater())
return sql_error(sql, 10, SQLSTATE(42000) "SELECT: too many
nested operators");
+ if (*rel && (*rel)->card == CARD_AGGR) { //group by expression case,
handle it before
+ sql_exp *exp = stack_get_groupby_expression(sql, se);
+ if (sql->errstr[0] != '\0')
+ return NULL;
+ if (exp) {
+ sql_exp *res = exp_column(sql->sa, exp_relname(exp),
exp_name(exp), exp_subtype(exp), exp->card, has_nil(exp), is_intern(exp));
+ if(se->token == SQL_AGGR) {
+ dlist *l = se->data.lval;
+ int distinct = l->h->next->data.i_val;
+ if (distinct)
+ set_distinct(res);
+ }
+ return res;
+ }
+ }
+
switch (se->token) {
case SQL_OP:
return rel_op(sql, se, ek);
diff --git a/sql/server/sql_mvc.c b/sql/server/sql_mvc.c
--- a/sql/server/sql_mvc.c
+++ b/sql/server/sql_mvc.c
@@ -1628,21 +1628,10 @@ sql_var*
stack_push_groupby_expression(mvc *sql, symbol *def, sql_exp *exp)
{
sql_var* res = NULL;
- char *err = NULL;
sql_groupby_expression *sge = MNEW(sql_groupby_expression);
if(sge) {
- sge->sdef = symbol2string(sql, def, 1, &err);
- if (!sge->sdef) {
- if (err) {
- (void) sql_error(sql, 02, SQLSTATE(42000)
"SELECT: incorrect expression '%s'", err);
- _DELETE(err);
- _DELETE(sge);
- return NULL;
- }
- _DELETE(sge);
- return NULL;
- }
+ sge->sdef = def;
sge->token = def->token;
sge->exp = exp;
@@ -1657,19 +1646,9 @@ stack_push_groupby_expression(mvc *sql,
sql_exp*
stack_get_groupby_expression(mvc *sql, symbol *def)
{
- char *err = NULL, *sdef = symbol2string(sql, def, 1, &err);
-
if(sql->has_groupby_expressions) {
- if (!sdef) {
- if (err) {
- (void) sql_error(sql, 02, SQLSTATE(42000)
"SELECT: incorrect expression '%s'", err);
- _DELETE(err);
- return NULL;
- }
- return NULL;
- }
for (int i = sql->topvars-1; i >= 0; i--) {
- if (!sql->vars[i].frame && sql->vars[i].exp &&
sql->vars[i].exp->token == def->token && strcmp(sql->vars[i].exp->sdef,
sdef)==0) {
+ if (!sql->vars[i].frame && sql->vars[i].exp &&
sql->vars[i].exp->token == def->token && symbol_cmp(sql->vars[i].exp->sdef,
def)==0) {
return sql->vars[i].exp->exp;
}
}
@@ -1757,10 +1736,8 @@ stack_pop_until(mvc *sql, int top)
c_delete(v->name);
VALclear(&v->a.data);
v->a.data.vtype = 0;
- if(v->exp) {
- _DELETE(v->exp->sdef);
+ if(v->exp)
_DELETE(v->exp);
- }
v->wdef = NULL;
}
}
@@ -1778,10 +1755,8 @@ stack_pop_frame(mvc *sql)
table_destroy(v->t);
else if (v->rel)
rel_destroy(v->rel);
- else if(v->exp) {
- _DELETE(v->exp->sdef);
+ else if(v->exp)
_DELETE(v->exp);
- }
v->wdef = NULL;
}
if (sql->topvars && sql->vars[sql->topvars].name)
diff --git a/sql/server/sql_mvc.h b/sql/server/sql_mvc.h
--- a/sql/server/sql_mvc.h
+++ b/sql/server/sql_mvc.h
@@ -68,7 +68,7 @@
#define mod_locked 16
typedef struct sql_groupby_expression {
- char *sdef;
+ symbol *sdef;
tokens token;
sql_exp *exp;
} sql_groupby_expression;
diff --git a/sql/server/sql_parser.y b/sql/server/sql_parser.y
--- a/sql/server/sql_parser.y
+++ b/sql/server/sql_parser.y
@@ -496,7 +496,7 @@ int yydebug=1;
routine_body
table_function_column_list
select_target_list
- simple_scalar_exp_commalist
+ search_condition_commalist
external_function_name
with_list
window_specification
@@ -3646,12 +3646,12 @@ opt_table_name:
opt_group_by_clause:
/* empty */ { $$ = NULL; }
- | sqlGROUP BY simple_scalar_exp_commalist { $$ = _symbol_create_list(
SQL_GROUPBY, $3 );}
- ;
-
-simple_scalar_exp_commalist:
- simple_scalar_exp { $$ =
append_symbol(L(), $1); }
- | simple_scalar_exp_commalist ',' simple_scalar_exp { $$ = append_symbol($1,
$3); }
+ | sqlGROUP BY search_condition_commalist { $$ = _symbol_create_list(
SQL_GROUPBY, $3 );}
+ ;
+
+search_condition_commalist:
+ search_condition { $$ = append_symbol(L(),
$1); }
+ | search_condition_commalist ',' search_condition { $$ = append_symbol($1,
$3); }
;
column_ref_commalist:
@@ -4260,7 +4260,7 @@ window_ident_clause:
window_partition_clause:
/* empty */ { $$ = NULL; }
- | PARTITION BY simple_scalar_exp_commalist
+ | PARTITION BY search_condition_commalist
{ $$ = _symbol_create_list( SQL_GROUPBY, $3 ); }
;
diff --git a/sql/test/miscellaneous/Tests/groupby_expressions.sql
b/sql/test/miscellaneous/Tests/groupby_expressions.sql
--- a/sql/test/miscellaneous/Tests/groupby_expressions.sql
+++ b/sql/test/miscellaneous/Tests/groupby_expressions.sql
@@ -14,10 +14,16 @@ select cast(sum(("aa"+1) + ("bb"+2)) as
select cast("aa"+1 as bigint) from "groupings" group by "aa"+1 having "aa"+1 >
2;
select cast("aa"+1 as bigint) from "groupings" group by "aa"+1 order by "aa"+1;
---select count(*) from "groupings" group by case when "aa" > 1 then "aa" else
"aa" + 10 end;
---select (case when "aa" > 1 then "aa" else "aa" * 4 end) from "groupings"
group by (case when "aa" > 1 then "aa" else "aa" * 4 end);
+select count(*) from "groupings" group by "aa" > 1;
+select "aa" > 1 from "groupings" group by "aa" > 1;
+select count(*) from "groupings" group by case when "aa" > 1 then "aa" else
"aa" + 10 end;
+select case when "aa" > 1 then "aa" else "aa" * 4 end from "groupings" group
by case when "aa" > 1 then "aa" else "aa" * 4 end;
+
+select cast(sum("aa"+"bb") as bigint) from "groupings" group by "aa"+"bb";
+select cast(sum("aa"+3452) as bigint) from "groupings" group by "aa"+"bb";
rollback;
+select "aa"+3452 from "groupings" group by "aa"+"bb"; --error
select count(*) from "groupings" group by rank() over (); --error
select count(*) from "groupings" having rank() over (); --error
select count(*) from "groupings" order by rank() over (); --error TODO?
diff --git a/sql/test/miscellaneous/Tests/groupby_expressions.stable.err
b/sql/test/miscellaneous/Tests/groupby_expressions.stable.err
--- a/sql/test/miscellaneous/Tests/groupby_expressions.stable.err
+++ b/sql/test/miscellaneous/Tests/groupby_expressions.stable.err
@@ -30,7 +30,11 @@ stderr of test 'groupby_expressions` in
# 14:21:56 > "mclient" "-lsql" "-ftest" "-tnone" "-Eutf-8" "-i" "-e"
"--host=/var/tmp/mtest-21747" "--port=32012"
# 14:21:56 >
-MAPI = (monetdb) /var/tmp/mtest-23848/.s.monetdb.34914
+MAPI = (monetdb) /var/tmp/mtest-28161/.s.monetdb.36698
+QUERY = select "aa"+3452 from "groupings" group by "aa"+"bb"; --error
+ERROR = !SELECT: no such aggregate 'sql_add'
+CODE = 42000
+MAPI = (monetdb) /var/tmp/mtest-28161/.s.monetdb.36698
QUERY = select count(*) from "groupings" group by rank() over (); --error
ERROR = !RANK: window function 'rank' not allowed in GROUP BY clause
CODE = 42000
diff --git a/sql/test/miscellaneous/Tests/groupby_expressions.stable.out
b/sql/test/miscellaneous/Tests/groupby_expressions.stable.out
--- a/sql/test/miscellaneous/Tests/groupby_expressions.stable.out
+++ b/sql/test/miscellaneous/Tests/groupby_expressions.stable.out
@@ -134,6 +134,48 @@ Ready.
% 1 # length
[ 2 ]
[ 3 ]
+#select count(*) from "groupings" group by "aa" > 1;
+% sys.L3 # table_name
+% L3 # name
+% bigint # type
+% 1 # length
+[ 2 ]
+[ 1 ]
+#select "aa" > 1 from "groupings" group by "aa" > 1;
+% sys.L1 # table_name
+% L1 # name
+% boolean # type
+% 5 # length
+[ false ]
+[ true ]
+#select count(*) from "groupings" group by case when "aa" > 1 then "aa" else
"aa" + 10 end;
+% sys.L3 # table_name
+% L3 # name
+% bigint # type
+% 1 # length
+[ 2 ]
+[ 1 ]
+#select case when "aa" > 1 then "aa" else "aa" * 4 end from "groupings" group
by case when "aa" > 1 then "aa" else "aa" * 4 end;
+% sys.L1 # table_name
+% L1 # name
+% bigint # type
+% 1 # length
+[ 4 ]
+[ 2 ]
+#select cast(sum("aa"+"bb") as bigint) from "groupings" group by "aa"+"bb";
+% sys.L4 # table_name
+% L4 # name
+% bigint # type
+% 1 # length
+[ 2 ]
+[ 8 ]
+#select cast(sum("aa"+3452) as bigint) from "groupings" group by "aa"+"bb";
+% sys.L4 # table_name
+% L4 # name
+% bigint # type
+% 4 # length
+[ 3453 ]
+[ 6907 ]
_______________________________________________
checkin-list mailing list
[email protected]
https://www.monetdb.org/mailman/listinfo/checkin-list