Forgot to attach patches.
--
Tatsuo Ishii
SRA OSS, Inc. Japan
English: http://www.sraoss.co.jp/index_en.php
Japanese: http://www.sraoss.co.jp

>> 2011/6/14 Tatsuo Ishii <[email protected]>
>> 
>>> Please explain what is implemented and what is not implemented in this
>>> patch.
>>>
>> 
>> What is implemented in this patch are as below.
>> - connect to memcached.
>> - set RowDescription or DataRow on memcached.
>> - get RowDescription or DataRow on memcached by using key of md5(SELECT
>> convert).
>> - delete cache on memcached by using key of md5(SELECT convert). only
>> module.
>> - fetch and parse the fellowing data in pgpool.conf.
>> 
>> memory_cache_enabled
>> memqcache_method
>> memqcache_memcached_host
>> memqcache_memcached_port
>> memqcache_total_size
>> memqcache_expire
>> memqcache_maxcache
>> memqcache_cache_block_size
>> 
>> - add data to buffer before set data on memcached.
>> - get buffer in order to set it on memcached
>> - initialize buffer
>> 
>> I am implemented only in Simple Query case.
>> 
>> 
>> What is not implemented in this patch are as below.
>> - shmem cache.
>> structure of  managing table oids.
>> the space management map.
>> on memory query cache structure.
>> 
>> - implementation in Extended Query case.
>> 
>> - cache validation.
>> The result of SELECT using none IMMUTABLE functions is not cached.
> 
> I have made a patch to implement a function which checks if a SELECT
> statement includes non IMMUTABLE function call.
> 
> extern bool pool_has_non_immutable_function_call(Node *node);
> 
> See attached patches.
> 
> TODO:
> 
> Some statements including:
> 
> SELECT current_timestamp;
> 
> is not detected by the function even if it uses IMMUTABLE function
> because it is translated to a non function form. Obviously we should
> not cache the result of current_timestamp. What should we do? Probably
> we have to have a heuristics to detect the particular form?
> 
>> - remove cache
>> If cache is full, the least recently used cache is removed.
>> If a table is dropped or modified, related cache data is deleted.
>> If a table definition is modified(ALTER TABLE), related cache data is
>> deleted.
>> If a schema or database is dropped, related cache data is deleted.
>> 
>> 
>> This week I am mainly implementing the shmem cache.
>> 
>> Regards
>> Masanori YAMAZAKI
>> 
>> 
>> 
>> 
>>> --
>>> Tatsuo Ishii
>>> SRA OSS, Inc. Japan
>>> English: http://www.sraoss.co.jp/index_en.php
>>> Japanese: http://www.sraoss.co.jp
>>>
>>> > Hello, hackers
>>> >
>>> > I have implemented a function caching query on memcached.
>>> > I am sending the patch file and it's so nice to give me some opinions.
>>> >
>>> > Main program which I implemented is as below.
>>> > - Search for cache data on memcached by using md5 which converted SELECT
>>> > into.
>>> > - Set data on memcached. The key is md5 which converted  SELECT into.
>>> > The value is RowDescription, DataRow from Backend.
>>> >
>>> > [Modify files]
>>> > - pool.h
>>> > - child.c
>>> > - pool_config.l
>>> > - pool_config.h
>>> > - pool_config.c
>>> > - pool_system.c
>>> > - pool_proto_modules.c
>>> > - pool_process_query.c
>>> >
>>> > [New File]
>>> > - pool_memqcache.c
>>> >
>>> >
>>> > --
>>> > Regards
>>> > Masanori YAMAZAKI
>>>
Index: pool_select_walker.h
===================================================================
RCS file: /cvsroot/pgpool/pgpool-II/pool_select_walker.h,v
retrieving revision 1.4
diff -c -r1.4 pool_select_walker.h
*** pool_select_walker.h	6 Sep 2010 05:03:21 -0000	1.4
--- pool_select_walker.h	19 Jun 2011 10:14:59 -0000
***************
*** 30,35 ****
--- 30,36 ----
  #include "parser/nodes.h"
  
  extern bool pool_has_function_call(Node *node);
+ extern bool pool_has_non_immutable_function_call(Node *node);
  extern bool pool_has_system_catalog(Node *node);
  extern bool pool_has_temp_table(Node *node);
  extern bool pool_has_pgpool_regclass(void);
Index: pool_select_walker.c
===================================================================
RCS file: /cvsroot/pgpool/pgpool-II/pool_select_walker.c,v
retrieving revision 1.10
diff -c -r1.10 pool_select_walker.c
*** pool_select_walker.c	19 Jun 2011 08:56:38 -0000	1.10
--- pool_select_walker.c	19 Jun 2011 10:14:59 -0000
***************
*** 33,38 ****
--- 33,39 ----
  	bool	has_system_catalog;		/* True if system catalog table is used */
  	bool	has_temp_table;		/* True if temporary table is used */
  	bool	has_function_call;	/* True if write function call is used */	
+ 	bool	has_non_immutable_function_call;	/* True if non stable functions are used */
  } SelectContext;
  
  static bool function_call_walker(Node *node, void *context);
***************
*** 40,45 ****
--- 41,48 ----
  static bool is_system_catalog(char *table_name);
  static bool temp_table_walker(Node *node, void *context);
  static bool is_temp_table(char *table_name);
+ static bool non_immutable_function_call_walker(Node *node, void *context);
+ static bool is_immutable_function(char *fname);
  
  /*
   * Return true if this SELECT has function calls *and* supposed to
***************
*** 453,455 ****
--- 456,550 ----
  	result = pool_search_relcache(relcache, backend, "pgpool_regclass")==0?0:1;
  	return result;
  }
+ 
+ /*
+  * Return true if this SELECT has non immutable function calls.
+  */
+ bool pool_has_non_immutable_function_call(Node *node)
+ {
+ 	SelectContext	ctx;
+ 
+ 	if (!IsA(node, SelectStmt))
+ 		return false;
+ 
+ 	ctx.has_non_immutable_function_call = false;
+ 
+ 	raw_expression_tree_walker(node, non_immutable_function_call_walker, &ctx);
+ 
+ 	pool_debug("pool_has_non_immutable_function_call: %d", ctx.has_non_immutable_function_call);
+ 	return ctx.has_non_immutable_function_call;
+ }
+ 
+ /*
+  * Walker function to find non immutable function call.
+  */
+ static bool non_immutable_function_call_walker(Node *node, void *context)
+ {
+ 	SelectContext	*ctx = (SelectContext *) context;
+ 
+ 	if (node == NULL)
+ 		return false;
+ 
+ 	if (IsA(node, FuncCall))
+ 	{
+ 		FuncCall *fcall = (FuncCall *)node;
+ 		char *fname;
+ 		int length = list_length(fcall->funcname);
+ 
+ 		if (length > 0)
+ 		{
+ 			if (length == 1)	/* no schema qualification? */
+ 			{
+ 				fname = strVal(linitial(fcall->funcname));
+ 			}
+ 			else
+ 			{
+ 				fname = strVal(lsecond(fcall->funcname));		/* with schema qualification */
+ 			}
+ 
+ 			pool_debug("non_immutable_function_call_walker: function name: %s", fname);
+ 
+ 			/* Check system catalog if the function is immutable */
+ 			if (is_immutable_function(fname) == false)
+ 			{
+ 				/* Non immutable function call found */
+ 				ctx->has_non_immutable_function_call = true;
+ 				return false;
+ 			}
+ 		}
+ 	}
+ 	return raw_expression_tree_walker(node, non_immutable_function_call_walker, context);
+ }
+ 
+ /*
+  * Check if the function is stable.
+  */
+ static bool is_immutable_function(char *fname)
+ {
+ /*
+  * Query to know if the function is IMMUTABLE
+  */
+ #define IS_STABLE_FUNCTION_QUERY "SELECT count(*) FROM pg_catalog.pg_proc AS p WHERE p.proname = '%s' AND p.provolatile = 'i'"
+ 	bool result;
+ 	static POOL_RELCACHE *relcache;
+ 	POOL_CONNECTION_POOL *backend;
+ 
+ 	backend = pool_get_session_context()->backend;
+ 
+ 	if (!relcache)
+ 	{
+ 		relcache = pool_create_relcache(32, IS_STABLE_FUNCTION_QUERY,
+ 										int_register_func, int_unregister_func,
+ 										false);
+ 		if (relcache == NULL)
+ 		{
+ 			pool_error("is_immutable_function: pool_create_relcache error");
+ 			return false;
+ 		}
+ 		pool_debug("is_immutable_function: relcache created");
+ 	}
+ 
+ 	result = pool_search_relcache(relcache, backend, fname)==0?0:1;
+ 	pool_debug("is_immutable_function: search result:%d", result);
+ 	return result;
+ }
_______________________________________________
Pgpool-hackers mailing list
[email protected]
http://pgfoundry.org/mailman/listinfo/pgpool-hackers

Reply via email to