diff --git a/src/sphinxexpr.cpp b/src/sphinxexpr.cpp index 6458da6888..52acab919a 100644 --- a/src/sphinxexpr.cpp +++ b/src/sphinxexpr.cpp @@ -2657,11 +2657,13 @@ static inline ESphAttr GetIntType ( int64_t iValue ) /// get the widest numeric type of the two 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 ) return SPH_ATTR_FLOAT; if ( a==SPH_ATTR_BIGINT || b==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; } diff --git a/src/sphinxexpr.y b/src/sphinxexpr.y index 77caf81ae8..4d049a9c45 100644 --- a/src/sphinxexpr.y +++ b/src/sphinxexpr.y @@ -203,6 +203,7 @@ function: | TOK_UDF '(' arglist ')' { $$ = pParser->AddNodeUdf ( $1, $3 ); if ( $$<0 ) YYERROR; } | TOK_UDF '(' ')' { $$ = pParser->AddNodeUdf ( $1, -1 ); if ( $$<0 ) YYERROR; } | 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_FUNC_JA '(' expr for_loop ')' { $$ = pParser->AddNodeFor ( $1, $3, $4 ); } | TOK_FUNC_REMAP '(' expr ',' expr ',' '(' constlist ')' ',' '(' constlist ')' ')' { $$ = pParser->AddNodeRemap ( $3, $5, $8, $12 ); } diff --git a/src/sphinxql.y b/src/sphinxql.y index 0018d9e138..1fc9ebb852 100644 --- a/src/sphinxql.y +++ b/src/sphinxql.y @@ -959,6 +959,7 @@ expr: function: TOK_IDENT '(' arglist ')' { TRACK_BOUNDS ( $$, $1, $4 ); } | 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_BIGINT '(' arglist ')' { TRACK_BOUNDS ( $$, $1, $4 ); } | TOK_FLOAT '(' arglist ')' { TRACK_BOUNDS ( $$, $1, $4 ); } diff --git a/test/test_361/model.bin b/test/test_361/model.bin new file mode 100644 index 0000000000..a3123f50d9 --- /dev/null +++ b/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;}}} \ No newline at end of file diff --git a/test/test_361/test.xml b/test/test_361/test.xml new file mode 100644 index 0000000000..a965370c49 --- /dev/null +++ b/test/test_361/test.xml @@ -0,0 +1,89 @@ + + + +IN filter vs expression + + +indexer +{ + mem_limit = 16M +} + +searchd +{ + + workers = threads +} + +source test +{ + type = mysql + + sql_query = select * from test_table + sql_attr_uint = gid + sql_attr_json = j +} + +index test +{ + source = test + path = /test +} + +index pq +{ + type = percolate + path = /pq_re + rt_field = title + rt_attr_json = j +} + +index dist +{ + type = distributed + agent = :test +} + + + +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`) +); + +DROP TABLE IF EXISTS `test_table`; + +INSERT INTO `test_table` VALUES +(1,1,'test one','{"a":5,"b":123}'), +(2,1,'test two','{"a":101,"b":134}') + + + + +select * from test +select * from test where j.a IN (5,100) +select *, IN(j.b, 100, 134) as cnd from test where cnd<>0 +select *, j.b IN(100, 134) as cnd from test where cnd<>0 + + +select * from dist where j.a IN (5,100) +select *, IN(j.b, 100, 134) as cnd from dist where cnd<>0 +select *, j.b IN(100, 134) as cnd from dist where cnd<>0 + + +INSERT INTO pq (query, filters) VALUES ('', 'j.a IN (5, 100)') +INSERT INTO pq (query, filters) VALUES ('', 'IN (j.a, 5, 100)') +INSERT INTO pq (query, filters) VALUES ('', 'j.a IN (5, 100) and CRC32(\'test\')') +INSERT INTO pq (query, filters) VALUES ('', 'IN (j.a, 5, 100) and CRC32(\'test\')') +INSERT INTO pq (query, filters) VALUES ('', 'j.a IN (5, 100) or IN (j.b, 134, 200)') +INSERT INTO pq (query, filters) VALUES ('', 'IN (j.a, 5, 100) or j.b IN (134, 200)') + +CALL PQ ('pq', ('{"j":{"a":5, "b":123}}', '{"j":{"a":101, "b":134}}'), 1 as docs, 1 as query) + + +select *, IN (missed.a,5,100) from test + +