search_path用途
1.确定默认当前schema。postgres的当前schema是search_path中第一个有效的schema。在创建对象时,不指名schema,对象将创建到当前少schema。sql中查找对象(函数,存储过程例外,规则更复杂),也是找的当前schema。如下示例中,用户是lightdb,所以第一个schema是lightdb,但是lightdb schema并不存在,所以第一个有效的schema是public,表创建在public中。
lightdb@test=# show search_path;
search_path
-----------------------------
"$user", public, lt_catalog
(1 row)
lightdb@test=# create table test(a int);
CREATE TABLE
lightdb@test=# \d test;
Table "public.test"
Column | Type | Collation | Nullable | Default
--------+---------+-----------+----------+---------
a | integer | | |
2.函数的搜索路径。函数调用会优先找出函数名相同的在这里插入代码片函数(参数类型相同将根据优先级保留一个)。
Oracle和MySQL schema是特殊的schema,用于存放一些MySQL和Oracle兼容函数。只有oracle模式时,search_path才允许包含oracle,同理,MySQL模式才允许包含mysql.下面的示例中,sql兼容模式是mysql,search_path包含oracle时,设置失败。
lightdb@test=# set lightdb_syntax_compatible_type to mysql;
SET
lightdb@test=# set search_path to "$user", public, mysql;
SET
lightdb@test=# set search_path to "$user", public, oracle;
ERROR: invalid value for parameter "search_path": ""$user", public, oracle"
DETAIL: oracle can be included only when the value of lightdb_syntax_compatible_type is Oracle.
同时只允许设置会话级别,如下设置将失败:
lightdb@test=# alter database test set search_path to "$user", public, mysql;
ERROR: invalid value for parameter "search_path": ""$user", public, mysql"
DETAIL: Only the current session can contains "mysql".
oracle兼容模式
LightDB提供兼容模式(通过配置lightdb_syntax_compatible_type配置),用于解决MySQL,Oracle,Postgrest语义不一致的问题。
例如:当处于oracle 模式时,1/2的结果是0.5。
lightdb@test=# set lightdb_syntax_compatible_type to oracle;
SET
lightdb@test=# select 1/2;
?column?
------------------------
0.50000000000000000000
(1 row)
lightdb@test=# set lightdb_syntax_compatible_type to off;
SET
lightdb@test=# select 1/2;
?column?
----------
0
(1 row)
mysql/oracle函数兼容
部分函数,在MySQL/Oracle/Postgres中的语义,为了更好的兼容MySQL和Oracle.LightDB提供了一套机制,处理语义不一致的问题。下面以函数test为例:
创建三个test函数:
create function pg_catalog.test() returns varchar as $$ select 'pg_catalog' $$ language sql;
create function oracle.test() returns varchar as $$ select 'oracle' $$ language sql;
create function mysql.test() returns varchar as $$ select 'mysql' $$ language sql;
效果如下:
lightdb@test=# set lightdb_syntax_compatible_type to oracle;
SET
lightdb@test=# select test();
test
------------
pg_catalog
(1 row)
lightdb@test=# set search_path to "$user", public, oracle;
SET
lightdb@test=# select test();
test
--------
oracle
(1 row)
当只设置oracle模式时,调用的是pg_catalog.test,当search_path包含oracle时,调用的oracle.test的函数,原因如下:
当设置oracle模式,且search_path包含oracle时,LightDB会自动补上schema,也就是说,select test()语法解析到select oracle.test。