diff --git a/mysql-test/lib/My/Config.pm b/mysql-test/lib/My/Config.pm index c88b1170a80df..0e440c2459c53 100644 --- a/mysql-test/lib/My/Config.pm +++ b/mysql-test/lib/My/Config.pm @@ -25,7 +25,7 @@ use Carp; # many times in the config file. Note that options must be written # using '-' instead of '_' here! -my %multipart_options= +our %multipart_options= ( "plugin-load-add" => 1, "optimizer-switch" => 1, diff --git a/storage/sphinx/mysql-test/sphinx/my.cnf b/storage/sphinx/mysql-test/sphinx/my.cnf index f60380b7171e1..8a9ea17cefbd1 100644 --- a/storage/sphinx/mysql-test/sphinx/my.cnf +++ b/storage/sphinx/mysql-test/sphinx/my.cnf @@ -7,7 +7,6 @@ xmlpipe_command = cat @ENV.MTR_SUITE_DIR/testdata.xml [index test1] source = src1 docinfo = extern -charset_type = utf-8 path = @ENV.MYSQLTEST_VARDIR/searchd/test1 [indexer] @@ -24,6 +23,8 @@ query_log = @ENV.MYSQLTEST_VARDIR/searchd/sphinx-query.log #log-error = @ENV.MYSQLTEST_VARDIR/searchd/sphinx.log pid_file = @ENV.MYSQLTEST_VARDIR/run/searchd.pid listen = @ENV.SPHINXSEARCH_PORT +listen = @ENV.SPHINXSEARCH_SOCKET [ENV] SPHINXSEARCH_PORT = @OPT.port +SPHINXSEARCH_SOCKET = @ENV.MYSQLTEST_VARDIR/run/sphinx.socket diff --git a/storage/sphinx/mysql-test/sphinx/sphinx.result b/storage/sphinx/mysql-test/sphinx/sphinx.result index c462d0cc8839a..3b6ad98960eb9 100644 --- a/storage/sphinx/mysql-test/sphinx/sphinx.result +++ b/storage/sphinx/mysql-test/sphinx/sphinx.result @@ -95,3 +95,20 @@ id w q 1 2 test;range=meta.foo_count,100,500 5 1 test;range=meta.foo_count,100,500 drop table ts; +# MDEV-37969 sphinx_snippets() UDF fails to resolve hostname +CREATE FUNCTION sphinx_snippets RETURNS STRING SONAME 'ha_sphinx.so'; +SELECT sphinx_snippets('d', 'test1', 'search_term', 'sphinx://localhost:SPHINXSEARCH_PORT' AS sphinx); +sphinx_snippets('d', 'test1', 'search_term', 'sphinx://localhost:SPHINXSEARCH_PORT' AS sphinx) +d +SELECT sphinx_snippets('this is to test groups', 'test1', 'groups', 'sphinx://127.0.0.1:19001' AS sphinx); +sphinx_snippets('this is to test groups', 'test1', 'groups', 'sphinx://127.0.0.1:19001' AS sphinx) +this is to test groups +SELECT sphinx_snippets('this is to test groups', 'test1', 'groups', 'unix://SPHINXSEARCH_SOCKET' AS sphinx); +sphinx_snippets('this is to test groups', 'test1', 'groups', 'unix://SPHINXSEARCH_SOCKET' AS sphinx) +this is to test groups +SELECT sphinx_snippets('d', 'test1', 'search_term', 'sphinx://somedomainthatdoesntresolve.example.com:19001' AS sphinx); +ERROR HY000: Unable to connect to foreign data source: failed to resolve searchd host (name=somedomainthatdoesntresolve +SELECT sphinx_snippets('this is to test groups', 'test1', 'groups', 'unix:///home/dan/repos/build-mariadb-server-10.11/mysql-test/var/tmp/missing_socket' AS sphinx); +ERROR HY000: Unable to connect to foreign data source: unix:////home/dan/repos/build-mariadb-server-10.11/mysql-test/va +DROP FUNCTION sphinx_snippets; +# End of 10.11 tests diff --git a/storage/sphinx/mysql-test/sphinx/sphinx.test b/storage/sphinx/mysql-test/sphinx/sphinx.test index b733a3fc5ff7a..aa5de0c10491e 100644 --- a/storage/sphinx/mysql-test/sphinx/sphinx.test +++ b/storage/sphinx/mysql-test/sphinx/sphinx.test @@ -54,3 +54,20 @@ select * from ts where q=';filter=meta.sub.list[0],4'; select * from ts where q=';filter=meta.sub.list[1],4'; select * from ts where q='test;range=meta.foo_count,100,500'; drop table ts; + +--echo # MDEV-37969 sphinx_snippets() UDF fails to resolve hostname + +eval CREATE FUNCTION sphinx_snippets RETURNS STRING SONAME '$HA_SPHINX_SO'; +--replace_result $SPHINXSEARCH_PORT SPHINXSEARCH_PORT +eval SELECT sphinx_snippets('d', 'test1', 'search_term', 'sphinx://localhost:$SPHINXSEARCH_PORT' AS sphinx); +eval SELECT sphinx_snippets('this is to test groups', 'test1', 'groups', 'sphinx://127.0.0.1:$SPHINXSEARCH_PORT' AS sphinx); +--replace_result $SPHINXSEARCH_SOCKET SPHINXSEARCH_SOCKET +eval SELECT sphinx_snippets('this is to test groups', 'test1', 'groups', 'unix://$SPHINXSEARCH_SOCKET' AS sphinx); + +--error ER_CONNECT_TO_FOREIGN_DATA_SOURCE +eval SELECT sphinx_snippets('d', 'test1', 'search_term', 'sphinx://somedomainthatdoesntresolve.example.com:$SPHINXSEARCH_PORT' AS sphinx); +--error ER_CONNECT_TO_FOREIGN_DATA_SOURCE +eval SELECT sphinx_snippets('this is to test groups', 'test1', 'groups', 'unix://$MYSQL_TMP_DIR/missing_socket' AS sphinx); +DROP FUNCTION sphinx_snippets; + +--echo # End of 10.11 tests diff --git a/storage/sphinx/mysql-test/sphinx/suite.pm b/storage/sphinx/mysql-test/sphinx/suite.pm index e44a8e626df1c..4c46c3deee10f 100644 --- a/storage/sphinx/mysql-test/sphinx/suite.pm +++ b/storage/sphinx/mysql-test/sphinx/suite.pm @@ -4,6 +4,9 @@ use My::SafeProcess; use My::File::Path; use mtr_report; +# Sphinx configuration supports multiple listens +$My::Config::Option::multipart_options{"listen"} = 1; + @ISA = qw(My::Suite); ############# initialization ###################### diff --git a/storage/sphinx/snippets_udf.cc b/storage/sphinx/snippets_udf.cc index 8b87d9dce0429..61b282df70269 100644 --- a/storage/sphinx/snippets_udf.cc +++ b/storage/sphinx/snippets_udf.cc @@ -26,22 +26,13 @@ #include -#if MYSQL_VERSION_ID>=50515 #include "sql_class.h" #include "sql_array.h" -#elif MYSQL_VERSION_ID>50100 -#include "mysql_priv.h" -#include -#else -#include "../mysql_priv.h" -#endif #include #include -#if MYSQL_VERSION_ID>=50120 typedef uchar byte; -#endif /// partially copy-pasted stuff that should be moved elsewhere @@ -90,7 +81,6 @@ void sphUnalignedWrite ( void * pPtr, const T & tVal ) #define SafeDelete(_arg) { if ( _arg ) delete ( _arg ); (_arg) = NULL; } #define SafeDeleteArray(_arg) { if ( _arg ) delete [] ( _arg ); (_arg) = NULL; } -#define Min(a,b) ((a)<(b)?(a):(b)) #ifndef _WIN32 typedef unsigned int DWORD; #endif @@ -360,82 +350,68 @@ bool CSphUrl::Parse ( const char * sUrl, int iLen ) int CSphUrl::Connect() { - struct sockaddr_in sin; -#ifndef _WIN32 - struct sockaddr_un saun; -#endif - - int iDomain = 0; - int iSockaddrSize = 0; - struct sockaddr * pSockaddr = NULL; - - in_addr_t ip_addr; + int iSocket = -1; if ( m_iPort ) { - iDomain = AF_INET; - iSockaddrSize = sizeof(sin); - pSockaddr = (struct sockaddr *) &sin; + char portStr[16]; + struct addrinfo hints, *hp, *p; + int tmp_errno; - memset ( &sin, 0, sizeof(sin) ); - sin.sin_family = AF_INET; - sin.sin_port = htons ( m_iPort ); + my_snprintf(portStr, sizeof(portStr), "%d", m_iPort); - // resolve address - if ( (int)( ip_addr = inet_addr ( m_sHost ) )!=(int)INADDR_NONE ) - memcpy ( &sin.sin_addr, &ip_addr, sizeof(ip_addr) ); - else + memset(&hints, 0, sizeof(hints)); + hints.ai_family = AF_UNSPEC; + hints.ai_socktype = SOCK_STREAM; + + tmp_errno = getaddrinfo ( m_sHost, portStr, &hints, &hp ); + if ( tmp_errno!=0 || !hp || !hp->ai_addr ) { - int tmp_errno; - bool bError = false; + char sError[256]; + my_snprintf ( sError, sizeof(sError), + "failed to resolve searchd host (name=%s) because %s", + m_sHost, gai_strerror(tmp_errno) ); -#if MYSQL_VERSION_ID>=50515 - struct addrinfo *hp = NULL; - tmp_errno = getaddrinfo ( m_sHost, NULL, NULL, &hp ); - if ( !tmp_errno || !hp || !hp->ai_addr ) - { - bError = true; - if ( hp ) - freeaddrinfo ( hp ); - } -#else - struct hostent tmp_hostent, *hp; - char buff2 [ GETHOSTBYNAME_BUFF_SIZE ]; - hp = my_gethostbyname_r ( m_sHost, &tmp_hostent, buff2, sizeof(buff2), &tmp_errno ); - if ( !hp ) - { - my_gethostbyname_r_free(); - bError = true; - } -#endif + my_error ( ER_CONNECT_TO_FOREIGN_DATA_SOURCE, MYF(0), sError ); + return -1; + } - if ( bError ) - { - char sError[256]; - my_snprintf ( sError, sizeof(sError), "failed to resolve searchd host (name=%s)", m_sHost ); + for (p = hp; p != NULL; p = p->ai_next) + { + iSocket = socket(p->ai_family, p->ai_socktype, p->ai_protocol); + if (iSocket == -1) + continue; - my_error ( ER_CONNECT_TO_FOREIGN_DATA_SOURCE, MYF(0), sError ); - return -1; - } + if (connect(iSocket, p->ai_addr, p->ai_addrlen) == 0) + break; // success -#if MYSQL_VERSION_ID>=50515 - memcpy ( &sin.sin_addr, hp->ai_addr, Min ( sizeof(sin.sin_addr), (size_t)hp->ai_addrlen ) ); - freeaddrinfo ( hp ); -#else - memcpy ( &sin.sin_addr, hp->h_addr, Min ( sizeof(sin.sin_addr), (size_t)hp->h_length ) ); - my_gethostbyname_r_free(); -#endif + close(iSocket); + iSocket = -2; } + freeaddrinfo ( hp ); } else { #ifndef _WIN32 - iDomain = AF_UNIX; - iSockaddrSize = sizeof(saun); - pSockaddr = (struct sockaddr *) &saun; - + struct sockaddr_un saun; memset ( &saun, 0, sizeof(saun) ); saun.sun_family = AF_UNIX; + + if (strlen(m_sHost) >= sizeof(saun.sun_path)) + { + my_error ( ER_CONNECT_TO_FOREIGN_DATA_SOURCE, MYF(0), "Unix socket path too long" ); + return -1; + } strncpy ( saun.sun_path, m_sHost, sizeof(saun.sun_path)-1 ); + + iSocket = socket(AF_UNIX, SOCK_STREAM, 0); + if (iSocket >= 0) + { + if (connect(iSocket, (struct sockaddr *)&saun, sizeof(saun)) == -1) + { + close(iSocket); + iSocket = -2; + } + } #else my_error ( ER_CONNECT_TO_FOREIGN_DATA_SOURCE, MYF(0), "Unix-domain sockets are not supported on Windows" ); return -1; @@ -445,36 +421,17 @@ int CSphUrl::Connect() // connect to searchd and exchange versions uint uServerVersion; uint uClientVersion = htonl ( SPHINX_SEARCHD_PROTO ); - int iSocket = -1; const char * pError = NULL; - do - { - iSocket = (int)socket ( iDomain, SOCK_STREAM, 0 ); - if ( iSocket==-1 ) - { - pError = "Failed to create client socket"; - break; - } + if ( iSocket == -1 ) + pError = "Failed to create client socket"; + else if ( iSocket == -2 ) + pError = "Failed to connect to searchd"; - if ( connect ( iSocket, pSockaddr, iSockaddrSize )==-1 ) - { - pError = "Failed to connect to searchd"; - break; - } - - if ( !sphRecv ( iSocket, (char *)&uServerVersion, sizeof(uServerVersion) ) ) - { - pError = "Failed to receive searchd version"; - break; - } + else if ( !sphRecv ( iSocket, (char *)&uServerVersion, sizeof(uServerVersion) ) ) + pError = "Failed to receive searchd version"; - if ( !sphSend ( iSocket, (char *)&uClientVersion, sizeof(uClientVersion) ) ) - { - pError = "Failed to send client version"; - break; - } - } - while(0); + else if ( !sphSend ( iSocket, (char *)&uClientVersion, sizeof(uClientVersion) ) ) + pError = "Failed to send client version"; // fixme: compare versions? @@ -484,8 +441,8 @@ int CSphUrl::Connect() snprintf ( sError, sizeof(sError), "%s [%d] %s", Format(), errno, strerror(errno) ); my_error ( ER_CONNECT_TO_FOREIGN_DATA_SOURCE, MYF(0), sError ); - if ( iSocket!=-1 ) - close ( iSocket ); + if ( iSocket >= 0 ) + close(iSocket); return -1; }