Skip to content

Commit

Permalink
fixed #423 IN statement in expression with formatting like at filter;…
Browse files Browse the repository at this point in the history
… added regressions to test 361
  • Loading branch information
tomatolog committed Sep 4, 2018
1 parent 73b468b commit 5d52868
Show file tree
Hide file tree
Showing 5 changed files with 95 additions and 1 deletion.
4 changes: 3 additions & 1 deletion src/sphinxexpr.cpp
Expand Up @@ -2657,11 +2657,13 @@ static inline ESphAttr GetIntType ( int64_t iValue )
/// get the widest numeric type of the two /// get the widest numeric type of the two
static inline ESphAttr WidestType ( ESphAttr a, ESphAttr b ) static inline ESphAttr WidestType ( ESphAttr a, ESphAttr b )
{ {
assert ( IsNumeric(a) && IsNumeric(b) ); assert ( ( IsNumeric(a) && IsNumeric(b) ) || ( IsNumeric(a) && b==SPH_ATTR_JSON_FIELD ) || ( a==SPH_ATTR_JSON_FIELD && IsNumeric(b) ) );
if ( a==SPH_ATTR_FLOAT || b==SPH_ATTR_FLOAT ) if ( a==SPH_ATTR_FLOAT || b==SPH_ATTR_FLOAT )
return SPH_ATTR_FLOAT; return SPH_ATTR_FLOAT;
if ( a==SPH_ATTR_BIGINT || b==SPH_ATTR_BIGINT ) if ( a==SPH_ATTR_BIGINT || b==SPH_ATTR_BIGINT )
return SPH_ATTR_BIGINT; return SPH_ATTR_BIGINT;
if ( a==SPH_ATTR_JSON_FIELD || b==SPH_ATTR_JSON_FIELD )
return SPH_ATTR_BIGINT;
return SPH_ATTR_INTEGER; return SPH_ATTR_INTEGER;
} }


Expand Down
1 change: 1 addition & 0 deletions src/sphinxexpr.y
Expand Up @@ -203,6 +203,7 @@ function:
| TOK_UDF '(' arglist ')' { $$ = pParser->AddNodeUdf ( $1, $3 ); if ( $$<0 ) YYERROR; } | TOK_UDF '(' arglist ')' { $$ = pParser->AddNodeUdf ( $1, $3 ); if ( $$<0 ) YYERROR; }
| TOK_UDF '(' ')' { $$ = pParser->AddNodeUdf ( $1, -1 ); if ( $$<0 ) YYERROR; } | TOK_UDF '(' ')' { $$ = pParser->AddNodeUdf ( $1, -1 ); if ( $$<0 ) YYERROR; }
| TOK_FUNC_IN '(' arg ',' constlist_or_uservar ')'{ $$ = pParser->AddNodeIn ( $3, $5 ); } | TOK_FUNC_IN '(' arg ',' constlist_or_uservar ')'{ $$ = pParser->AddNodeIn ( $3, $5 ); }
| json_field TOK_FUNC_IN '(' constlist_or_uservar ')'{ $$ = pParser->AddNodeIn ( $1, $4 ); }
| TOK_HOOK_FUNC '(' arglist ')' { $$ = pParser->AddNodeHookFunc ( $1, $3 ); if ( $$<0 ) YYERROR; } | TOK_HOOK_FUNC '(' arglist ')' { $$ = pParser->AddNodeHookFunc ( $1, $3 ); if ( $$<0 ) YYERROR; }
| TOK_FUNC_JA '(' expr for_loop ')' { $$ = pParser->AddNodeFor ( $1, $3, $4 ); } | TOK_FUNC_JA '(' expr for_loop ')' { $$ = pParser->AddNodeFor ( $1, $3, $4 ); }
| TOK_FUNC_REMAP '(' expr ',' expr ',' '(' constlist ')' ',' '(' constlist ')' ')' { $$ = pParser->AddNodeRemap ( $3, $5, $8, $12 ); } | TOK_FUNC_REMAP '(' expr ',' expr ',' '(' constlist ')' ',' '(' constlist ')' ')' { $$ = pParser->AddNodeRemap ( $3, $5, $8, $12 ); }
Expand Down
1 change: 1 addition & 0 deletions src/sphinxql.y
Expand Up @@ -959,6 +959,7 @@ expr:
function: function:
TOK_IDENT '(' arglist ')' { TRACK_BOUNDS ( $$, $1, $4 ); } TOK_IDENT '(' arglist ')' { TRACK_BOUNDS ( $$, $1, $4 ); }
| TOK_IN '(' arglist ')' { TRACK_BOUNDS ( $$, $1, $4 ); } // handle exception from 'ident' rule | TOK_IN '(' arglist ')' { TRACK_BOUNDS ( $$, $1, $4 ); } // handle exception from 'ident' rule
| json_field TOK_IN '(' arglist ')' { TRACK_BOUNDS ( $$, $1, $5 ); } // handle exception from 'ident' rule
| TOK_INTEGER '(' arglist ')' { TRACK_BOUNDS ( $$, $1, $4 ); } | TOK_INTEGER '(' arglist ')' { TRACK_BOUNDS ( $$, $1, $4 ); }
| TOK_BIGINT '(' arglist ')' { TRACK_BOUNDS ( $$, $1, $4 ); } | TOK_BIGINT '(' arglist ')' { TRACK_BOUNDS ( $$, $1, $4 ); }
| TOK_FLOAT '(' arglist ')' { TRACK_BOUNDS ( $$, $1, $4 ); } | TOK_FLOAT '(' arglist ')' { TRACK_BOUNDS ( $$, $1, $4 ); }
Expand Down
1 change: 1 addition & 0 deletions test/test_361/model.bin
@@ -0,0 +1 @@
a:1:{i:0;a:15:{i:0;a:3:{s:8:"sphinxql";s:18:"select * from test";s:10:"total_rows";i:2;s:4:"rows";a:2:{i:0;a:3:{s:2:"id";s:1:"1";s:3:"gid";s:1:"1";s:1:"j";s:15:"{"a":5,"b":123}";}i:1;a:3:{s:2:"id";s:1:"2";s:3:"gid";s:1:"1";s:1:"j";s:17:"{"a":101,"b":134}";}}}i:1;a:3:{s:8:"sphinxql";s:39:"select * from test where j.a IN (5,100)";s:10:"total_rows";i:1;s:4:"rows";a:1:{i:0;a:3:{s:2:"id";s:1:"1";s:3:"gid";s:1:"1";s:1:"j";s:15:"{"a":5,"b":123}";}}}i:2;a:3:{s:8:"sphinxql";s:57:"select *, IN(j.b, 100, 134) as cnd from test where cnd<>0";s:10:"total_rows";i:1;s:4:"rows";a:1:{i:0;a:4:{s:2:"id";s:1:"2";s:3:"gid";s:1:"1";s:1:"j";s:17:"{"a":101,"b":134}";s:3:"cnd";s:1:"1";}}}i:3;a:3:{s:8:"sphinxql";s:56:"select *, j.b IN(100, 134) as cnd from test where cnd<>0";s:10:"total_rows";i:1;s:4:"rows";a:1:{i:0;a:4:{s:2:"id";s:1:"2";s:3:"gid";s:1:"1";s:1:"j";s:17:"{"a":101,"b":134}";s:3:"cnd";s:1:"1";}}}i:4;a:3:{s:8:"sphinxql";s:39:"select * from dist where j.a IN (5,100)";s:10:"total_rows";i:1;s:4:"rows";a:1:{i:0;a:3:{s:2:"id";s:1:"1";s:3:"gid";s:1:"1";s:1:"j";s:15:"{"a":5,"b":123}";}}}i:5;a:3:{s:8:"sphinxql";s:57:"select *, IN(j.b, 100, 134) as cnd from dist where cnd<>0";s:10:"total_rows";i:1;s:4:"rows";a:1:{i:0;a:4:{s:2:"id";s:1:"2";s:3:"gid";s:1:"1";s:1:"j";s:17:"{"a":101,"b":134}";s:3:"cnd";s:1:"1";}}}i:6;a:3:{s:8:"sphinxql";s:56:"select *, j.b IN(100, 134) as cnd from dist where cnd<>0";s:10:"total_rows";i:1;s:4:"rows";a:1:{i:0;a:4:{s:2:"id";s:1:"2";s:3:"gid";s:1:"1";s:1:"j";s:17:"{"a":101,"b":134}";s:3:"cnd";s:1:"1";}}}i:7;a:2:{s:8:"sphinxql";s:62:"INSERT INTO pq (query, filters) VALUES ('', 'j.a IN (5, 100)')";s:14:"total_affected";i:1;}i:8;a:2:{s:8:"sphinxql";s:63:"INSERT INTO pq (query, filters) VALUES ('', 'IN (j.a, 5, 100)')";s:14:"total_affected";i:1;}i:9;a:2:{s:8:"sphinxql";s:82:"INSERT INTO pq (query, filters) VALUES ('', 'j.a IN (5, 100) and CRC32(\'test\')')";s:14:"total_affected";i:1;}i:10;a:2:{s:8:"sphinxql";s:83:"INSERT INTO pq (query, filters) VALUES ('', 'IN (j.a, 5, 100) and CRC32(\'test\')')";s:14:"total_affected";i:1;}i:11;a:2:{s:8:"sphinxql";s:84:"INSERT INTO pq (query, filters) VALUES ('', 'j.a IN (5, 100) or IN (j.b, 134, 200)')";s:14:"total_affected";i:1;}i:12;a:2:{s:8:"sphinxql";s:84:"INSERT INTO pq (query, filters) VALUES ('', 'IN (j.a, 5, 100) or j.b IN (134, 200)')";s:14:"total_affected";i:1;}i:13;a:3:{s:8:"sphinxql";s:93:"CALL PQ ('pq', ('{"j":{"a":5, "b":123}}', '{"j":{"a":101, "b":134}}'), 1 as docs, 1 as query)";s:10:"total_rows";i:6;s:4:"rows";a:6:{i:0;a:5:{s:3:"UID";s:1:"1";s:9:"Documents";s:1:"1";s:5:"Query";s:0:"";s:4:"Tags";s:0:"";s:7:"Filters";s:15:" j.a IN (5,100)";}i:1;a:5:{s:3:"UID";s:1:"2";s:9:"Documents";s:1:"1";s:5:"Query";s:0:"";s:4:"Tags";s:0:"";s:7:"Filters";s:17:" IN (j.a, 5, 100)";}i:2;a:5:{s:3:"UID";s:1:"3";s:9:"Documents";s:1:"1";s:5:"Query";s:0:"";s:4:"Tags";s:0:"";s:7:"Filters";s:34:" j.a IN (5, 100) and CRC32('test')";}i:3;a:5:{s:3:"UID";s:1:"4";s:9:"Documents";s:1:"1";s:5:"Query";s:0:"";s:4:"Tags";s:0:"";s:7:"Filters";s:35:" IN (j.a, 5, 100) and CRC32('test')";}i:4;a:5:{s:3:"UID";s:1:"5";s:9:"Documents";s:3:"1,2";s:5:"Query";s:0:"";s:4:"Tags";s:0:"";s:7:"Filters";s:38:" j.a IN (5, 100) or IN (j.b, 134, 200)";}i:5;a:5:{s:3:"UID";s:1:"6";s:9:"Documents";s:3:"1,2";s:5:"Query";s:0:"";s:4:"Tags";s:0:"";s:7:"Filters";s:38:" IN (j.a, 5, 100) or j.b IN (134, 200)";}}}i:14;a:3:{s:8:"sphinxql";s:39:"select *, IN (missed.a,5,100) from test";s:5:"error";s:47:"index test: parse error: unknown column: missed";s:5:"errno";i:1064;}}}
89 changes: 89 additions & 0 deletions test/test_361/test.xml
@@ -0,0 +1,89 @@
<?xml version="1.0" encoding="utf-8"?>
<test>

<name>IN filter vs expression</name>

<config>
indexer
{
mem_limit = 16M
}

searchd
{
<searchd_settings/>
workers = threads
}

source test
{
type = mysql
<sql_settings/>
sql_query = select * from test_table
sql_attr_uint = gid
sql_attr_json = j
}

index test
{
source = test
path = <data_path/>/test
}

index pq
{
type = percolate
path = <data_path/>/pq_re
rt_field = title
rt_attr_json = j
}

index dist
{
type = distributed
agent = <my_address/>:test
}
</config>

<db_create>
CREATE TABLE `test_table` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`gid` int(11) NOT NULL,
`title` varchar(255) NOT NULL,
`j` varchar(8192) NOT NULL,
PRIMARY KEY (`id`)
);
</db_create>
<db_drop>DROP TABLE IF EXISTS `test_table`;</db_drop>
<db_insert>
INSERT INTO `test_table` VALUES
(1,1,'test one','{"a":5,"b":123}'),
(2,1,'test two','{"a":101,"b":134}')
</db_insert>

<sphqueries>
<!-- IN for plain indexes -->
<sphinxql>select * from test</sphinxql>
<sphinxql>select * from test where j.a IN (5,100)</sphinxql>
<sphinxql>select *, IN(j.b, 100, 134) as cnd from test where cnd&lt;&gt;0</sphinxql>
<sphinxql>select *, j.b IN(100, 134) as cnd from test where cnd&lt;&gt;0</sphinxql>

<!-- IN for distributed indexes -->
<sphinxql>select * from dist where j.a IN (5,100)</sphinxql>
<sphinxql>select *, IN(j.b, 100, 134) as cnd from dist where cnd&lt;&gt;0</sphinxql>
<sphinxql>select *, j.b IN(100, 134) as cnd from dist where cnd&lt;&gt;0</sphinxql>

<!-- IN for PQ indexes -->
<sphinxql>INSERT INTO pq (query, filters) VALUES ('', 'j.a IN (5, 100)')</sphinxql>
<sphinxql>INSERT INTO pq (query, filters) VALUES ('', 'IN (j.a, 5, 100)')</sphinxql>
<sphinxql>INSERT INTO pq (query, filters) VALUES ('', 'j.a IN (5, 100) and CRC32(\'test\')')</sphinxql>
<sphinxql>INSERT INTO pq (query, filters) VALUES ('', 'IN (j.a, 5, 100) and CRC32(\'test\')')</sphinxql>
<sphinxql>INSERT INTO pq (query, filters) VALUES ('', 'j.a IN (5, 100) or IN (j.b, 134, 200)')</sphinxql>
<sphinxql>INSERT INTO pq (query, filters) VALUES ('', 'IN (j.a, 5, 100) or j.b IN (134, 200)')</sphinxql>

<sphinxql>CALL PQ ('pq', ('{"j":{"a":5, "b":123}}', '{"j":{"a":101, "b":134}}'), 1 as docs, 1 as query)</sphinxql>

<!-- crash on IN for plain indexes -->
<sphinxql>select *, IN (missed.a,5,100) from test</sphinxql>
</sphqueries>
</test>

0 comments on commit 5d52868

Please sign in to comment.