Skip to content

Commit

Permalink
overcoming MySQL stored routines bug with local variables
Browse files Browse the repository at this point in the history
  • Loading branch information
Shlomi Noach committed Apr 1, 2016
1 parent 7271c32 commit 53b6017
Show file tree
Hide file tree
Showing 108 changed files with 622 additions and 493 deletions.
90 changes: 46 additions & 44 deletions build.xml
Original file line number Diff line number Diff line change
Expand Up @@ -6,16 +6,16 @@
</taskdef>



<!--
<property name="mysql.user" value="root" />
<property name="mysql.password" value="" />
<property name="mysql.socket" value="/tmp/mysql.prime.sock" />
-->
-->
<property name="mysql.user" value="root" />
<property name="mysql.password" value="msandbox" />
<property name="mysql.socket" value="/tmp/mysql_sandbox5524.sock" />
<property name="mysql.socket" value="/var/folders/m2/jxhw5r550fbcj96cg_9j8xx40000gn/T//mysql_sandbox22293.sock" />

<!--
Expand All @@ -24,16 +24,16 @@
<property name="mysql.socket" value="/tmp/mysql_sandbox5524.sock" />
-->

<!--
<!--
<property name="mysql.user" value="root" />
<property name="mysql.password" value="msandbox" />
<property name="mysql.socket" value="/tmp/mysql_sandbox5612.sock" />
-->




<property name="mysql.database" value="common_schema" />

<property name="build_data.dir" value="build_data" />
Expand All @@ -49,28 +49,28 @@

<property name="doc.templates.dir" value="doc/templates" />
<property name="doc.html.dir" value="doc/html" />

<property name="doc.sql.tmp.file" value="doc_sql.txt" />


<target name="all" depends="build">
</target>


<target name="clean">
<delete dir="${build.dir}" />
<delete dir="${dist.dir}" />
<delete dir="${tmp.dir}" />
</target>


<target name="undeploy">
<antcall target="exec_mysql_command">
<param name="mysql_command" value="DROP DATABASE IF EXISTS ${mysql.database}" />
</antcall>
</target>


<target name="revnumber" description="Get the SVN greatest revision number">
<mkdir dir="${tmp.dir}" />
<exec dir="." executable="svn" output="ant-tmp/svn_output" failifexecutionfails="false" description="Get SVN info for all files recursively">
Expand All @@ -90,7 +90,7 @@
<echo>revision: ${svn.revision}</echo>
</target>


<target name="build_base_components" depends="revnumber">
<mkdir dir="${build.dir}" />
<concat destfile="${build.dir}/${sql.base_components.output.file}">
Expand Down Expand Up @@ -118,15 +118,15 @@
<fileset dir="routines/time/" includes="*.sql" />
<fileset dir="routines/version_control/" includes="*.sql" />
<!--
<fileset dir="routines/math/" includes="*.sql" />
-->
<fileset dir="routines/math/" includes="*.sql" />
-->
<!--
<fileset dir="autocache/tables/" includes="*.sql" />
<fileset dir="autocache/routines/" includes="*.sql" />
<fileset dir="autocache/views_internal/" includes="*.sql" />
<fileset dir="autocache/views/" includes="*.sql" />
-->

<fileset dir="views/schema_analysis/" includes="*.sql" />
<fileset dir="views/data_dimension/" includes="*.sql" />
<fileset dir="views/debug/" includes="*.sql" />
Expand All @@ -139,8 +139,8 @@
</concat>
<replace file="${build.dir}/${sql.base_components.output.file}" token="revision.placeholder" value="${svn.revision}"/>
</target>


<target name="build_additional_components">
<delete dir="${tmp.dir}" />
<mkdir dir="${tmp.dir}" />
Expand All @@ -164,32 +164,32 @@
</concat>
<delete dir="${tmp.dir}" />
</target>

<target name="build_innodb_plugin_component">
<basename property="innodb_plugin_component.file.basename" file="${innodb_plugin_component.filename}" />

<loadfile property="component.text" srcfile="${innodb_plugin_component.filename}"></loadfile>
<copy file="${build_data.dir}/innodb_plugin_component.sql" toFile="${tmp.dir}/${innodb_plugin_component.file.basename}" />
<replace file="${tmp.dir}/${innodb_plugin_component.file.basename}" token="component.placeholder" value="${component.text}"/>
</target>

<target name="build_percona_server_component">
<basename property="percona_server_component.file.basename" file="${percona_server_component.filename}" />

<loadfile property="component.text" srcfile="${percona_server_component.filename}"></loadfile>
<copy file="${build_data.dir}/percona_server_component.sql" toFile="${tmp.dir}/${percona_server_component.file.basename}" />
<replace file="${tmp.dir}/${percona_server_component.file.basename}" token="component.placeholder" value="${component.text}"/>
</target>

<target name="build_tokudb_component">
<basename property="tokudb_component.file.basename" file="${tokudb_component.filename}" />

<loadfile property="component.text" srcfile="${tokudb_component.filename}"></loadfile>
<copy file="${build_data.dir}/tokudb_component.sql" toFile="${tmp.dir}/${tokudb_component.file.basename}" />
<replace file="${tmp.dir}/${tokudb_component.file.basename}" token="component.placeholder" value="${component.text}"/>
</target>


<target name="build_scripts">
<delete file="${build.dir}/${sql.scripts.output.file}" />
<foreach param="script.filename" target="build_script">
Expand All @@ -198,7 +198,7 @@
</path>
</foreach>
</target>

<target name="build_script">
<basename property="script.file.basename" file="${script.filename}" suffix=".sql"/>
<loadfile property="script.text" srcfile="${script.filename}"></loadfile>
Expand All @@ -212,30 +212,30 @@
</concat>
</target>


<target name="build" depends="revnumber, build_base_components, build_additional_components, build_scripts">
<concat destfile="${build.dir}/${sql.build.output.file}">
<fileset file="${build_data.dir}/main_head.sql" />
<fileset file="${build.dir}/${sql.base_components.output.file}" />
<fileset file="${build.dir}/${sql.additional_components.output.file}" />
<fileset file="${build.dir}/${sql.scripts.output.file}" />
<fileset file="${build.dir}/${sql.help.output.file}" />
<fileset file="${build_data.dir}/main_tail.sql" />
<fileset file="${build_data.dir}/main_tail.sql" />
</concat>
</target>


<target name="deploy" depends="build">
<antcall target="deploy_file">
<param name="common_schema_sql_file" value="${build.dir}/${sql.build.output.file}" />
</antcall>
</target>


<target name="dist" depends="clean, build, doc_sql, revnumber, test">
<mkdir dir="${dist.dir}" />
<propertyregex property="release_filename" input="${sql.build.output.file}" regexp="(.*).sql" select="\1-r${svn.revision}.sql" />

<loadfile property="doc_sql" srcfile="${build.dir}/${sql.help.output.file}"></loadfile>
<copy file="${build.dir}/${sql.build.output.file}" tofile="${dist.dir}/${release_filename}" />
<replace file="${dist.dir}/${release_filename}" token="doc_sql.placeholder" value="${doc_sql}"/>
Expand All @@ -259,6 +259,7 @@
<arg value="--user=${mysql.user}" />
<arg value="--password=${mysql.password}" />
<arg value="--socket=${mysql.socket}" />
<arg value="--host=localhost" />
</exec>
</target>

Expand All @@ -273,11 +274,12 @@
<arg value="--user=${mysql.user}" />
<arg value="--password=${mysql.password}" />
<arg value="--socket=${mysql.socket}" />
<arg value="--host=localhost" />
<arg value="--execute=${mysql_command}" />
</exec>
</target>


<target name="doc" depends="revnumber">
<copy file="${doc.templates.dir}/style.css" todir="${doc.html.dir}/css">
</copy>
Expand Down Expand Up @@ -310,7 +312,7 @@
<arg value="${doc.html.dir}/"/>
</exec>
</target>

<target name="component_doc">
<basename property="doc_basename" file="${component_doc_filename}" />
<basename property="component_name" file="${component_doc_filename}" suffix=".html" />
Expand All @@ -320,9 +322,9 @@
</concat>
<replace file="${doc.html.dir}/${doc_basename}" token="pagetitle" value="${component_name}" />
<replace file="${doc.html.dir}/${doc_basename}" token="pagename" value="${component_name}" />
<replace file="${doc.html.dir}/${doc_basename}" token="revision.placeholder" value="${svn.revision}"/>
<replace file="${doc.html.dir}/${doc_basename}" token="revision.placeholder" value="${svn.revision}"/>
</target>

<target name="generaldoc">
<basename property="doc_basename" file="${generaldoc_filename}" />
<basename property="docname" file="${generaldoc_filename}" suffix=".html" />
Expand All @@ -332,10 +334,10 @@
</concat>
<replace file="${doc.html.dir}/${doc_basename}" token="pagetitle" value="${docname}" />
<replace file="${doc.html.dir}/${doc_basename}" token="pagename" value="${docname}" />
<replace file="${doc.html.dir}/${doc_basename}" token="revision.placeholder" value="${svn.revision}"/>
<replace file="${doc.html.dir}/${doc_basename}" token="revision.placeholder" value="${svn.revision}"/>
</target>


<target name="doc_sql">
<mkdir dir="${tmp.dir}" />
<mkdir dir="${build.dir}" />
Expand All @@ -352,7 +354,7 @@
</foreach>
<delete dir="${tmp.dir}" />
</target>

<target name="page_doc_sql">
<basename property="doc_basename" file="${page_doc_filename}" />
<basename property="page_doc_name" file="${page_doc_filename}" suffix=".html" />
Expand All @@ -375,7 +377,7 @@
</concat>
</target>


<target name="test">
<echo>Testing</echo>
<exec executable="bash" dir="${tests.dir}" failonerror="true">
Expand All @@ -385,8 +387,8 @@
<arg value="${mysql.socket}" />
</exec>
</target>


<target name="__test__">
<echo>${basedir}</echo>
<echo>${abc}</echo>
Expand All @@ -397,4 +399,4 @@
</propertyregex>
<echo>prop2: ---${f.c2}---</echo>
</target>
</project>
</project>
24 changes: 14 additions & 10 deletions routines/script/_consume_expression.sql
Original file line number Diff line number Diff line change
Expand Up @@ -23,32 +23,36 @@ sql security invoker
main_body: begin
declare first_state text;
declare expression_level int unsigned;
declare id_end_expression int unsigned;
declare id_end_expression int unsigned;
declare expanded_variables TEXT CHARSET utf8;
declare expanded_variables_found tinyint unsigned;

set expression_statement := NULL ;

call _skip_spaces(id_from, id_to);
SELECT level, state FROM _sql_tokens WHERE id = id_from INTO expression_level, first_state;
set @_expression_level=null, @_first_state=null;
SELECT level, state FROM _sql_tokens WHERE id = id_from INTO @_expression_level, @_first_state;
set expression_level=@_expression_level;
set first_state=@_first_state;

if (first_state = 'left parenthesis') then
SELECT MIN(id) FROM _sql_tokens WHERE id > id_from AND state = 'right parenthesis' AND level = expression_level INTO id_end_expression;
SELECT MIN(id) FROM _sql_tokens WHERE id > id_from AND state = 'right parenthesis' AND level = expression_level INTO @_id_end_expression;
set id_end_expression=@_id_end_expression;
if id_end_expression IS NULL then
call _throw_script_error(id_from, 'Unmatched "(" parenthesis');
end if;
set id_from := id_from + 1;
call _skip_spaces(id_from, id_to);

call _expand_statement_variables(id_from, id_end_expression-1, expression, expanded_variables_found, should_execute_statement);
-- SELECT GROUP_CONCAT(token ORDER BY id SEPARATOR '') FROM _sql_tokens WHERE id BETWEEN id_from AND id_end_expression-1 INTO expression;


-- Note down the statement (if any) of the expression:
SELECT token FROM _sql_tokens WHERE id = id_from AND state = 'alpha' INTO expression_statement;
set @_expression_statement=null;
SELECT token FROM _sql_tokens WHERE id = id_from AND state = 'alpha' INTO @_expression_statement;
set expression_statement=@_expression_statement;
if ((expression is NULL) or (trim_wspace(expression) = '')) and (should_execute_statement or not expanded_variables_found) then
call _throw_script_error(id_from, 'Found empty expression');
end if;
-- ~~~ select expression, expression_statement;
set consumed_to_id := id_end_expression;
else
if require_parenthesis then
Expand Down
28 changes: 16 additions & 12 deletions routines/script/_consume_foreach_expression.sql
Original file line number Diff line number Diff line change
Expand Up @@ -24,40 +24,44 @@ sql security invoker
main_body: begin
declare first_state text;
declare expression_level int unsigned;
declare id_end_expression int unsigned default NULL;
declare id_end_variables_definition int unsigned default NULL;
declare id_end_expression int unsigned default NULL;
declare id_end_variables_definition int unsigned default NULL;

call _skip_spaces(id_from, id_to);
SELECT level, state FROM _sql_tokens WHERE id = id_from INTO expression_level, first_state;
set @_expression_level=null, @_first_state=null;
SELECT level, state FROM _sql_tokens WHERE id = id_from INTO @_expression_level, @_first_state;
set expression_level=@_expression_level;
set first_state=@_first_state;

if (first_state != 'left parenthesis') then
call _throw_script_error(id_from, 'Expected "(" on foreach expression');
end if;

SELECT MIN(id) FROM _sql_tokens WHERE id > id_from AND state = 'right parenthesis' AND level = expression_level INTO id_end_expression;

SELECT MIN(id) FROM _sql_tokens WHERE id > id_from AND state = 'right parenthesis' AND level = expression_level INTO @_id_end_expression;
set id_end_expression=@_id_end_expression;
if id_end_expression IS NULL then
call _throw_script_error(id_from, 'Unmatched "(" parenthesis');
end if;

-- Detect the positions where variables are declared
SELECT MIN(id) FROM _sql_tokens WHERE id > id_from AND state = 'colon' AND level = expression_level INTO id_end_variables_definition;
SELECT MIN(id) FROM _sql_tokens WHERE id > id_from AND state = 'colon' AND level = expression_level INTO @_id_end_variables_definition;
set id_end_variables_definition=@_id_end_variables_definition;
if id_end_variables_definition IS NULL then
call _throw_script_error(id_from, 'foreach: expected ":" as in (variables : collection)');
end if;

set id_from := id_from + 1;

-- Expect variables declaration:
call _expect_dynamic_states_list(id_from, id_end_variables_definition-1, 'query_script variable', variables_array_id);
set variables_delaration_id := id_from;
call _declare_local_variables(id_from, id_to, id_end_variables_definition, depth, _implode_nospace_array(variables_array_id));

-- Get the collection clause:
set id_from := id_end_variables_definition + 1;
call _skip_spaces(id_from, id_to);

call _expand_statement_variables(id_from, id_end_expression-1, collection, @_common_schema_dummy, should_execute_statement);
-- SELECT GROUP_CONCAT(token ORDER BY id SEPARATOR '') FROM _sql_tokens WHERE id BETWEEN id_from AND id_end_expression-1 INTO collection;

set consumed_to_id := id_end_expression;
end;
Expand Down
Loading

0 comments on commit 53b6017

Please sign in to comment.