操作符运算兼容
在将参数开关dolphin.b_compatibility_mode设置为on时,表示启用四则运算的MySQL兼容。相比于原始的openGauss,dolphin对于四则运算的修改主要为:
-
支持更多类型参与四则运算,具体如下:
-
数字类型:tinyint(unsigned)、smallint(unsigned)、integer(unsigned)、bigint(unsigned)、float4、float8、decimal/numeric以及bit。
- 字符串类型:char、varchar、binary、varbinary、tinyblob、blob、mediumblob、longblob、enum、set、json以及text(目前openGauss没有实际上的tinytext、mediumtext和longtext,因此不考虑)。
- 时间日期类型:date、datetime、timestamp、time、year。
-
一些原操作符返回值兼容MySQL,具体的兼容规则如下:
-
整型 X 整型:针对”+”、”-“、”*“这三个操作符,如果两个都是有符号的整型,则返回结果也是有符号的整型,否则返回无符号整型;针对”/“,其返回值为定点型(numeric类型)。
- 整型 X 定点型:针对”+”、”-“、”*“、”/“四则运算,返回定点型。注:openGauss定点数未实现无符号,所以无符号整型参与运算返回的结果均为有符号的。
- 整型 X 浮点型:针对”+”、”-“、”*“、”/“四则运算,返回浮点型。注:openGauss浮点数未实现无符号,所以无符号整型参与运算返回的结果均为有符号的。
- 定点型 X 定点型:针对”+”、”-“、”*“、”/“四则运算,返回定点型。
- 定点型 X 浮点型:针对”+”、”-“、”*“、”/“四则运算,返回浮点型。
- 浮点型 X 浮点型:针对”+”、”-“、”*“、”/“四则运算,返回浮点型。
基于上述规则,只需要运用字符串类型、时间类型等的类型转换规则,就可以推算出这些类型进行混合运算时的返回值,类型转换规则如下:
- 字符串类型:在进行四则运算是统一转换为浮点类型
- 时间日期类型:date固定转换为有符号整型,year固定转换为无符号整型;针对datetime、timestamp、time三个类型,如果没有指定typmod(表示毫秒和微秒)的话,就转换为有符号整型,否则会转换为一个定点数,其小数位数与指定的typmod相同。
示例:
测试用例:
1. create database test_db dbcompatibility 'B';
2. \c test_db
3. set dolphin.b_compatibility_mode to on;
4. -- 整型 X 整型
5. select 1::int4 + 1::int4;
6. select 1::int4 - 1::int4;
7. select 1::int4 * 1::int4;
8. select 1::int4 / 1::int4;
10. -- 整型 X 整型(带无符号)
11. select 1::int4 + 1::uint4;
12. select 1::int4 - 1::uint4;
13. select 1::int4 * 1::uint4;
14. select 1::int4 / 1::uint4;
16. -- 整型 X 定点型
17. select 1::int4 + 1::numeric;
18. select 1::int4 - 1::numeric;
19. select 1::int4 * 1::numeric;
20. select 1::int4 / 1::numeric;
22. -- 整型 X 浮点型
23. select 1::int4 + 1::float8;
24. select 1::int4 - 1::float8;
25. select 1::int4 * 1::float8;
26. select 1::int4 / 1::float8;
28. -- 定点型 X 浮点型
29. select 1::numeric + 1::float8;
30. select 1::numeric - 1::float8;
31. select 1::numeric * 1::float8;
32. select 1::numeric / 1::float8;
34. -- 整型 X 字符串
35. select 1::int4 + '1.23'::text;
36. select 1::int4 - '1.23'::text;
37. select 1::int4 * '1.23'::text;
38. select 1::int4 / '1.23'::text;
40. -- 整型 X 日期
41. select 1::int4 + '2022-01-01'::date;
42. select 1::int4 - '2022-01-01'::date;
43. select 1::int4 * '2022-01-01'::date;
44. select 1::int4 / '2022-01-01'::date;
46. -- 整型 X 时间(不带微秒)
47. select 1::int4 + '12:12:12'::time;
48. select 1::int4 - '12:12:12'::time;
49. select 1::int4 * '12:12:12'::time;
50. select 1::int4 / '12:12:12'::time;
52. -- 整型 X 时间(带微秒)
53. select 1::int4 + '12:12:12.36'::time(3);
54. select 1::int4 - '12:12:12.36'::time(3);
55. select 1::int4 * '12:12:12.36'::time(3);
56. select 1::int4 / '12:12:12.36'::time(3);
结果:
1. openGauss=# create database test_db dbcompatibility 'B';
2. CREATE DATABASE
3. openGauss=# \c test_db
4. test_db=# set dolphin.b_compatibility_mode to on;
5. SET
6. test_db=# -- 整型 X 整型
7. test_db=# select 1::int4 + 1::int4;
8. ?column?
9. ----------
10. 2
11. (1 row)
13. test_db=# select 1::int4 - 1::int4;
14. ?column?
15. ----------
16. 0
17. (1 row)
19. test_db=# select 1::int4 * 1::int4;
20. ?column?
21. ----------
22. 1
23. (1 row)
25. test_db=# select 1::int4 / 1::int4;
26. ?column?
27. ------------------------
28. 1.00000000000000000000
29. (1 row)
31. test_db=# -- 整型 X 整型(带无符号)
32. test_db=# select 1::int4 + 1::uint4;
33. ?column?
34. ----------
35. 2
36. (1 row)
38. test_db=# select 1::int4 - 1::uint4;
39. ?column?
40. ----------
41. 0
42. (1 row)
44. test_db=# select 1::int4 * 1::uint4;
45. ?column?
46. ----------
47. 1
48. (1 row)
50. test_db=# select 1::int4 / 1::uint4;
51. ?column?
52. ------------------------
53. 1.00000000000000000000
54. (1 row)
56. test_db=# -- 整型 X 定点型
57. test_db=# select 1::int4 + 1::numeric;
58. ?column?
59. ----------
60. 2
61. (1 row)
63. test_db=# select 1::int4 - 1::numeric;
64. ?column?
65. ----------
66. 0
67. (1 row)
69. test_db=# select 1::int4 * 1::numeric;
70. ?column?
71. ----------
72. 1
73. (1 row)
75. test_db=# select 1::int4 / 1::numeric;
76. ?column?
77. ------------------------
78. 1.00000000000000000000
79. (1 row)
81. test_db=# -- 整型 X 浮点型
82. test_db=# select 1::int4 + 1::float8;
83. ?column?
84. ----------
85. 2
86. (1 row)
88. test_db=# select 1::int4 - 1::float8;
89. ?column?
90. ----------
91. 0
92. (1 row)
94. test_db=# select 1::int4 * 1::float8;
95. ?column?
96. ----------
97. 1
98. (1 row)
100. test_db=# select 1::int4 / 1::float8;
101. ?column?
102. ----------
103. 1
104. (1 row)
106. test_db=# -- 定点型 X 浮点型
107. test_db=# select 1::numeric + 1::float8;
108. ?column?
109. ----------
110. 2
111. (1 row)
113. test_db=# select 1::numeric - 1::float8;
114. ?column?
115. ----------
116. 0
117. (1 row)
119. test_db=# select 1::numeric * 1::float8;
120. ?column?
121. ----------
122. 1
123. (1 row)
125. test_db=# select 1::numeric / 1::float8;
126. ?column?
127. ----------
128. 1
129. (1 row)
131. test_db=# -- 整型 X 字符串
132. test_db=# select 1::int4 + '1.23'::text;
133. ?column?
134. ----------
135. 2.23
136. (1 row)
138. test_db=# select 1::int4 - '1.23'::text;
139. ?column?
140. ----------
141. -0.23
142. (1 row)
144. test_db=# select 1::int4 * '1.23'::text;
145. ?column?
146. ----------
147. 1.23
148. (1 row)
150. test_db=# select 1::int4 / '1.23'::text;
151. ?column?
152. -------------------
153. 0.813008130081301
154. (1 row)
156. test_db=# -- 整型 X 日期
157. test_db=# select 1::int4 + '2022-01-01'::date;
158. ?column?
159. ----------
160. 20220102
161. (1 row)
163. test_db=# select 1::int4 - '2022-01-01'::date;
164. ?column?
165. -----------
166. -20220100
167. (1 row)
169. test_db=# select 1::int4 * '2022-01-01'::date;
170. ?column?
171. ----------
172. 20220101
173. (1 row)
175. test_db=# select 1::int4 / '2022-01-01'::date;
176. ?column?
177. ----------------------------
178. 0.000000049455737139987580
179. (1 row)
181. test_db=# -- 整型 X 时间(不带微秒)
182. test_db=# select 1::int4 + '12:12:12'::time;
183. ?column?
184. ----------
185. 121213
186. (1 row)
188. test_db=# select 1::int4 - '12:12:12'::time;
189. ?column?
190. ----------
191. -121211
192. (1 row)
194. test_db=# select 1::int4 * '12:12:12'::time;
195. ?column?
196. ----------
197. 121212
198. (1 row)
200. test_db=# select 1::int4 / '12:12:12'::time;
201. ?column?
202. ----------------------------
203. 0.000008250008250008250008
204. (1 row)
206. test_db=# -- 整型 X 时间(带微秒)
207. test_db=# select 1::int4 + '12:12:12.36'::time(3);
208. ?column?
209. ---------------
210. 121213.360000
211. (1 row)
213. test_db=# select 1::int4 - '12:12:12.36'::time(3);
214. ?column?
215. ----------------
216. -121211.360000
217. (1 row)
219. test_db=# select 1::int4 * '12:12:12.36'::time(3);
220. ?column?
221. ---------------
222. 121212.360000
223. (1 row)
225. test_db=# select 1::int4 / '12:12:12.36'::time(3);
226. ?column?
227. ----------------------------
228. 0.000008249983747532017362
229. (1 row)
