!4481 【神舟通用】支持标识符包含双引号的情况下也忽略大小写

Merge pull request !4481 from 雷紫薇/double_mark
This commit is contained in:
opengauss_bot
2023-12-09 08:05:44 +00:00
committed by Gitee
10 changed files with 576 additions and 5 deletions

View File

@ -131,6 +131,7 @@ config_file|string|0,0|NULL|NULL|
connection_alarm_rate|real|0,1|NULL|NULL|
constraint_exclusion|enum|partition,on,off,true,false,yes,no,1,0|NULL|NULL|
enable_union_all_subquery_orderby|bool|0,0|NULL|NULL|
enable_ignore_case_in_dquotes|bool|0,0|NULL|NULL|
instr_unique_sql_track_type|enum|all,top|NULL|NULL|
transform_to_numeric_operators|bool|0,0|NULL|NULL|
convert_string_to_digit|bool|0,0|NULL|Please don't modify this parameter which will change the type conversion rule and may lead to unpredictable behavior!|

View File

@ -28882,14 +28882,36 @@ SignedIconst: Iconst { $$ = $1; }
/* Column identifier --- names that can be column, table, etc names.
*/
ColId: IDENT { $$ = $1; }
ColId: IDENT
{
if (u_sess->attr.attr_sql.enable_ignore_case_in_dquotes
&& (pg_yyget_extra(yyscanner))->core_yy_extra.ident_quoted)
{
$$ = pg_strtolower(pstrdup($1));
}
else
{
$$ = $1;
}
}
| unreserved_keyword { $$ = pstrdup($1); }
| col_name_keyword { $$ = pstrdup($1); }
;
/* Type/function identifier --- names that can be type or function names.
*/
type_function_name: IDENT { $$ = $1; }
type_function_name: IDENT
{
if (u_sess->attr.attr_sql.enable_ignore_case_in_dquotes
&& (pg_yyget_extra(yyscanner))->core_yy_extra.ident_quoted)
{
$$ = pg_strtolower(pstrdup($1));
}
else
{
$$ = $1;
}
}
| unreserved_keyword { $$ = pstrdup($1); }
| type_func_name_keyword { $$ = pstrdup($1); }
;
@ -28897,7 +28919,18 @@ type_function_name: IDENT { $$ = $1; }
/* Column label --- allowed labels in "AS" clauses.
* This presently includes *all* Postgres keywords.
*/
ColLabel: IDENT { $$ = $1; }
ColLabel: IDENT
{
if (u_sess->attr.attr_sql.enable_ignore_case_in_dquotes
&& (pg_yyget_extra(yyscanner))->core_yy_extra.ident_quoted)
{
$$ = pg_strtolower(pstrdup($1));
}
else
{
$$ = $1;
}
}
| unreserved_keyword { $$ = pstrdup($1); }
| col_name_keyword { $$ = pstrdup($1); }
| type_func_name_keyword { $$ = pstrdup($1); }

View File

@ -182,6 +182,7 @@ static void assign_plsql_compile_behavior_compat_options(const char* newval, voi
static void assign_connection_info(const char* newval, void* extra);
static bool check_application_type(int* newval, void** extra, GucSource source);
static void assign_convert_string_to_digit(bool newval, void* extra);
static bool check_enable_ignore_case_in_dquotes(bool* newval, void** extra, GucSource source);
static bool CheckUStoreAttr(char** newval, void** extra, GucSource source);
static void AssignUStoreAttr(const char* newval, void* extra);
static bool check_snapshot_delimiter(char** newval, void** extra, GucSource source);
@ -1726,6 +1727,17 @@ static void InitSqlConfigureNamesBool()
NULL,
NULL,
NULL},
{{"enable_ignore_case_in_dquotes",
PGC_USERSET,
NODE_ALL,
QUERY_TUNING_METHOD,
gettext_noop("Enable ignore case in double quotes for some driver."),
NULL},
&u_sess->attr.attr_sql.enable_ignore_case_in_dquotes,
false,
check_enable_ignore_case_in_dquotes,
NULL,
NULL},
{{"enable_streaming",
PGC_POSTMASTER,
NODE_DISTRIBUTE,
@ -3762,6 +3774,16 @@ static void assign_convert_string_to_digit(bool newval, void* extra)
return;
}
static bool check_enable_ignore_case_in_dquotes(bool* newval, void** extra, GucSource source)
{
if (*newval && (currentGucContext == PGC_SUSET || currentGucContext == PGC_USERSET)) {
ereport(WARNING, (errmsg("if tables with the same name but different case already\n"
"exists in the database, this will result in only being able to\n"
"manipulate tables with table names that are entirely lowercase.")));
}
return true;
}
#define IS_NULL_STR(str) ((str) == NULL || (str)[0] == '\0')
const int MIN_USTATS_TRACKER_NAPTIME = 1;

View File

@ -820,6 +820,7 @@ job_queue_processes = 10 # Number of concurrent jobs, optional: [0..1000]
#plsql_show_all_error=off
#enable_seqscan_fusion = off
#enable_cachedplan_mgr=on
#enable_ignore_case_in_dquotes=off
#------------------------------------------------------------------------------
# SHARED STORAGE OPTIONS

View File

@ -246,6 +246,7 @@ typedef struct knl_session_attr_sql {
char* db4ai_snapshot_mode;
char* db4ai_snapshot_version_delimiter;
char* db4ai_snapshot_version_separator;
bool enable_ignore_case_in_dquotes;
int pldebugger_timeout;
bool partition_page_estimation;
bool enable_opfusion_reuse;

View File

@ -0,0 +1,354 @@
DROP SCHEMA sch_ignore_quote_01 CASCADE;
ERROR: schema "sch_ignore_quote_01" does not exist
CREATE SCHEMA sch_ignore_quote_01;
SET CURRENT_SCHEMA TO sch_ignore_quote_01;
-- test tables with the same name but different case already exists in the database
-- table
create table "TeSt" ("A" int);
select * from test;
ERROR: relation "test" does not exist on datanode1
LINE 1: select * from test;
^
select * from "TeSt";
A
---
(0 rows)
create table test ("A" int, "a" int);
insert into test("A","a") values(1,2);
select * from test;
A | a
---+---
1 | 2
(1 row)
-- view
CREATE VIEW test_view AS SELECT * FROM test;
CREATE VIEW "TeSt_view" AS SELECT * FROM "TeSt";
select * from test_view;
A | a
---+---
1 | 2
(1 row)
select * from "TeSt_view";
A
---
(0 rows)
-- materialized view
CREATE MATERIALIZED VIEW m_test_view AS SELECT * FROM test;
CREATE MATERIALIZED VIEW "M_teSt_view" AS SELECT * FROM "TeSt";
select * from m_test_view;
A | a
---+---
1 | 2
(1 row)
select * from "M_teSt_view";
A
---
(0 rows)
-- index
CREATE INDEX i1 ON test USING btree(a);
CREATE INDEX "I1" ON "TeSt" USING btree("A");
drop index "I1";
-- Chinese characters
create table "¥" ("¥" int, "$" int);
create table "啊啊" ("," int, "," int);
select * from "¥";
¥ | $
----+---
(0 rows)
select * from ¥;
¥ | $
----+---
(0 rows)
select * from "$"; -- errors
ERROR: relation "$" does not exist on datanode1
LINE 1: select * from "$";
^
select * from "啊啊";
, | ,
----+---
(0 rows)
insert into ¥("¥","$") values(1,2);
insert into ¥(¥,"$") values(4,3);
insert into "啊啊"(",",",") values(1,2);
-- function
create function f1(b int) returns int
as $$
begin
return b;
end;
$$language plpgsql;
create function "F1"(b int) returns int
as $$
begin
b=b+1;
return b;
end;
$$language plpgsql;
call f1(8);
f1
----
8
(1 row)
call "F1"(8);
F1
----
9
(1 row)
-- procedure
create procedure p1() is
begin
insert into test("A","a") values(5,9);
end;
/
create procedure "P1"() is
begin
insert into "TeSt"("A") values(10);
end;
/
call p1();
p1
----
(1 row)
select * from test;
A | a
---+---
1 | 2
5 | 9
(2 rows)
call "P1"();
P1
----
(1 row)
select * from "TeSt";
A
----
10
(1 row)
-- type
CREATE TYPE compfoo AS (f1 int, f2 text);
CREATE TYPE "CompFoo" AS (f3 text, f4 int, f5 int);
CREATE TABLE t1_compfoo(a int, b compfoo);
CREATE TABLE t2_compfoo(a int, b "CompFoo");
INSERT INTO t1_compfoo values(1,(1,'demo1'));
INSERT INTO t2_compfoo values(2,('demo2', 3, 5));
select * from t1_compfoo;
a | b
---+-----------
1 | (1,demo1)
(1 row)
select * from t2_compfoo;
a | b
---+-------------
2 | (demo2,3,5)
(1 row)
-- sequence
CREATE SEQUENCE s1 START 101 CACHE 20;
CREATE SEQUENCE "S1" START 801 CACHE 90;
drop sequence "S1";
-- test enable_ignore_case_in_dquotes=on
set enable_ignore_case_in_dquotes=on;
WARNING: if tables with the same name but different case already
exists in the database, this will result in only being able to
manipulate tables with table names that are entirely lowercase.
create table test1 ("A" int, 'a' int);-- error
ERROR: syntax error at or near "'a'"
LINE 1: create table test1 ("A" int, 'a' int);
^
insert into test("A","a") values(2,3);-- error
ERROR: column "a" specified more than once
LINE 1: insert into test("A","a") values(2,3);
^
select * from test;
A | a
---+---
1 | 2
5 | 9
(2 rows)
select * from test_view;
A | a
---+---
1 | 2
5 | 9
(2 rows)
select * from "TeSt_view";-- lowcase
A | a
---+---
1 | 2
5 | 9
(2 rows)
select * from m_test_view;
A | a
---+---
1 | 2
(1 row)
select * from "M_teSt_view";-- lowcase
A | a
---+---
1 | 2
(1 row)
call f1(8);
f1
----
8
(1 row)
call "F1"(8); -- lowcase
f1
----
8
(1 row)
call p1(8);
ERROR: function "p1" with 1 parameters doesn't exist
call "P1"(8); -- lowcase
ERROR: function "p1" with 1 parameters doesn't exist
CREATE TABLE t3_compfoo(a int, b "CompFoo");
CREATE INDEX "I1" ON "TeSt" USING btree("A");
ERROR: relation "i1" already exists
INSERT INTO t3_compfoo values(2,('demo2', 3, 5));-- error
ERROR: invalid input syntax for integer: "demo2"
LINE 1: INSERT INTO t3_compfoo values(2,('demo2', 3, 5));
^
CONTEXT: referenced column: b
INSERT INTO t3_compfoo values(1,(1,'demo1'));
select * from t3_compfoo;
a | b
---+-----------
1 | (1,demo1)
(1 row)
CREATE SEQUENCE "S1" START 801 CACHE 90;-- error
ERROR: relation "s1" already exists in schema "sch_ignore_quote_01"
DETAIL: creating new table with existing name in the same schema
call p1();
p1
----
(1 row)
select * from test;
A | a
---+---
1 | 2
5 | 9
5 | 9
(3 rows)
call "P1"();
p1
----
(1 row)
select * from "TeSt";
A | a
---+---
1 | 2
5 | 9
5 | 9
5 | 9
(4 rows)
create table "SCH_ignore_quote_01"."TAB_quote"("A" int);
insert into tab_quote (a) values (4);
insert into "SCH_IGNORE_QUOTE_01"."TAB_QUOTE" ("A") values (5);
select a from tab_quote;
a
---
4
5
(2 rows)
select t.a from sch_ignore_quote_01.tab_quote t;
a
---
4
5
(2 rows)
select t."A" from "SCH_IGNORE_QUOTE_01"."TAB_QUOTE" t;
a
---
4
5
(2 rows)
create table "¥¥" ("¥" int, "$" int);
create table "$" ("," int, "," int);
select * from "¥";
¥ | $
----+---
1 | 2
4 | 3
(2 rows)
select * from ¥;
¥ | $
----+---
1 | 2
4 | 3
(2 rows)
select * from "$";
, | ,
----+---
(0 rows)
select * from "啊啊";
, | ,
----+---
1 | 2
(1 row)
insert into ¥("¥","$") values(5,6);
insert into ¥(¥,"$") values(7,8);
insert into "啊啊"(",",",") values(10,11);
-- clean
drop table TAB_quote;
set enable_ignore_case_in_dquotes=off;
drop materialized view m_test_view;
drop materialized view "M_teSt_view";
drop index i1;
drop view test_view;
drop view "TeSt_view";
drop table test;
drop table "TeSt";
drop table "¥¥";
drop table "$";
drop table ¥;
drop table "啊啊";
drop function f1;
drop function "F1";
drop procedure p1;
drop procedure "P1";
drop table t1_compfoo;
drop table t2_compfoo;
drop table t3_compfoo;
drop type compfoo;
drop type "CompFoo";
drop sequence s1;
drop schema sch_ignore_quote_01;

View File

@ -284,6 +284,7 @@ select name,vartype,unit,min_val,max_val from pg_settings where name <> 'qunit_c
enable_hdfs_predicate_pushdown | bool | | |
enable_huge_pages | bool | | |
enable_hypo_index | bool | | |
enable_ignore_case_in_dquotes | bool | | |
enable_incremental_catchup | bool | | |
enable_incremental_checkpoint | bool | | |
enable_index_nestloop | bool | | |

View File

@ -143,7 +143,7 @@ test: single_node_numerology
# ----------
# The second group of parallel tests
# ----------
test: single_node_point single_node_lseg single_node_box single_node_path single_node_polygon single_node_circle single_node_date single_node_time single_node_timetz single_node_timestamp single_node_timestamptz
test: single_node_point single_node_lseg single_node_box single_node_path single_node_polygon single_node_circle single_node_date single_node_time single_node_timetz single_node_timestamp single_node_timestamptz ignore_double_quotes
#test: single_node_interval
test: single_node_abstime single_node_reltime
#test: single_node_tinterval

View File

@ -172,7 +172,7 @@ test: boolean name oid bit txid uuid numeric_hide_tailing_zero rawlike
# The second group of parallel tests
# ----------
#test: lseg box path polygon circle date time timetz timestamptz abstime reltime inet
test: interval tinterval macaddr tstypes comments
test: interval tinterval macaddr tstypes comments ignore_double_quotes
#test: point timestamp
# ----------

View File

@ -0,0 +1,158 @@
DROP SCHEMA sch_ignore_quote_01 CASCADE;
CREATE SCHEMA sch_ignore_quote_01;
SET CURRENT_SCHEMA TO sch_ignore_quote_01;
-- test tables with the same name but different case already exists in the database
-- table
create table "TeSt" ("A" int);
select * from test;
select * from "TeSt";
create table test ("A" int, "a" int);
insert into test("A","a") values(1,2);
select * from test;
-- view
CREATE VIEW test_view AS SELECT * FROM test;
CREATE VIEW "TeSt_view" AS SELECT * FROM "TeSt";
select * from test_view;
select * from "TeSt_view";
-- materialized view
CREATE MATERIALIZED VIEW m_test_view AS SELECT * FROM test;
CREATE MATERIALIZED VIEW "M_teSt_view" AS SELECT * FROM "TeSt";
select * from m_test_view;
select * from "M_teSt_view";
-- index
CREATE INDEX i1 ON test USING btree(a);
CREATE INDEX "I1" ON "TeSt" USING btree("A");
drop index "I1";
-- Chinese characters
create table "" ("" int, "$" int);
create table "啊啊" ("" int, "," int);
select * from "";
select * from ;
select * from "$"; -- errors
select * from "啊啊";
insert into ("","$") values(1,2);
insert into (,"$") values(4,3);
insert into "啊啊"("",",") values(1,2);
-- function
create function f1(b int) returns int
as $$
begin
return b;
end;
$$language plpgsql;
create function "F1"(b int) returns int
as $$
begin
b=b+1;
return b;
end;
$$language plpgsql;
call f1(8);
call "F1"(8);
-- procedure
create procedure p1() is
begin
insert into test("A","a") values(5,9);
end;
/
create procedure "P1"() is
begin
insert into "TeSt"("A") values(10);
end;
/
call p1();
select * from test;
call "P1"();
select * from "TeSt";
-- type
CREATE TYPE compfoo AS (f1 int, f2 text);
CREATE TYPE "CompFoo" AS (f3 text, f4 int, f5 int);
CREATE TABLE t1_compfoo(a int, b compfoo);
CREATE TABLE t2_compfoo(a int, b "CompFoo");
INSERT INTO t1_compfoo values(1,(1,'demo1'));
INSERT INTO t2_compfoo values(2,('demo2', 3, 5));
select * from t1_compfoo;
select * from t2_compfoo;
-- sequence
CREATE SEQUENCE s1 START 101 CACHE 20;
CREATE SEQUENCE "S1" START 801 CACHE 90;
drop sequence "S1";
-- test enable_ignore_case_in_dquotes=on
set enable_ignore_case_in_dquotes=on;
create table test1 ("A" int, 'a' int);-- error
insert into test("A","a") values(2,3);-- error
select * from test;
select * from test_view;
select * from "TeSt_view";-- lowcase
select * from m_test_view;
select * from "M_teSt_view";-- lowcase
call f1(8);
call "F1"(8); -- lowcase
call p1(8);
call "P1"(8); -- lowcase
CREATE TABLE t3_compfoo(a int, b "CompFoo");
CREATE INDEX "I1" ON "TeSt" USING btree("A");
INSERT INTO t3_compfoo values(2,('demo2', 3, 5));-- error
INSERT INTO t3_compfoo values(1,(1,'demo1'));
select * from t3_compfoo;
CREATE SEQUENCE "S1" START 801 CACHE 90;-- error
call p1();
select * from test;
call "P1"();
select * from "TeSt";
create table "SCH_ignore_quote_01"."TAB_quote"("A" int);
insert into tab_quote (a) values (4);
insert into "SCH_IGNORE_QUOTE_01"."TAB_QUOTE" ("A") values (5);
select a from tab_quote;
select t.a from sch_ignore_quote_01.tab_quote t;
select t."A" from "SCH_IGNORE_QUOTE_01"."TAB_QUOTE" t;
create table "¥¥" ("" int, "$" int);
create table "$" ("" int, "," int);
select * from "";
select * from ;
select * from "$";
select * from "啊啊";
insert into ("","$") values(5,6);
insert into (,"$") values(7,8);
insert into "啊啊"("",",") values(10,11);
-- clean
drop table TAB_quote;
set enable_ignore_case_in_dquotes=off;
drop materialized view m_test_view;
drop materialized view "M_teSt_view";
drop index i1;
drop view test_view;
drop view "TeSt_view";
drop table test;
drop table "TeSt";
drop table "¥¥";
drop table "$";
drop table ;
drop table "啊啊";
drop function f1;
drop function "F1";
drop procedure p1;
drop procedure "P1";
drop table t1_compfoo;
drop table t2_compfoo;
drop table t3_compfoo;
drop type compfoo;
drop type "CompFoo";
drop sequence s1;
drop schema sch_ignore_quote_01;