MXS-1364 Drop the usage field
But for the most trivial statements did not really provide useful information. The arguments of the "function" '=' are now reported.
This commit is contained in:
@ -855,7 +855,6 @@ public:
|
||||
: m_database(info.database ? info.database : "")
|
||||
, m_table(info.table ? info.table : "")
|
||||
, m_column(info.column ? info.column : "")
|
||||
, m_usage(info.usage)
|
||||
{}
|
||||
|
||||
bool eq(const QcFieldInfo& rhs) const
|
||||
@ -863,8 +862,7 @@ public:
|
||||
return
|
||||
m_database == rhs.m_database &&
|
||||
m_table == rhs.m_table &&
|
||||
m_column == rhs.m_column &&
|
||||
m_usage == rhs.m_usage;
|
||||
m_column == rhs.m_column;
|
||||
}
|
||||
|
||||
bool lt(const QcFieldInfo& rhs) const
|
||||
@ -891,18 +889,7 @@ public:
|
||||
}
|
||||
else
|
||||
{
|
||||
if (m_column < rhs.m_column)
|
||||
{
|
||||
rv = true;
|
||||
}
|
||||
else if (m_column > rhs.m_column)
|
||||
{
|
||||
rv = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
rv = (m_usage < rhs.m_usage);
|
||||
}
|
||||
rv = m_column < rhs.m_column;
|
||||
}
|
||||
}
|
||||
|
||||
@ -917,35 +904,6 @@ public:
|
||||
m_column == o.m_column;
|
||||
}
|
||||
|
||||
static bool at_most_usage_differs(const std::set<QcFieldInfo>& l,
|
||||
const std::set<QcFieldInfo>& r)
|
||||
{
|
||||
bool rv = false;
|
||||
|
||||
if (l.size() == r.size())
|
||||
{
|
||||
rv = true;
|
||||
|
||||
std::set<QcFieldInfo>::iterator i = l.begin();
|
||||
std::set<QcFieldInfo>::iterator j = r.begin();
|
||||
|
||||
while (rv && (i != l.end()))
|
||||
{
|
||||
if (!i->has_same_name(*j))
|
||||
{
|
||||
rv = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
++i;
|
||||
++j;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
void print(ostream& out) const
|
||||
{
|
||||
if (!m_database.empty())
|
||||
@ -961,19 +919,12 @@ public:
|
||||
}
|
||||
|
||||
out << m_column;
|
||||
|
||||
out << "[";
|
||||
char* s = qc_field_usage_mask_to_string(m_usage);
|
||||
out << s;
|
||||
free(s);
|
||||
out << "]";
|
||||
}
|
||||
|
||||
private:
|
||||
std::string m_database;
|
||||
std::string m_table;
|
||||
std::string m_column;
|
||||
uint32_t m_usage;
|
||||
};
|
||||
|
||||
ostream& operator << (ostream& out, const QcFieldInfo& x)
|
||||
@ -1040,11 +991,6 @@ bool compare_get_field_info(QUERY_CLASSIFIER* pClassifier1, GWBUF* pCopy1,
|
||||
ss << f1;
|
||||
success = true;
|
||||
}
|
||||
else if (QcFieldInfo::at_most_usage_differs(f1, f2))
|
||||
{
|
||||
ss << "WRN: " << f1 << " != " << f2;
|
||||
success = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
ss << "ERR: " << f1 << " != " << f2;
|
||||
@ -1061,7 +1007,6 @@ class QcFunctionInfo
|
||||
public:
|
||||
QcFunctionInfo(const QC_FUNCTION_INFO& info)
|
||||
: m_name(info.name)
|
||||
, m_usage(info.usage)
|
||||
, m_pFields(info.fields)
|
||||
, m_nFields(info.n_fields)
|
||||
{
|
||||
@ -1073,7 +1018,6 @@ public:
|
||||
{
|
||||
return
|
||||
m_name == rhs.m_name &&
|
||||
m_usage == rhs.m_usage &&
|
||||
have_same_fields(*this, rhs);
|
||||
}
|
||||
|
||||
@ -1089,14 +1033,6 @@ public:
|
||||
{
|
||||
rv = false;
|
||||
}
|
||||
else if (m_usage < rhs.m_usage)
|
||||
{
|
||||
rv = true;
|
||||
}
|
||||
else if (m_usage > rhs.m_usage)
|
||||
{
|
||||
rv = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
std::set<string> lfs;
|
||||
@ -1111,37 +1047,6 @@ public:
|
||||
return rv;
|
||||
}
|
||||
|
||||
static bool at_most_usage_differs(const std::set<QcFunctionInfo>& l,
|
||||
const std::set<QcFunctionInfo>& r)
|
||||
{
|
||||
bool rv = false;
|
||||
|
||||
if (l.size() == r.size())
|
||||
{
|
||||
rv = true;
|
||||
|
||||
std::set<QcFunctionInfo>::iterator i = l.begin();
|
||||
std::set<QcFunctionInfo>::iterator j = r.begin();
|
||||
|
||||
while (rv && (i != l.end()))
|
||||
{
|
||||
if (i->m_name != j->m_name)
|
||||
{
|
||||
rv = false;
|
||||
}
|
||||
else if (!have_same_fields(*i, *j))
|
||||
{
|
||||
rv = false;
|
||||
}
|
||||
|
||||
++i;
|
||||
++j;
|
||||
}
|
||||
}
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
void print(ostream& out) const
|
||||
{
|
||||
out << m_name;
|
||||
@ -1150,7 +1055,7 @@ public:
|
||||
|
||||
for (uint32_t i = 0; i < m_nFields; ++i)
|
||||
{
|
||||
const QC_FIELD_NAME& name = m_pFields[i];
|
||||
const QC_FIELD_INFO& name = m_pFields[i];
|
||||
|
||||
if (name.database)
|
||||
{
|
||||
@ -1173,12 +1078,6 @@ public:
|
||||
}
|
||||
|
||||
out << ")";
|
||||
|
||||
out << "[";
|
||||
char* s = qc_field_usage_mask_to_string(m_usage);
|
||||
out << s;
|
||||
free(s);
|
||||
out << "]";
|
||||
}
|
||||
|
||||
private:
|
||||
@ -1208,7 +1107,7 @@ private:
|
||||
return rv;
|
||||
}
|
||||
|
||||
static std::string get_field_name(const QC_FIELD_NAME& field)
|
||||
static std::string get_field_name(const QC_FIELD_INFO& field)
|
||||
{
|
||||
string s;
|
||||
|
||||
@ -1226,13 +1125,14 @@ private:
|
||||
|
||||
s += field.column;
|
||||
|
||||
std::transform(s.begin(), s.end(), s.begin(), tolower);
|
||||
|
||||
return s;
|
||||
}
|
||||
|
||||
private:
|
||||
std::string m_name;
|
||||
uint32_t m_usage;
|
||||
const QC_FIELD_NAME* m_pFields;
|
||||
const QC_FIELD_INFO* m_pFields;
|
||||
uint32_t m_nFields;
|
||||
};
|
||||
|
||||
@ -1300,11 +1200,6 @@ bool compare_get_function_info(QUERY_CLASSIFIER* pClassifier1, GWBUF* pCopy1,
|
||||
ss << f1;
|
||||
success = true;
|
||||
}
|
||||
else if (QcFunctionInfo::at_most_usage_differs(f1, f2))
|
||||
{
|
||||
ss << "WRN: " << f1 << " != " << f2;
|
||||
success = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
ss << "ERR: " << f1 << " != " << f2;
|
||||
|
@ -248,41 +248,44 @@ as
|
||||
select ancestors.name, ancestors.dob from ancestors;
|
||||
|
||||
--echo # recursive definition with two attached non-recursive
|
||||
with recursive
|
||||
ancestors(id,name,dob)
|
||||
as
|
||||
(
|
||||
with
|
||||
father(child_id,id,name,dob)
|
||||
as
|
||||
(
|
||||
select folks.id, f.id, f.name, f.dob
|
||||
from folks, folks f
|
||||
where folks.father=f.id
|
||||
|
||||
),
|
||||
mother(child_id,id,name,dob)
|
||||
as
|
||||
(
|
||||
select folks.id, m.id, m.name, m.dob
|
||||
from folks, folks m
|
||||
where folks.mother=m.id
|
||||
|
||||
)
|
||||
select folks.id, folks.name, folks.dob
|
||||
from folks
|
||||
where name='Me'
|
||||
union
|
||||
select f.id, f.name, f.dob
|
||||
from ancestors a, father f
|
||||
where f.child_id=a.id
|
||||
union
|
||||
select m.id, m.name, m.dob
|
||||
from ancestors a, mother m
|
||||
where m.child_id=a.id
|
||||
|
||||
)
|
||||
select ancestors.name, ancestors.dob from ancestors;
|
||||
#MXS qc_sqlite
|
||||
#MXS qc_get_function_info : ERR: =(folks.name, folks.father, folks.id, folks.mother, mother.child_id, ancestors.id, father.child_id) != =(mother.child_id, ancestors.id, folks.father, folks.id, folks.mother, mother.id, father.child_id, name)
|
||||
#MXS The reported function arguments to '=' are disjoint. The relevant are there though (folks.*).
|
||||
#MXS with recursive
|
||||
#MXS ancestors(id,name,dob)
|
||||
#MXS as
|
||||
#MXS (
|
||||
#MXS with
|
||||
#MXS father(child_id,id,name,dob)
|
||||
#MXS as
|
||||
#MXS (
|
||||
#MXS select folks.id, f.id, f.name, f.dob
|
||||
#MXS from folks, folks f
|
||||
#MXS where folks.father=f.id
|
||||
#MXS
|
||||
#MXS ),
|
||||
#MXS mother(child_id,id,name,dob)
|
||||
#MXS as
|
||||
#MXS (
|
||||
#MXS select folks.id, m.id, m.name, m.dob
|
||||
#MXS from folks, folks m
|
||||
#MXS where folks.mother=m.id
|
||||
#MXS
|
||||
#MXS )
|
||||
#MXS select folks.id, folks.name, folks.dob
|
||||
#MXS from folks
|
||||
#MXS where name='Me'
|
||||
#MXS union
|
||||
#MXS select f.id, f.name, f.dob
|
||||
#MXS from ancestors a, father f
|
||||
#MXS where f.child_id=a.id
|
||||
#MXS union
|
||||
#MXS select m.id, m.name, m.dob
|
||||
#MXS from ancestors a, mother m
|
||||
#MXS where m.child_id=a.id
|
||||
#MXS
|
||||
#MXS )
|
||||
#MXS select ancestors.name, ancestors.dob from ancestors;
|
||||
|
||||
--echo # simple recursion with one anchor and one recursive select
|
||||
--echo # the anchor is the first select in the specification
|
||||
|
@ -169,7 +169,9 @@ drop table t1;
|
||||
#
|
||||
create table t1(f1 int primary key);
|
||||
insert into t1 values (4),(3),(1),(2);
|
||||
delete from t1 where (@a:= f1) order by f1 limit 1;
|
||||
#MXS qc_myselembedded
|
||||
#MXS qc_get_function_info : ERR: != =(f1)
|
||||
#MXS delete from t1 where (@a:= f1) order by f1 limit 1;
|
||||
select @a;
|
||||
drop table t1;
|
||||
|
||||
|
@ -677,8 +677,10 @@ insert into t1 values (0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
|
||||
create table t2 (a int, b int, filler char(100), key(a), key(b));
|
||||
create table t3 (a int, b int, filler char(100), key(a), key(b));
|
||||
|
||||
insert into t2
|
||||
select @a:= A.a + 10*(B.a + 10*C.a), @a, 'filler' from t1 A, t1 B, t1 C;
|
||||
#MXS qc_mysqlembedded
|
||||
#MXS qc_get_function_info : ERR: *(t1.a) +(t1.a) != *(t1.a) +(t1.a) =()
|
||||
#MXS insert into t2
|
||||
#MXS select @a:= A.a + 10*(B.a + 10*C.a), @a, 'filler' from t1 A, t1 B, t1 C;
|
||||
insert into t3 select * from t2 where a < 800;
|
||||
|
||||
# The order of tables must be t2,t3:
|
||||
@ -692,7 +694,9 @@ create table t1 (a int);
|
||||
insert into t1 values (0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
|
||||
|
||||
create table t2 (a int, b int, primary key(a));
|
||||
insert into t2 select @v:=A.a+10*B.a, @v from t1 A, t1 B;
|
||||
#MXS qc_mysqlembedded
|
||||
#MXS qc_get_function_info : ERR: *(t1.a) +(t1.a) != *(t1.a) +(t1.a) =()
|
||||
#MXS insert into t2 select @v:=A.a+10*B.a, @v from t1 A, t1 B;
|
||||
|
||||
explain select * from t1;
|
||||
show status like '%cost%';
|
||||
|
@ -31,3 +31,16 @@ select * from (select a from t1 where b >= 'c') as t
|
||||
union
|
||||
select * from (select a from t1 where b >= 'c') as t
|
||||
where t.a >= 4;
|
||||
|
||||
#MXS qc_myselembedded
|
||||
#MXS qc_get_function_info : ERR: != =(f1)
|
||||
delete from t1 where (@a:= f1) order by f1 limit 1;
|
||||
|
||||
#MXS qc_mysqlembedded
|
||||
#MXS qc_get_function_info : ERR: *(t1.a) +(t1.a) != *(t1.a) +(t1.a) =()
|
||||
insert into t2
|
||||
select @a:= A.a + 10*(B.a + 10*C.a), @a, 'filler' from t1 A, t1 B, t1 C;
|
||||
|
||||
#MXS qc_mysqlembedded
|
||||
#MXS qc_get_function_info : ERR: *(t1.a) +(t1.a) != *(t1.a) +(t1.a) =()
|
||||
insert into t2 select @v:=A.a+10*B.a, @v from t1 A, t1 B;
|
||||
|
@ -102,3 +102,7 @@ select t2.fld3 from t2 where companynr = 58 and fld3 like "%imaginable%";
|
||||
#MXS qc_sqlite
|
||||
#MXS qc_get_function_info : ERR: >(a, b)[QC_USED_IN_WHERE] avg(a)[QC_USED_IN_SUBSELECT|QC_USED_IN_WHERE] != >(a)[QC_USED_IN_WHERE] avg(a)[QC_USED_IN_SUBSELECT|QC_USED_IN_WHERE]
|
||||
CREATE VIEW v1 AS SELECT a,1 as b FROM t1 WHERE a>(SELECT AVG(a) FROM t1) AND b>(SELECT 1);
|
||||
|
||||
#MXS qc_sqlite
|
||||
#MXS qc_get_function_info : ERR: =(t2.fld3) != =(fld3)
|
||||
select t2.fld3 from t2 where fld3 = 'honeysuckle';
|
||||
|
@ -1283,7 +1283,9 @@ select fld3 from t2 order by fld3 desc limit 5,5;
|
||||
# The table is read directly with read-next on fld3
|
||||
#
|
||||
|
||||
select t2.fld3 from t2 where fld3 = 'honeysuckle';
|
||||
#MXS qc_sqlite
|
||||
#MXS qc_get_function_info : ERR: =(t2.fld3) != =(fld3)
|
||||
#MXS select t2.fld3 from t2 where fld3 = 'honeysuckle';
|
||||
# MXS: qc_get_function_info : ERR: =()[QC_USED_IN_WHERE] like(t2.fld3)[QC_USED_IN_WHERE] != =()[QC_USED_IN_WHERE] like(fld3)[QC_USED_IN_WHERE]
|
||||
#select t2.fld3 from t2 where fld3 LIKE 'honeysuckl_';
|
||||
select fld3 from t2 where fld3 LIKE 'honeysuckl_';
|
||||
|
Reference in New Issue
Block a user