Allow function expressions to have variable length of parameters

This commit is contained in:
Pedro 2017-03-07 02:49:29 +01:00
parent f82504b319
commit 9ecfa8e8f6
7 changed files with 48 additions and 6 deletions

View File

@ -644,7 +644,7 @@ comp_expr:
; ;
function_expr: function_expr:
IDENTIFIER '(' opt_distinct expr ')' { $$ = Expr::makeFunctionRef($1, $4, $3); } IDENTIFIER '(' opt_distinct expr_list ')' { $$ = Expr::makeFunctionRef($1, $4, $3); }
; ;
column_name: column_name:

View File

@ -79,10 +79,10 @@ namespace hsql {
return e; return e;
} }
Expr* Expr::makeFunctionRef(char* func_name, Expr* expr, bool distinct) { Expr* Expr::makeFunctionRef(char* func_name, std::vector<Expr*>* exprList, bool distinct) {
Expr* e = new Expr(kExprFunctionRef); Expr* e = new Expr(kExprFunctionRef);
e->name = func_name; e->name = func_name;
e->expr = expr; e->exprList = exprList;
e->distinct = distinct; e->distinct = distinct;
return e; return e;
} }

View File

@ -3,6 +3,7 @@
#include <stdlib.h> #include <stdlib.h>
#include <memory> #include <memory>
#include <vector>
namespace hsql { namespace hsql {
@ -61,6 +62,7 @@ namespace hsql {
Expr* expr; Expr* expr;
Expr* expr2; Expr* expr2;
std::vector<Expr*>* exprList;
char* name; char* name;
char* table; char* table;
char* alias; char* alias;
@ -107,7 +109,7 @@ namespace hsql {
static Expr* makeColumnRef(char* table, char* name); static Expr* makeColumnRef(char* table, char* name);
static Expr* makeFunctionRef(char* func_name, Expr* expr, bool distinct); static Expr* makeFunctionRef(char* func_name, std::vector<Expr*>* exprList, bool distinct);
static Expr* makePlaceholder(int id); static Expr* makePlaceholder(int id);
}; };

View File

@ -1,6 +1,6 @@
-- http://www.sqlserver-dba.com/2011/09/this-is-a-followup-on-my-earlier-post-of-sql-server-test-data-generation-testing-tools-i-had-some-requests-for-my-set-up-pr.html -- http://www.sqlserver-dba.com/2011/09/this-is-a-followup-on-my-earlier-post-of-sql-server-test-data-generation-testing-tools-i-had-some-requests-for-my-set-up-pr.html
SELECT TOP 100 S_ACCTBAL, S_NAME, N_NAME, P_PARTKEY, P_MFGR, S_ADDRESS, S_PHONE, S_COMMENT SELECT TOP 100 S_ACCTBAL, S_NAME, N_NAME, P_PARTKEY, P_MFGR, S_ADDRESS, S_PHONE, S_COMMENT
FROM PART, SUPPLIER, PARTSUPP, NATION, REGION FROM "PART", SUPPLIER, PARTSUPP, NATION, REGION
WHERE P_PARTKEY = PS_PARTKEY AND S_SUPPKEY = PS_SUPPKEY AND P_SIZE = 15 AND WHERE P_PARTKEY = PS_PARTKEY AND S_SUPPKEY = PS_SUPPKEY AND P_SIZE = 15 AND
P_TYPE LIKE '%%BRASS' AND S_NATIONKEY = N_NATIONKEY AND N_REGIONKEY = R_REGIONKEY AND P_TYPE LIKE '%%BRASS' AND S_NATIONKEY = N_NATIONKEY AND N_REGIONKEY = R_REGIONKEY AND
R_NAME = 'EUROPE' AND R_NAME = 'EUROPE' AND

View File

@ -2,7 +2,7 @@
SELECT NATION, O_YEAR, SUM(AMOUNT) AS SUM_PROFIT SELECT NATION, O_YEAR, SUM(AMOUNT) AS SUM_PROFIT
FROM (SELECT N_NAME AS NATION, datepart(yy, O_ORDERDATE) AS O_YEAR, FROM (SELECT N_NAME AS NATION, datepart(yy, O_ORDERDATE) AS O_YEAR,
L_EXTENDEDPRICE*(1-L_DISCOUNT)-PS_SUPPLYCOST*L_QUANTITY AS AMOUNT L_EXTENDEDPRICE*(1-L_DISCOUNT)-PS_SUPPLYCOST*L_QUANTITY AS AMOUNT
FROM PART, SUPPLIER, LINEITEM, PARTSUPP, ORDERS, NATION FROM "PART", SUPPLIER, LINEITEM, PARTSUPP, ORDERS, NATION
WHERE S_SUPPKEY = L_SUPPKEY AND PS_SUPPKEY= L_SUPPKEY AND PS_PARTKEY = L_PARTKEY AND WHERE S_SUPPKEY = L_SUPPKEY AND PS_SUPPKEY= L_SUPPKEY AND PS_PARTKEY = L_PARTKEY AND
P_PARTKEY= L_PARTKEY AND O_ORDERKEY = L_ORDERKEY AND S_NATIONKEY = N_NATIONKEY AND P_PARTKEY= L_PARTKEY AND O_ORDERKEY = L_ORDERKEY AND S_NATIONKEY = N_NATIONKEY AND
P_NAME LIKE '%%green%%') AS PROFIT P_NAME LIKE '%%green%%') AS PROFIT

View File

@ -20,6 +20,45 @@ TEST(SelectTest) {
delete result; delete result;
} }
TEST(SelectExprTest) {
TEST_PARSE_SINGLE_SQL(
"SELECT a, MAX(b), CUSTOM(c, F(un)) FROM students;",
kStmtSelect,
SelectStatement,
result,
stmt);
ASSERT_NULL(stmt->whereClause);
ASSERT_NULL(stmt->groupBy);
ASSERT_EQ(stmt->selectList->size(), 3);
ASSERT(stmt->selectList->at(0)->isType(kExprColumnRef));
ASSERT_STREQ(stmt->selectList->at(0)->getName(), "a");
ASSERT(stmt->selectList->at(1)->isType(kExprFunctionRef));
ASSERT_STREQ(stmt->selectList->at(1)->getName(), "MAX");
ASSERT_NOTNULL(stmt->selectList->at(1)->exprList);
ASSERT_EQ(stmt->selectList->at(1)->exprList->size(), 1);
ASSERT(stmt->selectList->at(1)->exprList->at(0)->isType(kExprColumnRef));
ASSERT_STREQ(stmt->selectList->at(1)->exprList->at(0)->getName(), "b");
ASSERT(stmt->selectList->at(2)->isType(kExprFunctionRef));
ASSERT_STREQ(stmt->selectList->at(2)->getName(), "CUSTOM");
ASSERT_NOTNULL(stmt->selectList->at(2)->exprList);
ASSERT_EQ(stmt->selectList->at(2)->exprList->size(), 2);
ASSERT(stmt->selectList->at(2)->exprList->at(0)->isType(kExprColumnRef));
ASSERT_STREQ(stmt->selectList->at(2)->exprList->at(0)->getName(), "c");
ASSERT(stmt->selectList->at(2)->exprList->at(1)->isType(kExprFunctionRef));
ASSERT_STREQ(stmt->selectList->at(2)->exprList->at(1)->getName(), "F");
ASSERT_EQ(stmt->selectList->at(2)->exprList->at(1)->exprList->size(), 1);
ASSERT(stmt->selectList->at(2)->exprList->at(1)->exprList->at(0)->isType(kExprColumnRef));
ASSERT_STREQ(stmt->selectList->at(2)->exprList->at(1)->exprList->at(0)->getName(), "un");
delete result;
}
TEST(SelectHavingTest) { TEST(SelectHavingTest) {
TEST_PARSE_SINGLE_SQL( TEST_PARSE_SINGLE_SQL(

View File

@ -9,6 +9,7 @@ SELECT * FROM t1 UNION SELECT * FROM t2 ORDER BY col1;
SELECT * FROM (SELECT * FROM t1); SELECT * FROM (SELECT * FROM t1);
SELECT * FROM t1 UNION (SELECT * FROM t2 UNION SELECT * FROM t3) ORDER BY col1; SELECT * FROM t1 UNION (SELECT * FROM t2 UNION SELECT * FROM t3) ORDER BY col1;
SELECT TOP 10 * FROM t1 ORDER BY col1, col2; SELECT TOP 10 * FROM t1 ORDER BY col1, col2;
SELECT a, MAX(b), MAX(c, d), CUSTOM(q, UP(r)) AS f FROM t1;
# JOIN # JOIN
SELECT t1.a, t1.b, t2.c FROM "table" AS t1 JOIN (SELECT * FROM foo JOIN bar ON foo.id = bar.id) t2 ON t1.a = t2.b WHERE (t1.b OR NOT t1.a) AND t2.c = 12.5 SELECT t1.a, t1.b, t2.c FROM "table" AS t1 JOIN (SELECT * FROM foo JOIN bar ON foo.id = bar.id) t2 ON t1.a = t2.b WHERE (t1.b OR NOT t1.a) AND t2.c = 12.5
SELECT * FROM t1 JOIN t2 ON c1 = c2; SELECT * FROM t1 JOIN t2 ON c1 = c2;