diff --git a/contrib/dolphin/expected/fulltext_index.out b/contrib/dolphin/expected/fulltext_index.out new file mode 100644 index 0000000000000000000000000000000000000000..ed15d33630654d26f971687a70c7b2318a0eb2c0 --- /dev/null +++ b/contrib/dolphin/expected/fulltext_index.out @@ -0,0 +1,151 @@ +CREATE SCHEMA fulltext_test; +set current_schema to 'fulltext_test'; +CREATE TABLE test ( +id int unsigned auto_increment not null primary key, +title varchar, +boby text, +name name, +FULLTEXT (title, boby) WITH PARSER ngram +); +NOTICE: CREATE TABLE will create implicit sequence "test_id_seq" for serial column "test.id" +NOTICE: CREATE TABLE / PRIMARY KEY will create implicit index "test_pkey" for table "test" +\d test + Table "fulltext_test.test" + Column | Type | Modifiers +--------+-------------------+------------------------- + id | uint4 | not null AUTO_INCREMENT + title | character varying | + boby | text | + name | name | +Indexes: + "test_pkey" PRIMARY KEY, btree (id) TABLESPACE pg_default + "test_to_tsvector_to_tsvector1_idx" gin (to_tsvector('ngram'::regconfig, title::text), to_tsvector('ngram'::regconfig, boby)) TABLESPACE pg_default + +\d test_to_tsvector_to_tsvector1_idx + Index "fulltext_test.test_to_tsvector_to_tsvector1_idx" + Column | Type | Definition +--------------+------+---------------------------------------------- + to_tsvector | text | to_tsvector('ngram'::regconfig, title::text) + to_tsvector1 | text | to_tsvector('ngram'::regconfig, boby) +gin, for table "fulltext_test.test" + +DROP INDEX test_to_tsvector_to_tsvector1_idx; +ALTER TABLE test ADD FULLTEXT INDEX test_index_1 (title, boby) WITH PARSER ngram; +DROP INDEX test_index_1; +CREATE FULLTEXT INDEX test_index_1 ON test (title, boby) WITH PARSER ngram; +\d test_index_1 + Index "fulltext_test.test_index_1" + Column | Type | Definition +--------------+------+---------------------------------------------- + to_tsvector | text | to_tsvector('ngram'::regconfig, title::text) + to_tsvector1 | text | to_tsvector('ngram'::regconfig, boby) +gin, for table "fulltext_test.test" + +INSERT INTO test(title, boby, name) VALUES('test', '&67575@gauss', 'opengauss'); +INSERT INTO test(title, boby, name) VALUES('test1', 'gauss', 'opengauss'); +INSERT INTO test(title, boby, name) VALUES('test2', 'gauss2', 'opengauss'); +INSERT INTO test(title, boby, name) VALUES('test3', 'test', 'opengauss'); +INSERT INTO test(title, boby, name) VALUES('gauss_123_@', 'test', 'opengauss'); +INSERT INTO test(title, boby, name) VALUES('', '', 'opengauss'); +INSERT INTO test(title, boby, name) VALUES(' ', ' ', ' '); +SELECT * FROM TEST; + id | title | boby | name +----+-------------+--------------+----------- + 1 | test | &67575@gauss | opengauss + 2 | test1 | gauss | opengauss + 3 | test2 | gauss2 | opengauss + 4 | test3 | test | opengauss + 5 | gauss_123_@ | test | opengauss + 6 | | | opengauss + 7 | | | +(7 rows) + +SELECT * FROM TEST WHERE MATCH (title, boby) AGAINST ('test'); + id | title | boby | name +----+-------------+--------------+----------- + 1 | test | &67575@gauss | opengauss + 2 | test1 | gauss | opengauss + 3 | test2 | gauss2 | opengauss + 4 | test3 | test | opengauss + 5 | gauss_123_@ | test | opengauss +(5 rows) + +SELECT * FROM TEST WHERE MATCH (title, boby) AGAINST ('gauss'); + id | title | boby | name +----+-------------+--------------+----------- + 1 | test | &67575@gauss | opengauss + 2 | test1 | gauss | opengauss + 3 | test2 | gauss2 | opengauss + 5 | gauss_123_@ | test | opengauss +(4 rows) + +DROP INDEX test_index_1; +CREATE FULLTEXT INDEX test_index_1 ON test (boby) WITH PARSER ngram; +\d test_index_1 + Index "fulltext_test.test_index_1" + Column | Type | Definition +-------------+------+--------------------------------------- + to_tsvector | text | to_tsvector('ngram'::regconfig, boby) +gin, for table "fulltext_test.test" + +SELECT * FROM test WHERE MATCH (boby) AGAINST ('test'); + id | title | boby | name +----+-------------+------+----------- + 4 | test3 | test | opengauss + 5 | gauss_123_@ | test | opengauss +(2 rows) + +SELECT * FROM test WHERE MATCH (boby) AGAINST ('gauss'); + id | title | boby | name +----+-------+--------------+----------- + 1 | test | &67575@gauss | opengauss + 2 | test1 | gauss | opengauss + 3 | test2 | gauss2 | opengauss +(3 rows) + +DROP INDEX test_index_1; +CREATE FULLTEXT INDEX test_index_1 ON test (title, boby, name) WITH PARSER ngram; +\d test_index_1 + Index "fulltext_test.test_index_1" + Column | Type | Definition +--------------+------+---------------------------------------------- + to_tsvector | text | to_tsvector('ngram'::regconfig, title::text) + to_tsvector1 | text | to_tsvector('ngram'::regconfig, boby) + to_tsvector2 | text | to_tsvector('ngram'::regconfig, name::text) +gin, for table "fulltext_test.test" + +SELECT * FROM test WHERE MATCH (title, boby, name) AGAINST ('test'); + id | title | boby | name +----+-------------+--------------+----------- + 1 | test | &67575@gauss | opengauss + 2 | test1 | gauss | opengauss + 3 | test2 | gauss2 | opengauss + 4 | test3 | test | opengauss + 5 | gauss_123_@ | test | opengauss +(5 rows) + +SELECT * FROM test WHERE MATCH (title, boby, name) AGAINST ('gauss'); + id | title | boby | name +----+-------------+--------------+----------- + 1 | test | &67575@gauss | opengauss + 2 | test1 | gauss | opengauss + 3 | test2 | gauss2 | opengauss + 4 | test3 | test | opengauss + 5 | gauss_123_@ | test | opengauss + 6 | | | opengauss +(6 rows) + +SELECT * FROM test WHERE MATCH (title, boby, name) AGAINST ('opengauss'); + id | title | boby | name +----+-------------+--------------+----------- + 1 | test | &67575@gauss | opengauss + 2 | test1 | gauss | opengauss + 3 | test2 | gauss2 | opengauss + 4 | test3 | test | opengauss + 5 | gauss_123_@ | test | opengauss + 6 | | | opengauss +(6 rows) + +drop schema fulltext_test cascade; +NOTICE: drop cascades to table test +reset current_schema; diff --git a/contrib/dolphin/include/plugin_parser/kwlist.h b/contrib/dolphin/include/plugin_parser/kwlist.h index 9d31f1084c158318e751954f5e0955e3f5c60eb7..b519a8c3c4b63d2e8f19fdd44b2c0ebb396e6715 100644 --- a/contrib/dolphin/include/plugin_parser/kwlist.h +++ b/contrib/dolphin/include/plugin_parser/kwlist.h @@ -35,6 +35,9 @@ PG_KEYWORD("action", ACTION, UNRESERVED_KEYWORD) PG_KEYWORD("add", ADD_P, UNRESERVED_KEYWORD) PG_KEYWORD("admin", ADMIN, UNRESERVED_KEYWORD) PG_KEYWORD("after", AFTER, UNRESERVED_KEYWORD) +#ifdef DOLPHIN +PG_KEYWORD("against", AGAINST, TYPE_FUNC_NAME_KEYWORD) +#endif PG_KEYWORD("aggregate", AGGREGATE, UNRESERVED_KEYWORD) PG_KEYWORD("algorithm", ALGORITHM, UNRESERVED_KEYWORD) PG_KEYWORD("all", ALL, RESERVED_KEYWORD) @@ -343,6 +346,9 @@ PG_KEYWORD("forward", FORWARD, UNRESERVED_KEYWORD) PG_KEYWORD("freeze", FREEZE, TYPE_FUNC_NAME_KEYWORD) PG_KEYWORD("from", FROM, RESERVED_KEYWORD) PG_KEYWORD("full", FULL, TYPE_FUNC_NAME_KEYWORD) +#ifdef DOLPHIN +PG_KEYWORD("fulltext", FULLTEXT, TYPE_FUNC_NAME_KEYWORD) +#endif PG_KEYWORD("function", FUNCTION, UNRESERVED_KEYWORD) PG_KEYWORD("functions", FUNCTIONS, UNRESERVED_KEYWORD) PG_KEYWORD("generated", GENERATED, UNRESERVED_KEYWORD) @@ -533,6 +539,9 @@ PG_KEYWORD("national", NATIONAL, COL_NAME_KEYWORD) PG_KEYWORD("natural", NATURAL, TYPE_FUNC_NAME_KEYWORD) PG_KEYWORD("nchar", NCHAR, COL_NAME_KEYWORD) PG_KEYWORD("next", NEXT, UNRESERVED_KEYWORD) +#ifdef DOLPHIN +PG_KEYWORD("ngram", NGRAM, UNRESERVED_KEYWORD) +#endif PG_KEYWORD("no", NO, UNRESERVED_KEYWORD) #ifdef DOLPHIN PG_KEYWORD("no_write_to_binlog", NO_WRITE_TO_BINLOG, UNRESERVED_KEYWORD) diff --git a/contrib/dolphin/parallel_schedule_dolphin b/contrib/dolphin/parallel_schedule_dolphin index ee3ddc31884d2b6acddabf3a9cb0f0601dc30db0..6386aed8bf5d70c9fc2a8e4971c5a3fa6bb1e5ce 100644 --- a/contrib/dolphin/parallel_schedule_dolphin +++ b/contrib/dolphin/parallel_schedule_dolphin @@ -130,7 +130,7 @@ test: builtin_funcs/cast any_value_test default_function get_b_database union2 test: json_type json_pretty json_valid json_length json_objectagg json_arrayagg json_operator json_storage_size -test: test_uuid_short test_sleep distinct dual_test +test: test_uuid_short test_sleep distinct dual_test fulltext_index test: operator_compatibility_test/numeric_operator_test_normal operator_compatibility_test/numeric_operator_test_min operator_compatibility_test/numeric_operator_test_max operator_compatibility_test/time_operator_test operator_compatibility_test/string_operator_test operator_compatibility_test/multi_type_operator_test diff --git a/contrib/dolphin/plugin_parser/gram.y b/contrib/dolphin/plugin_parser/gram.y index 20b97fd004c7bf1c03df72bb2cfedf6c2c3514f0..d436fb84f47db58e9982f48434f313fe50800253 100644 --- a/contrib/dolphin/plugin_parser/gram.y +++ b/contrib/dolphin/plugin_parser/gram.y @@ -589,7 +589,7 @@ static char* appendString(char* source, char* target, int offset); %type CreateOptionList CreateIfNotExistsOptionList CreateAsOptionList %type TableIndexOption PartitionTableIndexOption %type TableIndexOptionList PartitionTableIndexOptionList -%type index_method_relation_clause +%type index_method_relation_clause fulltext_index_method_relation_clause %type stmt schema_stmt AlterEventTrigStmt AlterDatabaseStmt AlterDatabaseSetStmt AlterDataSourceStmt AlterDomainStmt AlterEnumStmt AlterEventStmt @@ -776,7 +776,7 @@ static char* appendString(char* source, char* target, int offset); oper_argtypes RuleActionList RuleActionMulti opt_column_list columnList opt_name_list opt_analyze_column_define opt_multi_name_list opt_include_without_empty opt_c_include index_including_params - sort_clause opt_sort_clause sortby_list index_params table_index_elems constraint_params + sort_clause opt_sort_clause sortby_list index_params fulltext_index_params table_index_elems constraint_params name_list UserIdList from_clause from_list opt_array_bounds dolphin_name_list qualified_name_list any_name type_name_list collate_name any_name_or_sconst any_name_list dolphin_qualified_name_list dolphin_any_name dolphin_any_name_list any_operator expr_list attrs callfunc_args callfunc_args_or_empty dolphin_attrs rename_user_clause rename_list @@ -886,7 +886,7 @@ static char* appendString(char* source, char* target, int offset); %type def_arg columnElem where_clause where_or_current_clause start_with_expr connect_by_expr a_expr b_expr c_expr c_expr_noparen AexprConst indirection_el siblings_clause columnref in_expr start_with_clause having_clause func_table array_expr set_ident_expr set_expr set_expr_extension - ExclusionWhereClause + ExclusionWhereClause fulltext_match_params %type ExclusionConstraintList ExclusionConstraintElem %type func_arg_list %type func_arg_expr @@ -899,7 +899,7 @@ static char* appendString(char* source, char* target, int offset); %type NumericOnly_list %type alias_clause opt_alias_clause dolphin_alias_clause opt_dolphin_alias_clause %type sortby -%type index_elem table_index_elem constraint_elem +%type index_elem table_index_elem constraint_elem fulltext_index_elem %type table_ref %type joined_table %type relation_expr @@ -1138,7 +1138,7 @@ static char* appendString(char* source, char* target, int offset); /* PGXC - added DISTRIBUTE, DIRECT, COORDINATOR, CLEAN, NODE, BARRIER, SLICE, DATANODE */ %token ABORT_P ABSOLUTE_P ACCESS ACCOUNT ACTION ADD_P ADMIN AFTER AGGREGATE ALGORITHM ALL ALSO ALTER ALWAYS ANALYSE ANALYZE AND ANY APP APPEND ARCHIVE ARRAY AS ASC - ASSERTION ASSIGNMENT ASYMMETRIC AT ATTRIBUTE AUDIT AUTHID AUTHORIZATION AUTOEXTEND AUTOEXTEND_SIZE AUTOMAPPED AUTO_INCREMENT AVG_ROW_LENGTH + ASSERTION ASSIGNMENT ASYMMETRIC AT ATTRIBUTE AUDIT AUTHID AUTHORIZATION AUTOEXTEND AUTOEXTEND_SIZE AUTOMAPPED AUTO_INCREMENT AVG_ROW_LENGTH AGAINST BACKWARD BARRIER BEFORE BEGIN_NON_ANOYBLOCK BEGIN_P BETWEEN BIGINT BINARY BINARY_P BINARY_DOUBLE BINARY_INTEGER BIT BLANKS BLOB_P BLOCKCHAIN BODY_P BOGUS BOOLEAN_P BOTH BUCKETCNT BUCKETS BY BYTEAWITHOUTORDER BYTEAWITHOUTORDERWITHEQUAL @@ -1166,7 +1166,7 @@ static char* appendString(char* source, char* target, int offset); FALSE_P FAMILY FAST FENCED FETCH FIELDS FILEHEADER_P FILL_MISSING_FIELDS FILLER FILTER FIRST_P FIXED_P FLOAT_P FLUSH FOLLOWING FOLLOWS_P FOR FORCE FOREIGN FORMATTER FORWARD FEATURES // DB4AI - FREEZE FROM FULL FUNCTION FUNCTIONS + FREEZE FROM FULL FULLTEXT FUNCTION FUNCTIONS GENERATED GET_FORMAT GLOBAL GRANT GRANTED GREATEST GROUP_P GROUPING_P GROUPPARENT GRANTS TRIGGERS @@ -1188,7 +1188,7 @@ static char* appendString(char* source, char* target, int offset); MAPPING MASKING MASTER MATCH MATERIALIZED MATCHED MAXEXTENTS MAX_ROWS MAXSIZE MAXTRANS MAXVALUE MEDIUMINT MEMORY MERGE MICROSECOND_P MID MIN_ROWS MINUS_P MINUTE_P MINUTE_MICROSECOND_P MINUTE_SECOND_P MINVALUE MINEXTENTS MOD MODE MODIFY_P MONTH_P MOVE MOVEMENT MODEL // DB4AI MODIFIES - NAME_P NAMES NATIONAL NATURAL NCHAR NEXT NO NOCOMPRESS NOCYCLE NODE NOLOGGING NOMAXVALUE NOMINVALUE NONE + NAME_P NAMES NATIONAL NATURAL NCHAR NEXT NGRAM NO NOCOMPRESS NOCYCLE NODE NOLOGGING NOMAXVALUE NOMINVALUE NONE NOT NOTHING NOTIFY NOTNULL NOWAIT NULL_P NULLCOLS NULLIF NULLS_P NUMBER_P NUMERIC NUMSTR NVARCHAR NVARCHAR2 NVL NO_WRITE_TO_BINLOG @@ -1265,7 +1265,7 @@ static char* appendString(char* source, char* target, int offset); END_OF_PROC EVENT_TRIGGER NOT_IN NOT_BETWEEN NOT_LIKE NOT_ILIKE NOT_SIMILAR - DEFAULT_FUNC + DEFAULT_FUNC MATCH_FUNC DO_SCONST DO_LANGUAGE SHOW_STATUS BEGIN_B_BLOCK FORCE_INDEX USE_INDEX LOCK_TABLES @@ -5278,6 +5278,36 @@ alter_table_cmd: n->def = $2; $$ = (Node *)n; } + /* ALTER TABLE ADD FULLTEXT INDEX ... */ + | ADD_P FULLTEXT INDEX index_name '(' fulltext_index_params ')' WITH PARSER NGRAM + { + IndexStmt *n = makeNode(IndexStmt); + n->unique = false; + n->concurrent = false; + n->idxname = $4; + n->relation = NULL; + n->accessMethod = "gin"; + n->indexParams = $6; + n->excludeOpNames = NIL; + n->idxcomment = NULL; + n->indexOid = InvalidOid; + n->oldNode = InvalidOid; + n->partClause = NULL; + n->isPartitioned = false; + n->isGlobal = false; + n->primary = false; + n->isconstraint = false; + n->deferrable = false; + n->initdeferred = false; + n->indexIncludingParams = NIL; + n->options = NIL; + n->tableSpace = NULL; + + AlterTableCmd *ati = makeNode(AlterTableCmd); + ati->subtype = AT_AddIndex; + ati->def = (Node *)n; + $$ = (Node *)ati; + } /* ALTER TABLE VALIDATE CONSTRAINT ... */ | VALIDATE CONSTRAINT name { @@ -9344,7 +9374,6 @@ TableIndexClause: n->isconstraint = false; n->deferrable = false; n->initdeferred = false; - /* n->internal_index_flag = true; */ $$ = (Node *)n; } | index_key_opt access_method_clause_without_keyword '(' table_index_elems ')' opt_table_index_options @@ -9372,9 +9401,33 @@ TableIndexClause: n->isconstraint = false; n->deferrable = false; n->initdeferred = false; - /* n->internal_index_flag = true; */ $$ = (Node *)n; } + | FULLTEXT '(' fulltext_index_params ')' WITH PARSER NGRAM + { + IndexStmt *n = makeNode(IndexStmt); + n->unique = false; + n->concurrent = false; + n->idxname = NULL; + n->relation = NULL; + n->accessMethod = "gin"; + n->indexParams = $3; + n->excludeOpNames = NIL; + n->idxcomment = NULL; + n->indexOid = InvalidOid; + n->oldNode = InvalidOid; + n->partClause = NULL; + n->isPartitioned = false; + n->isGlobal = false; + n->primary = false; + n->isconstraint = false; + n->deferrable = false; + n->initdeferred = false; + n->indexIncludingParams = NIL; + n->options = NIL; + n->tableSpace = NULL; + $$ = (Node *)n; + } ; @@ -17221,6 +17274,33 @@ IndexStmt: CREATE opt_unique INDEX opt_concurrently opt_index_name n->tableSpace = NULL; $$ = (Node *)n; } + | CREATE FULLTEXT INDEX opt_index_name + fulltext_index_method_relation_clause '(' fulltext_index_params ')' WITH PARSER NGRAM + { + IndexStmt *n = makeNode(IndexStmt); + n->unique = false; + n->concurrent = false; + n->schemaname = $4->schemaname; + n->idxname = $4->relname; + n->relation = $5->relation; + n->accessMethod = "gin"; + n->indexParams = $7; + n->excludeOpNames = NIL; + n->idxcomment = NULL; + n->indexOid = InvalidOid; + n->oldNode = InvalidOid; + n->partClause = NULL; + n->isPartitioned = false; + n->isGlobal = false; + n->primary = false; + n->isconstraint = false; + n->deferrable = false; + n->initdeferred = false; + n->indexIncludingParams = NIL; + n->options = NIL; + n->tableSpace = NULL; + $$ = (Node *)n; + } | CREATE opt_unique INDEX opt_concurrently opt_index_name index_method_relation_clause '(' index_params ')' idx_algo_expr @@ -18365,6 +18445,50 @@ index_params: index_elem { $$ = list_make1($1); } | index_params ',' index_elem { $$ = lappend($1, $3); } ; +fulltext_index_params: + fulltext_index_elem { $$ = list_make1($1); } + | fulltext_index_params ',' fulltext_index_elem { $$ = lappend($1, $3); } + ; + +fulltext_index_elem: + ColId + { + ColumnRef *fulltext_col = makeNode(ColumnRef); + fulltext_col->fields = list_make1(makeString($1)); + + FuncCall *n = makeNode(FuncCall); + n->funcname = SystemFuncName("to_tsvector"); + n->args = lappend(n->args, makeStringConst("ngram", -1)); + n->args = lappend(n->args, (Node*)fulltext_col); + n->agg_order = NIL; + n->agg_star = FALSE; + n->agg_distinct = FALSE; + n->func_variadic = FALSE; + n->over = NULL; + n->location = @1; + n->call_func = false; + + $$ = makeNode(IndexElem); + $$->name = NULL; + $$->expr = (Node *)n; + $$->indexcolname = NULL; + $$->collation = NIL; + $$->opclass = NIL; + $$->ordering = SORTBY_DEFAULT; + $$->nulls_ordering = SORTBY_NULLS_DEFAULT; + } + ; + +fulltext_index_method_relation_clause: + ON dolphin_qualified_name + { + IndexMethodRelationClause* result = (IndexMethodRelationClause*)palloc0(sizeof(IndexMethodRelationClause)); + result->relation = $2; + result->accessMethod = "gin"; + $$ = result; + } + ; + index_method_relation_clause: ON dolphin_qualified_name USING access_method { @@ -31030,8 +31154,8 @@ a_expr: c_expr { $$ = $1; } { $$ = (Node *) makeSimpleA_Expr(AEXPR_OP, ">", $1, $3, @2); } | a_expr '=' a_expr { $$ = (Node *) makeSimpleA_Expr(AEXPR_OP, "=", $1, $3, @2); } - | a_expr '@' a_expr - { $$ = (Node *) makeSimpleA_Expr(AEXPR_OP, "@", $1, $3, @2); } + | a_expr '@' a_expr + { $$ = (Node *) makeSimpleA_Expr(AEXPR_OP, "@", $1, $3, @2); } | a_expr CmpNullOp a_expr %prec IS { if (u_sess->attr.attr_sql.sql_compatibility == B_FORMAT) @@ -31721,6 +31845,19 @@ a_expr: c_expr { $$ = $1; } c->fields = lcons((Node *)makeString("excluded"), c->fields); $$ = (Node *) $3; } + | MATCH_FUNC fulltext_match_params ')' AGAINST '(' Sconst ')' + { + FuncCall *lexpr_func = makeNode(FuncCall); + lexpr_func->funcname = SystemFuncName("to_tsvector"); + lexpr_func->args = lappend(lexpr_func->args, makeStringConst("ngram", -1)); + lexpr_func->args = lappend(lexpr_func->args, $2); + FuncCall *rexpr_func = makeNode(FuncCall); + rexpr_func->funcname = SystemFuncName("to_tsquery"); + rexpr_func->args = lappend(rexpr_func->args, makeStringConst("ngram", -1)); + rexpr_func->args = lappend(rexpr_func->args, makeStringConst($6, @6)); + A_Expr *match_against = makeSimpleA_Expr(AEXPR_OP, "@@", (Node *)lexpr_func, (Node *)rexpr_func, -1); + $$ = (Node *)match_against; + } ; /* @@ -32131,7 +32268,18 @@ c_expr_noparen: columnref { $$ = $1; } } ; - +fulltext_match_params: + columnref + { + ColumnRef *fulltext_col = (ColumnRef *)$1; + $$ = (Node *)fulltext_col; + } + | fulltext_match_params ',' columnref + { + A_Expr *matchFollowCol = makeSimpleA_Expr(AEXPR_OP, "||", (Node *)$1, (Node *)$3, @2); + $$ = (Node *)matchFollowCol; + } + ; /* * func_expr and its cousin func_expr_windowless are split out from c_expr just @@ -35494,6 +35642,7 @@ unreserved_keyword_without_key: | NAME_P | NAMES | NEXT + | NGRAM | NO | NO_WRITE_TO_BINLOG | NOCOMPRESS @@ -35853,7 +36002,8 @@ col_name_keyword_nonambiguous: * - thomas 2000-11-28 */ type_func_name_keyword: - AUTHORIZATION + AGAINST + | AUTHORIZATION | COLLATION | COMPACT | CONCURRENTLY @@ -35864,6 +36014,7 @@ type_func_name_keyword: | DIV | FREEZE | FULL + | FULLTEXT | HDFSDIRECTORY | ILIKE | INDEX diff --git a/contrib/dolphin/plugin_parser/parser.cpp b/contrib/dolphin/plugin_parser/parser.cpp index 36e4f31284bb0948e1a179544321d03518cf414f..41cbe1297e023e3b7b97022674c83e8dd1a3f5af 100644 --- a/contrib/dolphin/plugin_parser/parser.cpp +++ b/contrib/dolphin/plugin_parser/parser.cpp @@ -199,6 +199,12 @@ static bool IsAlterStmtAlgorithm(char* scanbuf) return (pg_strcasecmp(ptr, "algorithm") == 0); } + +static inline bool IsSelectStmt(char* scanbuf) +{ + const int selectSize = 6; + return (scanbuf && pg_strncasecmp(scanbuf, "select", selectSize) == 0); +} #endif /* @@ -827,6 +833,26 @@ int base_yylex(YYSTYPE* lvalp, YYLTYPE* llocp, core_yyscan_t yyscanner) break; } break; + case MATCH: + /* + * DEFAULT must be reduced to one token, to allow START as table / column alias. + */ + GET_NEXT_TOKEN(); + switch (next_token) { + case '(': + if (IsSelectStmt(yyextra->core_yy_extra.scanbuf)) { + cur_token = MATCH_FUNC; + break; + } + default: + /* save the lookahead token for next time */ + SET_LOOKAHEAD_TOKEN(); + /* and back up the output info to cur_token */ + lvalp->core_yystype = cur_yylval; + *llocp = cur_yylloc; + break; + } + break; #endif default: break; diff --git a/contrib/dolphin/sql/fulltext_index.sql b/contrib/dolphin/sql/fulltext_index.sql new file mode 100644 index 0000000000000000000000000000000000000000..4b784fcc38f5db56adaea3cbccf28975df6e1e63 --- /dev/null +++ b/contrib/dolphin/sql/fulltext_index.sql @@ -0,0 +1,41 @@ +CREATE SCHEMA fulltext_test; +set current_schema to 'fulltext_test'; + +CREATE TABLE test ( +id int unsigned auto_increment not null primary key, +title varchar, +boby text, +name name, +FULLTEXT (title, boby) WITH PARSER ngram +); +\d test +\d test_to_tsvector_to_tsvector1_idx +DROP INDEX test_to_tsvector_to_tsvector1_idx; +ALTER TABLE test ADD FULLTEXT INDEX test_index_1 (title, boby) WITH PARSER ngram; +DROP INDEX test_index_1; +CREATE FULLTEXT INDEX test_index_1 ON test (title, boby) WITH PARSER ngram; +\d test_index_1 +INSERT INTO test(title, boby, name) VALUES('test', '&67575@gauss', 'opengauss'); +INSERT INTO test(title, boby, name) VALUES('test1', 'gauss', 'opengauss'); +INSERT INTO test(title, boby, name) VALUES('test2', 'gauss2', 'opengauss'); +INSERT INTO test(title, boby, name) VALUES('test3', 'test', 'opengauss'); +INSERT INTO test(title, boby, name) VALUES('gauss_123_@', 'test', 'opengauss'); +INSERT INTO test(title, boby, name) VALUES('', '', 'opengauss'); +INSERT INTO test(title, boby, name) VALUES(' ', ' ', ' '); +SELECT * FROM TEST; +SELECT * FROM TEST WHERE MATCH (title, boby) AGAINST ('test'); +SELECT * FROM TEST WHERE MATCH (title, boby) AGAINST ('gauss'); +DROP INDEX test_index_1; +CREATE FULLTEXT INDEX test_index_1 ON test (boby) WITH PARSER ngram; +\d test_index_1 +SELECT * FROM test WHERE MATCH (boby) AGAINST ('test'); +SELECT * FROM test WHERE MATCH (boby) AGAINST ('gauss'); +DROP INDEX test_index_1; +CREATE FULLTEXT INDEX test_index_1 ON test (title, boby, name) WITH PARSER ngram; +\d test_index_1 +SELECT * FROM test WHERE MATCH (title, boby, name) AGAINST ('test'); +SELECT * FROM test WHERE MATCH (title, boby, name) AGAINST ('gauss'); +SELECT * FROM test WHERE MATCH (title, boby, name) AGAINST ('opengauss'); + +drop schema fulltext_test cascade; +reset current_schema;