Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit ebb37ae

Browse files
authored
sql_mode can be set in session, therefore we should look for ANSI_QUOTES in session variable instead of global variable (ansible-collections#677)
* issue-671: get ASNI_QUOTES from session sql_mode instead of GLOBAL sql_mode
1 parent 90bd0b0 commit ebb37ae

File tree

4 files changed

+131
-1
lines changed

4 files changed

+131
-1
lines changed
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
bugfixes:
2+
- mysql_user,mysql_role - The sql_mode ANSI_QUOTES affects how the modules mysql_user
3+
and mysql_role compare the existing privileges with the configured privileges,
4+
as well as decide whether double quotes or backticks should be used in the GRANT
5+
statements. Pointing out in issue 671, the modules mysql_user and mysql_role allow
6+
users to enable/disable ANSI_QUOTES in session variable (within a DB session, the
7+
session variable always overwrites the global one). But due to the issue, the modules
8+
do not check for ANSI_MODE in the session variable, instead, they only check in the
9+
GLOBAL one.That behavior is not only limiting the users' flexibility, but also not
10+
allowing users to explicitly disable ANSI_MODE to work around such bugs like
11+
https://bugs.mysql.com/bug.php?id=115953.
12+
(https://github.com/ansible-collections/community.mysql/issues/671)

plugins/module_utils/user.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ class InvalidPrivsError(Exception):
3232

3333

3434
def get_mode(cursor):
35-
cursor.execute('SELECT @@GLOBAL.sql_mode')
35+
cursor.execute('SELECT @@sql_mode')
3636
result = cursor.fetchone()
3737
mode_str = result[0]
3838
if 'ANSI' in mode_str:
Lines changed: 112 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,112 @@
1+
---
2+
# Due to https://bugs.mysql.com/bug.php?id=115953, in Mysql 8, if ANSI_QUOTES is enabled,
3+
# backticks will be used instead of double quotes to quote functions or procedures name.
4+
# As a consequence, mysql_user and mysql_roles will always report "changed" for functions
5+
# and procedures no matter the privileges are granted or not.
6+
# Workaround for the mysql bug 116953 is removing ANSI_QUOTES from the module's session
7+
# sql_mode. But because issue 671, ANSI_QUOTES is always got from GLOBAL sql_mode, thus
8+
# this workaround can't work. Even without the Mysql bug, because sql_mode in session
9+
# precedes GLOBAL sql_mode. we should check for sql_mode in session variable instead of
10+
# the GLOBAL one.
11+
- vars:
12+
mysql_parameters: &mysql_params
13+
login_user: '{{ mysql_user }}'
14+
login_password: '{{ mysql_password }}'
15+
login_host: '{{ mysql_host }}'
16+
login_port: '{{ mysql_primary_port }}'
17+
18+
block:
19+
- name: Issue-671| test setup | drop database
20+
community.mysql.mysql_db:
21+
<<: *mysql_params
22+
name: "{{ item }}"
23+
state: absent
24+
loop:
25+
- foo
26+
- bar
27+
28+
- name: Issue-671| test setup | create database
29+
community.mysql.mysql_db:
30+
<<: *mysql_params
31+
name: "{{ item }}"
32+
state: present
33+
loop:
34+
- foo
35+
- bar
36+
37+
- name: Issue-671| test setup | get value of GLOBAL.sql_mode
38+
community.mysql.mysql_query:
39+
<<: *mysql_params
40+
query: 'select @@GLOBAL.sql_mode AS sql_mode'
41+
register: sql_mode_orig
42+
43+
- name: Issue-671| Assert sql_mode_orig
44+
ansible.builtin.assert:
45+
that:
46+
- sql_mode_orig.query_result[0][0].sql_mode != None
47+
48+
- name: Issue-671| enable sql_mode ANSI_QUOTES
49+
community.mysql.mysql_variables:
50+
<<: *mysql_params
51+
variable: sql_mode
52+
value: '{{ sql_mode_orig.query_result[0][0].sql_mode }},ANSI_QUOTES'
53+
mode: "{% if db_engine == 'mariadb' %}global{% else %}persist{% endif %}"
54+
55+
- name: Issue-671| Copy SQL scripts to remote
56+
ansible.builtin.copy:
57+
src: "{{ item }}"
58+
dest: "{{ remote_tmp_dir }}/{{ item | basename }}"
59+
loop:
60+
- create-function.sql
61+
- create-procedure.sql
62+
63+
- name: Issue-671| Create function for test
64+
ansible.builtin.shell:
65+
cmd: "{{ mysql_command }} < {{ remote_tmp_dir }}/create-function.sql"
66+
67+
- name: Issue-671| Create procedure for test
68+
ansible.builtin.shell:
69+
cmd: "{{ mysql_command }} < {{ remote_tmp_dir }}/create-procedure.sql"
70+
71+
- name: Issue-671| Create user with FUNCTION and PROCEDURE privileges
72+
community.mysql.mysql_user:
73+
<<: *mysql_params
74+
name: '{{ user_name_2 }}'
75+
password: '{{ user_password_2 }}'
76+
state: present
77+
priv: 'FUNCTION foo.function:EXECUTE/foo.*:SELECT/PROCEDURE bar.procedure:EXECUTE'
78+
79+
- name: Issue-671| Grant the privileges again, remove ANSI_QUOTES from the session variable
80+
community.mysql.mysql_user:
81+
<<: *mysql_params
82+
session_vars:
83+
sql_mode: ""
84+
name: '{{ user_name_2 }}'
85+
password: '{{ user_password_2 }}'
86+
state: present
87+
priv: 'FUNCTION foo.function:EXECUTE/foo.*:SELECT/PROCEDURE bar.procedure:EXECUTE'
88+
register: result
89+
failed_when:
90+
- result is failed or result is changed
91+
92+
- name: Issue-671| Test teardown | cleanup databases
93+
community.mysql.mysql_db:
94+
<<: *mysql_params
95+
name: "{{ item }}"
96+
state: absent
97+
loop:
98+
- foo
99+
- bar
100+
101+
- name: Issue-671| set sql_mode back to original value
102+
community.mysql.mysql_variables:
103+
<<: *mysql_params
104+
variable: sql_mode
105+
value: '{{ sql_mode_orig.query_result[0][0].sql_mode }}'
106+
mode: "{% if db_engine == 'mariadb' %}global{% else %}persist{% endif %}"
107+
108+
- name: Issue-671| Teardown user_name_2
109+
ansible.builtin.include_tasks:
110+
file: utils/remove_user.yml
111+
vars:
112+
user_name: "{{ user_name_2 }}"

tests/integration/targets/test_mysql_user/tasks/main.yml

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -282,6 +282,12 @@
282282
- import_tasks: issue-64560.yaml
283283
tags:
284284
- issue-64560
285+
286+
- name: Test ANSI_QUOTES
287+
ansible.builtin.import_tasks:
288+
file: issue-671.yaml
289+
tags:
290+
- issue-671
285291

286292
# Test that mysql_user still works with force_context enabled (database set to "mysql")
287293
# (https://github.com/ansible-collections/community.mysql/issues/265)

0 commit comments

Comments
 (0)