46 #include "utils/fmgroids.h"
82 retTypeId = INTERNALOID;
83 typeId[0] = INTERNALOID;
86 case Anum_pg_ts_parser_prsstart:
90 case Anum_pg_ts_parser_prstoken:
92 typeId[1] = INTERNALOID;
93 typeId[2] = INTERNALOID;
95 case Anum_pg_ts_parser_prsend:
99 case Anum_pg_ts_parser_prsheadline:
101 typeId[1] = INTERNALOID;
102 typeId[2] = TSQUERYOID;
104 case Anum_pg_ts_parser_prslextype:
115 elog(
ERROR,
"unrecognized attribute for text search parser: %d",
123 (
errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
124 errmsg(
"function %s should return type %s",
159 referenced.
objectId = prs->prstoken;
165 referenced.
objectId = prs->prslextype;
170 referenced.
objectId = prs->prsheadline;
191 bool nulls[Natts_pg_ts_parser];
199 (
errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
200 errmsg(
"must be superuser to create text search parsers")));
209 memset(nulls,
false,
sizeof(nulls));
212 Anum_pg_ts_parser_oid);
221 foreach(pl, parameters)
225 if (strcmp(defel->
defname,
"start") == 0)
227 values[Anum_pg_ts_parser_prsstart - 1] =
230 else if (strcmp(defel->
defname,
"gettoken") == 0)
232 values[Anum_pg_ts_parser_prstoken - 1] =
235 else if (strcmp(defel->
defname,
"end") == 0)
237 values[Anum_pg_ts_parser_prsend - 1] =
240 else if (strcmp(defel->
defname,
"headline") == 0)
242 values[Anum_pg_ts_parser_prsheadline - 1] =
245 else if (strcmp(defel->
defname,
"lextypes") == 0)
247 values[Anum_pg_ts_parser_prslextype - 1] =
252 (
errcode(ERRCODE_SYNTAX_ERROR),
253 errmsg(
"text search parser parameter \"%s\" not recognized",
262 (
errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
263 errmsg(
"text search parser start method is required")));
267 (
errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
268 errmsg(
"text search parser gettoken method is required")));
272 (
errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
273 errmsg(
"text search parser end method is required")));
277 (
errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
278 errmsg(
"text search parser lextypes method is required")));
360 elog(
ERROR,
"cache lookup failed for text search template %u",
364 initmethod = tform->tmplinit;
371 (
errcode(ERRCODE_SYNTAX_ERROR),
372 errmsg(
"text search template \"%s\" does not accept options",
403 bool nulls[Natts_pg_ts_dict];
425 foreach(pl, parameters)
429 if (strcmp(defel->
defname,
"template") == 0)
436 dictoptions =
lappend(dictoptions, defel);
445 (
errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
446 errmsg(
"text search template is required")));
457 memset(nulls,
false,
sizeof(nulls));
460 Anum_pg_ts_dict_oid);
468 values[Anum_pg_ts_dict_dictinitoption - 1] =
471 nulls[Anum_pg_ts_dict_dictinitoption - 1] =
true;
503 Datum repl_val[Natts_pg_ts_dict];
504 bool repl_null[Natts_pg_ts_dict];
505 bool repl_repl[Natts_pg_ts_dict];
515 elog(
ERROR,
"cache lookup failed for text search dictionary %u",
525 Anum_pg_ts_dict_dictinitoption,
535 foreach(pl,
stmt->options)
543 foreach(cell, dictoptions)
555 dictoptions =
lappend(dictoptions, defel);
567 memset(repl_val, 0,
sizeof(repl_val));
568 memset(repl_null,
false,
sizeof(repl_null));
569 memset(repl_repl,
false,
sizeof(repl_repl));
572 repl_val[Anum_pg_ts_dict_dictinitoption - 1] =
575 repl_null[Anum_pg_ts_dict_dictinitoption - 1] =
true;
576 repl_repl[Anum_pg_ts_dict_dictinitoption - 1] =
true;
579 repl_val, repl_null, repl_repl);
617 retTypeId = INTERNALOID;
618 typeId[0] = INTERNALOID;
619 typeId[1] = INTERNALOID;
620 typeId[2] = INTERNALOID;
621 typeId[3] = INTERNALOID;
624 case Anum_pg_ts_template_tmplinit:
627 case Anum_pg_ts_template_tmpllexize:
632 elog(
ERROR,
"unrecognized attribute for text search template: %d",
640 (
errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
641 errmsg(
"function %s should return type %s",
676 referenced.
objectId = tmpl->tmplinit;
696 bool nulls[Natts_pg_ts_template];
706 (
errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
707 errmsg(
"must be superuser to create text search templates")));
714 for (
i = 0;
i < Natts_pg_ts_template;
i++)
721 Anum_pg_ts_dict_oid);
730 foreach(pl, parameters)
734 if (strcmp(defel->
defname,
"init") == 0)
736 values[Anum_pg_ts_template_tmplinit - 1] =
738 nulls[Anum_pg_ts_template_tmplinit - 1] =
false;
740 else if (strcmp(defel->
defname,
"lexize") == 0)
742 values[Anum_pg_ts_template_tmpllexize - 1] =
744 nulls[Anum_pg_ts_template_tmpllexize - 1] =
false;
748 (
errcode(ERRCODE_SYNTAX_ERROR),
749 errmsg(
"text search template parameter \"%s\" not recognized",
758 (
errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
759 errmsg(
"text search template lexize method is required")));
799 elog(
ERROR,
"cache lookup failed for text search configuration %u",
820 myself.
classId = TSConfigRelationId;
839 referenced.
classId = NamespaceRelationId;
840 referenced.
objectId = cfg->cfgnamespace;
851 referenced.
classId = TSParserRelationId;
852 referenced.
objectId = cfg->cfgparser;
867 Anum_pg_ts_config_map_mapcfg,
878 referenced.
classId = TSDictionaryRelationId;
879 referenced.
objectId = cfgmap->mapdict;
905 bool nulls[Natts_pg_ts_config];
928 foreach(pl, parameters)
932 if (strcmp(defel->
defname,
"parser") == 0)
934 else if (strcmp(defel->
defname,
"copy") == 0)
938 (
errcode(ERRCODE_SYNTAX_ERROR),
939 errmsg(
"text search configuration parameter \"%s\" not recognized",
945 (
errcode(ERRCODE_SYNTAX_ERROR),
946 errmsg(
"cannot specify both PARSER and COPY options")));
965 elog(
ERROR,
"cache lookup failed for text search configuration %u",
971 prsOid = cfg->cfgparser;
981 (
errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
982 errmsg(
"text search parser is required")));
990 memset(nulls,
false,
sizeof(nulls));
993 Anum_pg_ts_config_oid);
1033 Anum_pg_ts_config_map_mapcfg,
1041 slot_stored_count = 0;
1043 slot_init_count = 0;
1049 if (slot_init_count < max_slots)
1058 memset(slot[slot_stored_count]->tts_isnull,
false,
1059 slot[slot_stored_count]->tts_tupleDescriptor->natts *
sizeof(
bool));
1061 slot[slot_stored_count]->
tts_values[Anum_pg_ts_config_map_mapcfg - 1] = cfgOid;
1062 slot[slot_stored_count]->
tts_values[Anum_pg_ts_config_map_maptokentype - 1] = cfgmap->maptokentype;
1063 slot[slot_stored_count]->
tts_values[Anum_pg_ts_config_map_mapseqno - 1] = cfgmap->mapseqno;
1064 slot[slot_stored_count]->
tts_values[Anum_pg_ts_config_map_mapdict - 1] = cfgmap->mapdict;
1067 slot_stored_count++;
1070 if (slot_stored_count == max_slots)
1074 slot_stored_count = 0;
1079 if (slot_stored_count > 0)
1083 for (
int i = 0;
i < slot_init_count;
i++)
1122 elog(
ERROR,
"cache lookup failed for text search dictionary %u",
1135 Anum_pg_ts_config_map_mapcfg,
1167 (
errcode(ERRCODE_UNDEFINED_OBJECT),
1168 errmsg(
"text search configuration \"%s\" does not exist",
1183 else if (
stmt->tokentype)
1213 if (strcmp(token_name, ts->
name) == 0)
1242 elog(
ERROR,
"method lextype isn't defined for text search parser %u",
1249 foreach(tn, tokennames)
1276 (
errcode(ERRCODE_INVALID_PARAMETER_VALUE),
1277 errmsg(
"token type \"%s\" does not exist",
1307 cfgId = tsform->oid;
1308 prsId = tsform->cfgparser;
1323 Anum_pg_ts_config_map_mapcfg,
1327 Anum_pg_ts_config_map_maptokentype,
1349 foreach(
c,
stmt->dicts)
1364 Oid dictOld = dictIds[0],
1365 dictNew = dictIds[1];
1368 Anum_pg_ts_config_map_mapcfg,
1384 bool tokmatch =
false;
1390 if (cfgmap->maptokentype == ts->
num)
1403 if (cfgmap->mapdict == dictOld)
1405 Datum repl_val[Natts_pg_ts_config_map];
1406 bool repl_null[Natts_pg_ts_config_map];
1407 bool repl_repl[Natts_pg_ts_config_map];
1410 memset(repl_val, 0,
sizeof(repl_val));
1411 memset(repl_null,
false,
sizeof(repl_null));
1412 memset(repl_repl,
false,
sizeof(repl_repl));
1415 repl_repl[Anum_pg_ts_config_map_mapdict - 1] =
true;
1419 repl_val, repl_null, repl_repl);
1433 nslots =
Min(ntoken * ndict,
1436 for (
i = 0;
i < nslots;
i++)
1447 for (
j = 0;
j < ndict;
j++)
1451 memset(slot[slotCount]->tts_isnull,
false,
1452 slot[slotCount]->tts_tupleDescriptor->natts *
sizeof(
bool));
1463 if (slotCount == nslots)
1477 for (
i = 0;
i < nslots;
i++)
1504 cfgId = tsform->oid;
1505 prsId = tsform->cfgparser;
1515 Anum_pg_ts_config_map_mapcfg,
1519 Anum_pg_ts_config_map_maptokentype,
1536 if (!
stmt->missing_ok)
1539 (
errcode(ERRCODE_UNDEFINED_OBJECT),
1540 errmsg(
"mapping for token type \"%s\" does not exist",
1546 (
errmsg(
"mapping for token type \"%s\" does not exist, skipping",
1591 if (strchr(
val,
'\\'))
1604 if (
lnext(deflist, l) != NULL)
1642 ds_state
state = CS_WAITKEY;
1647 for (; ptr < endptr; ptr++)
1652 if (isspace((
unsigned char) *ptr) || *ptr ==
',')
1667 if (isspace((
unsigned char) *ptr))
1672 else if (*ptr ==
'=')
1675 state = CS_WAITVALUE;
1685 if (ptr + 1 < endptr && ptr[1] ==
'"')
1703 state = CS_WAITVALUE;
1704 else if (!isspace((
unsigned char) *ptr))
1706 (
errcode(ERRCODE_SYNTAX_ERROR),
1707 errmsg(
"invalid parameter list format: \"%s\"",
1714 state = CS_INSQVALUE;
1716 else if (*ptr ==
'E' && ptr + 1 < endptr && ptr[1] ==
'\'')
1720 state = CS_INSQVALUE;
1722 else if (*ptr ==
'"')
1725 state = CS_INDQVALUE;
1727 else if (!isspace((
unsigned char) *ptr))
1731 state = CS_INWVALUE;
1737 if (ptr + 1 < endptr && ptr[1] ==
'\'')
1752 else if (*ptr ==
'\\')
1754 if (ptr + 1 < endptr && ptr[1] ==
'\\')
1770 if (ptr + 1 < endptr && ptr[1] ==
'"')
1791 if (*ptr ==
',' || isspace((
unsigned char) *ptr))
1806 elog(
ERROR,
"unrecognized deserialize_deflist state: %d",
1811 if (
state == CS_INWVALUE)
1819 else if (
state != CS_WAITKEY)
1821 (
errcode(ERRCODE_SYNTAX_ERROR),
1822 errmsg(
"invalid parameter list format: \"%s\"",
1837 if (!was_quoted &&
val[0] !=
'\0')
1845 if (errno == 0 && *endptr ==
'\0')
1851 (void) strtod(
val, &endptr);
1852 if (errno == 0 && *endptr ==
'\0')
1857 if (strcmp(
val,
"true") == 0)
1861 if (strcmp(
val,
"false") == 0)
void aclcheck_error(AclResult aclerr, ObjectType objtype, const char *objectname)
AclResult object_aclcheck(Oid classid, Oid objectid, Oid roleid, AclMode mode)
bool object_ownercheck(Oid classid, Oid objectid, Oid roleid)
static Datum values[MAXATTR]
#define ESCAPE_STRING_SYNTAX
#define SQL_STR_DOUBLE(ch, escape_backslash)
#define OidIsValid(objectId)
Oid GetNewOidWithIndex(Relation relation, Oid indexId, AttrNumber oidcolumn)
List * defGetQualifiedName(DefElem *def)
char * defGetString(DefElem *def)
void record_object_address_dependencies(const ObjectAddress *depender, ObjectAddresses *referenced, DependencyType behavior)
ObjectAddresses * new_object_addresses(void)
void add_exact_object_address(const ObjectAddress *object, ObjectAddresses *addrs)
void free_object_addresses(ObjectAddresses *addrs)
int errcode(int sqlerrcode)
int errmsg(const char *fmt,...)
#define ereport(elevel,...)
void EventTriggerCollectAlterTSConfig(AlterTSConfigurationStmt *stmt, Oid cfgId, Oid *dictIds, int ndicts)
TupleTableSlot * ExecStoreVirtualTuple(TupleTableSlot *slot)
void ExecDropSingleTupleTableSlot(TupleTableSlot *slot)
const TupleTableSlotOps TTSOpsHeapTuple
TupleTableSlot * MakeSingleTupleTableSlot(TupleDesc tupdesc, const TupleTableSlotOps *tts_ops)
#define OidFunctionCall1(functionId, arg1)
#define DatumGetTextPP(X)
void systable_endscan(SysScanDesc sysscan)
HeapTuple systable_getnext(SysScanDesc sysscan)
SysScanDesc systable_beginscan(Relation heapRelation, Oid indexId, bool indexOK, Snapshot snapshot, int nkeys, ScanKey key)
HeapTuple heap_modify_tuple(HeapTuple tuple, TupleDesc tupleDesc, const Datum *replValues, const bool *replIsnull, const bool *doReplace)
HeapTuple heap_form_tuple(TupleDesc tupleDescriptor, const Datum *values, const bool *isnull)
void heap_freetuple(HeapTuple htup)
#define HeapTupleIsValid(tuple)
void CatalogTupleUpdate(Relation heapRel, ItemPointer otid, HeapTuple tup)
void CatalogTuplesMultiInsertWithInfo(Relation heapRel, TupleTableSlot **slot, int ntuples, CatalogIndexState indstate)
void CatalogCloseIndexes(CatalogIndexState indstate)
void CatalogTupleInsert(Relation heapRel, HeapTuple tup)
CatalogIndexState CatalogOpenIndexes(Relation heapRel)
void CatalogTupleDelete(Relation heapRel, ItemPointer tid)
void CatalogTupleUpdateWithInfo(Relation heapRel, ItemPointer otid, HeapTuple tup, CatalogIndexState indstate)
#define MAX_CATALOG_MULTI_INSERT_BYTES
List * lappend(List *list, void *datum)
char * get_namespace_name(Oid nspid)
Oid get_func_rettype(Oid funcid)
DefElem * makeDefElem(char *name, Node *arg, int location)
char * pstrdup(const char *in)
void pfree(void *pointer)
void * palloc0(Size size)
void namestrcpy(Name name, const char *str)
Oid QualifiedNameGetCreationNamespace(const List *names, char **objname_p)
Oid get_ts_dict_oid(List *names, bool missing_ok)
Oid get_ts_parser_oid(List *names, bool missing_ok)
char * NameListToString(const List *names)
Oid get_ts_config_oid(List *names, bool missing_ok)
Oid get_ts_template_oid(List *names, bool missing_ok)
#define IsA(nodeptr, _type_)
#define InvokeObjectPostCreateHook(classId, objectId, subId)
#define InvokeObjectPostAlterHook(classId, objectId, subId)
#define ObjectAddressSet(addr, class_id, object_id)
const char * func_signature_string(List *funcname, int nargs, List *argnames, const Oid *argtypes)
Oid LookupFuncName(List *funcname, int nargs, const Oid *argtypes, bool missing_ok)
long deleteDependencyRecordsFor(Oid classId, Oid objectId, bool skipExtensionDeps)
void recordDependencyOnCurrentExtension(const ObjectAddress *object, bool isReplace)
#define lfirst_node(type, lc)
static int list_length(const List *l)
#define foreach_delete_current(lst, var_or_cell)
static ListCell * lnext(const List *l, const ListCell *c)
void deleteSharedDependencyRecordsFor(Oid classId, Oid objectId, int32 objectSubId)
void recordDependencyOnOwner(Oid classId, Oid objectId, Oid owner)
FormData_pg_ts_config * Form_pg_ts_config
FormData_pg_ts_config_map * Form_pg_ts_config_map
FormData_pg_ts_config_map
FormData_pg_ts_dict * Form_pg_ts_dict
FormData_pg_ts_parser * Form_pg_ts_parser
FormData_pg_ts_template * Form_pg_ts_template
static Datum PointerGetDatum(const void *X)
static Oid DatumGetObjectId(Datum X)
static Datum ObjectIdGetDatum(Oid X)
static Datum NameGetDatum(const NameData *X)
static Pointer DatumGetPointer(Datum X)
static Datum Int32GetDatum(int32 X)
#define RelationGetDescr(relation)
const char * quote_identifier(const char *ident)
void ScanKeyInit(ScanKey entry, AttrNumber attributeNumber, StrategyNumber strategy, RegProcedure procedure, Datum argument)
#define BTEqualStrategyNumber
int strtoint(const char *pg_restrict str, char **pg_restrict endptr, int base)
void appendStringInfo(StringInfo str, const char *fmt,...)
void appendStringInfoString(StringInfo str, const char *s)
void appendStringInfoChar(StringInfo str, char ch)
void initStringInfo(StringInfo str)
void ReleaseSysCache(HeapTuple tuple)
HeapTuple SearchSysCache1(int cacheId, Datum key1)
Datum SysCacheGetAttr(int cacheId, HeapTuple tup, AttrNumber attributeNumber, bool *isNull)
void table_close(Relation relation, LOCKMODE lockmode)
Relation table_open(Oid relationId, LOCKMODE lockmode)
TSParserCacheEntry * lookup_ts_parser_cache(Oid prsId)
ObjectAddress AlterTSConfiguration(AlterTSConfigurationStmt *stmt)
ObjectAddress DefineTSTemplate(List *names, List *parameters)
ObjectAddress DefineTSDictionary(List *names, List *parameters)
static ObjectAddress makeTSTemplateDependencies(HeapTuple tuple)
static ObjectAddress makeConfigurationDependencies(HeapTuple tuple, bool removeOld, Relation mapRel)
void RemoveTSConfigurationById(Oid cfgId)
static HeapTuple GetTSConfigTuple(List *names)
static DefElem * buildDefItem(const char *name, const char *val, bool was_quoted)
static void DropConfigurationMapping(AlterTSConfigurationStmt *stmt, HeapTuple tup, Relation relMap)
static ObjectAddress makeDictionaryDependencies(HeapTuple tuple)
static Datum get_ts_template_func(DefElem *defel, int attnum)
static bool tstoken_list_member(char *token_name, List *tokens)
List * deserialize_deflist(Datum txt)
static List * getTokenTypes(Oid prsId, List *tokennames)
ObjectAddress DefineTSConfiguration(List *names, List *parameters, ObjectAddress *copied)
static Datum get_ts_parser_func(DefElem *defel, int attnum)
ObjectAddress AlterTSDictionary(AlterTSDictionaryStmt *stmt)
static void verify_dictoptions(Oid tmplId, List *dictoptions)
ObjectAddress DefineTSParser(List *names, List *parameters)
static void MakeConfigurationMapping(AlterTSConfigurationStmt *stmt, HeapTuple tup, Relation relMap)
static ObjectAddress makeParserDependencies(HeapTuple tuple)
text * serialize_deflist(List *deflist)
static TupleTableSlot * ExecClearTuple(TupleTableSlot *slot)
Boolean * makeBoolean(bool val)
Float * makeFloat(char *numericStr)
String * makeString(char *str)
Integer * makeInteger(int i)
#define VARSIZE_ANY_EXHDR(PTR)
char * text_to_cstring(const text *t)
text * cstring_to_text_with_len(const char *s, int len)
void CommandCounterIncrement(void)