← Back to team overview

maria-developers team mailing list archive

SphinxSE pushed into 5.2

 

Hi,

I have pushed SphinxSE into MariaDB 5.2. It should be available in the
upcoming MariaDB 5.2.2, which is currently planned within a few weeks.

For now, only the code for the storage engine is pushed, not for the
mysql-test-run.pl stuff. Sergei Golubchik wanted to modify mysql-test-run.pl
first so that engine-specific code can be added in a more modular fashion (he
will do it when he returns from vacation).

For now, the engine is by default built as a loadable .so plugin. This is the
general policy for MariaDB for new plugins. I think the idea is that engines
that prove to be stable and well supported by their maintainer can get
promoted to build statically by default (we are still flexing out the new
policy). Note that the engine will still be available by default, the user
will just need to do a one-time INSTALL PLUGIN command. Note also that
SphinxSE can still be built statically with ./configure --with-plugin-sphinx,
only the default is dynamic.

Daniel, you should probably look into documenting the SphinxSE for MariaDB
5.2.2. Andrew kindly gave us permission to use what we need from the Sphinx
documentation:

    http://sphinxsearch.com/docs/current.html#sphinxse

Andrew suggested including also a link to the Sphinx webpage in the MariaDB
documentation for SphinxSE, which is of course a very good idea.

Also you should document how to do the INSTALL PLUGIN command (it's similar to
for OQGraph). Note that the sphinx plugin will be included in eg. deb packages
and so on and installed by default, just the INSTALL PLUGIN command is needed
to enable it.

Andrew, thanks for all your work with this! It is very good to have SphinxSE
included, there have been several requests for this.

We (mainly Sergei) made some changes to the code during review. I attach a
patch for all the changes since your original import, in case you are
interested. Note that I re-added the code when I merged to 5.2 to get a clean
history, so future work on SphinxSE in MariaDB should be based on
lp:maria/5.2, not our old sphinx bzr trees.

 - Kristian.

diff -u --recursive tmp/storage/sphinxse/ha_sphinx.cc mariadb-5.2/storage/sphinx/ha_sphinx.cc
--- tmp/storage/sphinxse/ha_sphinx.cc	2010-07-09 21:06:32.000000000 +0200
+++ mariadb-5.2/storage/sphinx/ha_sphinx.cc	2010-07-09 13:47:47.000000000 +0200
@@ -66,6 +66,10 @@
 #define UNALIGNED_RAM_ACCESS 1
 #endif
 
+#if MYSQL_VERSION_ID<50100
+#define thd_ha_data(X,Y) (X)->ha_data[sphinx_hton.slot]
+#define ha_thd()         current_thd
+#endif // <50100
 
 #if UNALIGNED_RAM_ACCESS
 
@@ -650,12 +654,13 @@
 		#if MYSQL_VERSION_ID > 50100
 		handlerton * hton = (handlerton*) p;
 		hton->state				= SHOW_OPTION_YES;
-		hton->db_type			= DB_TYPE_DEFAULT;
+		hton->db_type			= DB_TYPE_AUTOASSIGN;
 		hton->create			= sphinx_create_handler;
 		hton->close_connection	= sphinx_close_connection;
 		hton->show_status		= sphinx_show_status;
 		hton->panic				= sphinx_panic;
 		hton->flags				= HTON_CAN_RECREATE;
+		sphinx_hton_ptr = hton;
 		#endif
 	}
 	SPH_RET(0);
@@ -1134,7 +1139,6 @@
 #if MYSQL_VERSION_ID>50100
 static handler * sphinx_create_handler ( handlerton * hton, TABLE_SHARE * table, MEM_ROOT * mem_root )
 {
-	sphinx_hton_ptr = hton;
 	return new ( mem_root ) ha_sphinx ( hton, table );
 }
 #endif
@@ -1929,8 +1933,6 @@
 	, m_dUnboundFields ( NULL )
 {
 	SPH_ENTER_METHOD();
-	if ( current_thd )
-		current_thd->variables.engine_condition_pushdown = true;
 	SPH_VOID_RET();
 }
 
@@ -1960,11 +1962,7 @@
 
 	thr_lock_data_init ( &m_pShare->m_tLock, &m_tLock, NULL );
 
-	#if MYSQL_VERSION_ID>50100
 	*thd_ha_data ( table->in_use, ht ) = NULL;
-	#else
-	table->in_use->ha_data [ sphinx_hton.slot ] = NULL;
-	#endif
 
 	SPH_RET(0);
 }
@@ -2410,11 +2408,7 @@
 {
 	// where do we store that pointer in today's version?
 	CSphSEThreadData ** ppTls;
-#if MYSQL_VERSION_ID>50100
-	ppTls = (CSphSEThreadData**) thd_ha_data ( table->in_use, ht );
-#else
-	ppTls = (CSphSEThreadData**) &current_thd->ha_data[sphinx_hton.slot];
-#endif // >50100
+	ppTls = (CSphSEThreadData**) thd_ha_data ( ha_thd(), ht );
 
 	// allocate if needed
 	if ( !*ppTls )
@@ -2997,139 +2991,73 @@
 #define SHOW_VAR_FUNC_BUFF_SIZE 1024
 #endif
 
-CSphSEStats * sphinx_get_stats ( THD * thd, SHOW_VAR * out )
-{
-#if MYSQL_VERSION_ID>50100	
-	if ( sphinx_hton_ptr )
-	{
-		CSphSEThreadData *pTls = (CSphSEThreadData *) *thd_ha_data ( thd, sphinx_hton_ptr );
-
-		if ( pTls && pTls->m_bStats )
-			return &pTls->m_tStats;
-	}
-#else
-	CSphSEThreadData *pTls = (CSphSEThreadData *) thd->ha_data[sphinx_hton.slot];
-	if ( pTls && pTls->m_bStats )
-		return &pTls->m_tStats;
-#endif
-	
-	out->type = SHOW_CHAR;
-	out->value = "";
-	return 0;
-}
-
-int sphinx_showfunc_total ( THD * thd, SHOW_VAR * out, char * )
-{
-	CSphSEStats * pStats = sphinx_get_stats ( thd, out );
-	if ( pStats )
-	{
-		out->type = SHOW_INT;
-		out->value = (char *) &pStats->m_iMatchesTotal;
-	}
-	return 0;
-}
-
-int sphinx_showfunc_total_found ( THD * thd, SHOW_VAR * out, char * )
+static int sphinx_showfunc ( THD * thd, SHOW_VAR * out, char * sBuffer )
 {
-	CSphSEStats * pStats = sphinx_get_stats ( thd, out );
-	if ( pStats )
-	{
-		out->type = SHOW_INT;
-		out->value = (char *) &pStats->m_iMatchesFound;
-	}
-	return 0;
-}
-
-int sphinx_showfunc_time ( THD * thd, SHOW_VAR * out, char * )
-{
-	CSphSEStats * pStats = sphinx_get_stats ( thd, out );
-	if ( pStats )
-	{
-		out->type = SHOW_INT;
-		out->value = (char *) &pStats->m_iQueryMsec;
-	}
+	CSphSEThreadData *pTls = (CSphSEThreadData *) *thd_ha_data ( thd, sphinx_hton_ptr );
+	CSphSEStats * pStats = ( pTls && pTls->m_bStats ) ? &pTls->m_tStats : 0;
+    SHOW_VAR *array = (SHOW_VAR*)thd_alloc(thd, sizeof(SHOW_VAR)*7);
+    out->type = SHOW_ARRAY;
+    out->value = (char*)array;
+    if (pStats)
+    {
+        array[0].name = "total";
+        array[0].type = SHOW_INT;
+        array[0].value = (char *) &pStats->m_iMatchesTotal;
+        array[1].name = "total_found";
+        array[1].type = SHOW_INT;
+        array[1].value = (char *) &pStats->m_iMatchesFound;
+        array[2].name = "time";
+        array[2].type = SHOW_INT;
+        array[2].value = (char *) &pStats->m_iQueryMsec;
+        array[3].name = "word_count";
+        array[3].type = SHOW_INT;
+        array[3].value = (char *) &pStats->m_iWords;
+        array[4].name = "error";
+        array[4].type = SHOW_CHAR;
+        array[4].value = (char *) &pStats->m_sLastMessage;
+        array[5].name = "words";
+        array[5].type = SHOW_CHAR;
+        array[5].value = sBuffer;
+        sBuffer[0] = 0;
+
+        if ( pStats->m_iWords )
+        {
+            uint uBuffLen = 0;
+        
+            // the following is partially based on code in sphinx_show_status()
+            for ( int i=0; i<pStats->m_iWords; i++ )
+            {
+                CSphSEWordStats & tWord = pStats->m_dWords[i];
+                uBuffLen = my_snprintf ( sBuffer, SHOW_VAR_FUNC_BUFF_SIZE, "%s%s:%d:%d ", sBuffer,
+                    tWord.m_sWord, tWord.m_iDocs, tWord.m_iHits );
+            }
+
+            if ( uBuffLen > 0 )
+            {
+                // trim last space
+                sBuffer [ --uBuffLen ] = 0;
+            
+                if ( pTls->m_pQueryCharset )
+                {
+                    // String::c_ptr() will nul-terminate the buffer.
+                    //
+                    // NOTE: It's not entirely clear whether this conversion is necessary at all.
+                    
+                    String sConvert;
+                    uint iErrors;
+                    sConvert.copy ( sBuffer, uBuffLen, pTls->m_pQueryCharset, system_charset_info, &iErrors );
+                    memcpy ( sBuffer, sConvert.c_ptr(), sConvert.length() + 1 );
+                }
+            }
+        }
+        
+        array[6].name = 0; // terminate the array
+    }
+    else
+      array[0].name = 0;
 	return 0;
 }
 
-int sphinx_showfunc_word_count ( THD * thd, SHOW_VAR * out, char * )
-{
-	CSphSEStats * pStats = sphinx_get_stats ( thd, out );
-	if ( pStats )
-	{
-		out->type = SHOW_INT;
-		out->value = (char *) &pStats->m_iWords;
-	}
-	return 0;
-}
-
-int sphinx_showfunc_words ( THD * thd, SHOW_VAR * out, char * sBuffer )
-{
-#if MYSQL_VERSION_ID>50100	
-	if ( sphinx_hton_ptr )
-	{
-		CSphSEThreadData * pTls = (CSphSEThreadData *) *thd_ha_data ( thd, sphinx_hton_ptr );
-#else
-	{
-		CSphSEThreadData * pTls = (CSphSEThreadData *) thd->ha_data[sphinx_hton.slot];
-#endif		
-		if ( pTls && pTls->m_bStats )
-		{
-			CSphSEStats * pStats = &pTls->m_tStats;
-			if ( pStats && pStats->m_iWords )
-			{
-				uint uBuffLen = 0;
-			
-				out->type = SHOW_CHAR;
-				out->value = sBuffer;
-				
-				// the following is partially based on code in sphinx_show_status()
-				sBuffer[0] = 0;
-				for ( int i=0; i<pStats->m_iWords; i++ )
-				{
-					CSphSEWordStats & tWord = pStats->m_dWords[i];
-					uBuffLen = my_snprintf ( sBuffer, SHOW_VAR_FUNC_BUFF_SIZE, "%s%s:%d:%d ", sBuffer,
-						tWord.m_sWord, tWord.m_iDocs, tWord.m_iHits );
-				}
-
-				if ( uBuffLen > 0 )
-				{
-					// trim last space
-					sBuffer [ --uBuffLen ] = 0;
-				
-					if ( pTls->m_pQueryCharset )
-					{
-						// String::c_ptr() will nul-terminate the buffer.
-						//
-						// NOTE: It's not entirely clear whether this conversion is necessary at all.
-						
-						String sConvert;
-						uint iErrors;
-						sConvert.copy ( sBuffer, uBuffLen, pTls->m_pQueryCharset, system_charset_info, &iErrors );
-						memcpy ( sBuffer, sConvert.c_ptr(), sConvert.length() + 1 );
-					}
-				}
-
-				return 0;
-			}
-		}
-	}
-
-	out->type = SHOW_CHAR;
-	out->value = "";
-	return 0;
-}
-
-int sphinx_showfunc_error ( THD * thd, SHOW_VAR * out, char * )
-{
-	CSphSEStats * pStats = sphinx_get_stats ( thd, out );
-	if ( pStats && pStats->m_bLastError )
-	{
-		out->type = SHOW_CHAR;
-		out->value = pStats->m_sLastMessage;
-	}
-	return 0;
-}
-	
 #if MYSQL_VERSION_ID>50100
 struct st_mysql_storage_engine sphinx_storage_engine =
 {
@@ -3138,12 +3066,7 @@
 
 struct st_mysql_show_var sphinx_status_vars[] =
 {
-	{"sphinx_total",		(char *)sphinx_showfunc_total,			SHOW_FUNC},
-	{"sphinx_total_found",	(char *)sphinx_showfunc_total_found,	SHOW_FUNC},
-	{"sphinx_time",			(char *)sphinx_showfunc_time,			SHOW_FUNC},
-	{"sphinx_word_count",	(char *)sphinx_showfunc_word_count,		SHOW_FUNC},
-	{"sphinx_words",		(char *)sphinx_showfunc_words,			SHOW_FUNC},
-	{"sphinx_error",		(char *)sphinx_showfunc_error,			SHOW_FUNC},
+	{"sphinx",     (char *)sphinx_showfunc,      			SHOW_FUNC},
 	{0, 0, (enum_mysql_show_type)0}
 };
 
@@ -3165,6 +3088,26 @@
 }
 mysql_declare_plugin_end;
 
+#ifdef maria_declare_plugin
+maria_declare_plugin(sphinx)
+{
+	MYSQL_STORAGE_ENGINE_PLUGIN,
+	&sphinx_storage_engine,
+	sphinx_hton_name,
+	"Sphinx developers",
+	sphinx_hton_comment,
+	PLUGIN_LICENSE_GPL,
+	sphinx_init_func, // Plugin Init
+	sphinx_done_func, // Plugin Deinit
+	0x0001, // 0.1
+	sphinx_status_vars,
+	NULL,
+	"0.1", // string version
+	MariaDB_PLUGIN_MATURITY_EXPERIMENTAL
+}
+maria_declare_plugin_end;
+#endif
+
 #endif // >50100
 
 //
diff -u --recursive tmp/storage/sphinxse/ha_sphinx.h mariadb-5.2/storage/sphinx/ha_sphinx.h
--- tmp/storage/sphinxse/ha_sphinx.h	2010-07-09 21:06:32.000000000 +0200
+++ mariadb-5.2/storage/sphinx/ha_sphinx.h	2010-07-09 13:47:47.000000000 +0200
@@ -153,12 +153,6 @@
 bool sphinx_show_status ( THD * thd );
 #endif
 
-int sphinx_showfunc_total_found ( THD *, SHOW_VAR *, char * );
-int sphinx_showfunc_total ( THD *, SHOW_VAR *, char * );
-int sphinx_showfunc_time ( THD *, SHOW_VAR *, char * );
-int sphinx_showfunc_word_count ( THD *, SHOW_VAR *, char * );
-int sphinx_showfunc_words ( THD *, SHOW_VAR *, char * );
-
 //
 // $Id: ha_sphinx.h 1428 2008-09-05 18:06:30Z xale $
 //
diff -u --recursive tmp/storage/sphinxse/Makefile.am mariadb-5.2/storage/sphinx/Makefile.am
--- tmp/storage/sphinxse/Makefile.am	2010-07-09 21:06:32.000000000 +0200
+++ mariadb-5.2/storage/sphinx/Makefile.am	2010-07-09 13:49:37.000000000 +0200
@@ -25,27 +25,23 @@
 			-I$(top_srcdir)/regex \
 			-I$(top_srcdir)/sql \
                         -I$(srcdir)
-SUBDIRS =				../../include ../../mysys ../../strings ../../dbug ../../extra
-WRAPLIBS=
 
-LDADD =
-
-DEFS= @DEFS@ \
-      -D_REENTRANT -D_PTHREADS -DENGINE -DSTORAGE_ENGINE -DMYSQL_SERVER
+DEFS= @DEFS@ -D_REENTRANT -D_PTHREADS -DMYSQL_SERVER
 
 noinst_HEADERS =	ha_sphinx.h
 
 EXTRA_LTLIBRARIES =	ha_sphinx.la
 pkgplugin_LTLIBRARIES = @plugin_sphinx_shared_target@ sphinx.la
 
-ha_sphinx_la_LDFLAGS =	-module -rpath $(MYSQLLIBdir)
+ha_sphinx_la_LDFLAGS =	-module -rpath $(MYSQLLIBdir) \
+			-L$(top_builddir)/libservices -lmysqlservices
 ha_sphinx_la_CXXFLAGS=	$(AM_CFLAGS) -DMYSQL_DYNAMIC_PLUGIN
 ha_sphinx_la_CFLAGS =	$(AM_CFLAGS) -DMYSQL_DYNAMIC_PLUGIN
 ha_sphinx_la_SOURCES =	ha_sphinx.cc
 
 sphinx_la_LDFLAGS = -module
-sphinx_la_CXXFLAGS = $(AM_CFLAGS) -DMYSQL_DYNAMIC_PLUGIN
-sphinx_la_CFLAGS = $(AM_CFLAGS) -DMYSQL_DYNAMIC_PLUGIN
+sphinx_la_CXXFLAGS = $(AM_CFLAGS)
+sphinx_la_CFLAGS = $(AM_CFLAGS)
 sphinx_la_SOURCES = snippets_udf.cc
 
 EXTRA_LIBRARIES =	libsphinx.a
@@ -54,6 +50,6 @@
 libsphinx_a_CFLAGS =	$(AM_CFLAGS)
 libsphinx_a_SOURCES=	ha_sphinx.cc
 
-EXTRA_DIST =		cmakelists.txt
+EXTRA_DIST =		CMakeLists.txt
 # Don't update the files from bitkeeper
 %::SCCS/s.%
diff -u --recursive tmp/storage/sphinxse/plug.in mariadb-5.2/storage/sphinx/plug.in
--- tmp/storage/sphinxse/plug.in	2010-07-09 21:06:32.000000000 +0200
+++ mariadb-5.2/storage/sphinx/plug.in	2010-07-09 13:47:12.000000000 +0200
@@ -1,5 +1,6 @@
-MYSQL_STORAGE_ENGINE(sphinx,,  [Sphinx Storage Engine],
-        [Sphinx Storage Engines], [max,max-no-ndb])
+MYSQL_STORAGE_ENGINE(sphinx,,[Sphinx Storage Engine],
+        [SE client for Sphinx search daemon], [])
 MYSQL_PLUGIN_DIRECTORY(sphinx, [storage/sphinx])
-MYSQL_PLUGIN_STATIC(sphinx,    [libsphinx.a])
-MYSQL_PLUGIN_DYNAMIC(sphinx,   [ha_sphinx.la])
+MYSQL_PLUGIN_STATIC(sphinx,  [libsphinx.a])
+MYSQL_PLUGIN_DYNAMIC(sphinx, [ha_sphinx.la])
+