46 #include "utils/fmgroids.h"
76 retTypeId = INTERNALOID;
77 typeId[0] = INTERNALOID;
80 case Anum_pg_ts_parser_prsstart:
84 case Anum_pg_ts_parser_prstoken:
86 typeId[1] = INTERNALOID;
87 typeId[2] = INTERNALOID;
89 case Anum_pg_ts_parser_prsend:
93 case Anum_pg_ts_parser_prsheadline:
95 typeId[1] = INTERNALOID;
96 typeId[2] = TSQUERYOID;
98 case Anum_pg_ts_parser_prslextype:
109 elog(
ERROR,
"unrecognized attribute for text search parser: %d",
117 (
errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
118 errmsg(
"function %s should return type %s",
153 referenced.
objectId = prs->prstoken;
159 referenced.
objectId = prs->prslextype;
164 referenced.
objectId = prs->prsheadline;
185 bool nulls[Natts_pg_ts_parser];
193 (
errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
194 errmsg(
"must be superuser to create text search parsers")));
203 memset(nulls,
false,
sizeof(nulls));
206 Anum_pg_ts_parser_oid);
215 foreach(pl, parameters)
219 if (strcmp(defel->
defname,
"start") == 0)
221 values[Anum_pg_ts_parser_prsstart - 1] =
224 else if (strcmp(defel->
defname,
"gettoken") == 0)
226 values[Anum_pg_ts_parser_prstoken - 1] =
229 else if (strcmp(defel->
defname,
"end") == 0)
231 values[Anum_pg_ts_parser_prsend - 1] =
234 else if (strcmp(defel->
defname,
"headline") == 0)
236 values[Anum_pg_ts_parser_prsheadline - 1] =
239 else if (strcmp(defel->
defname,
"lextypes") == 0)
241 values[Anum_pg_ts_parser_prslextype - 1] =
246 (
errcode(ERRCODE_SYNTAX_ERROR),
247 errmsg(
"text search parser parameter \"%s\" not recognized",
256 (
errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
257 errmsg(
"text search parser start method is required")));
261 (
errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
262 errmsg(
"text search parser gettoken method is required")));
266 (
errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
267 errmsg(
"text search parser end method is required")));
271 (
errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
272 errmsg(
"text search parser lextypes method is required")));
354 elog(
ERROR,
"cache lookup failed for text search template %u",
358 initmethod = tform->tmplinit;
365 (
errcode(ERRCODE_SYNTAX_ERROR),
366 errmsg(
"text search template \"%s\" does not accept options",
397 bool nulls[Natts_pg_ts_dict];
419 foreach(pl, parameters)
423 if (strcmp(defel->
defname,
"template") == 0)
430 dictoptions =
lappend(dictoptions, defel);
439 (
errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
440 errmsg(
"text search template is required")));
451 memset(nulls,
false,
sizeof(nulls));
454 Anum_pg_ts_dict_oid);
462 values[Anum_pg_ts_dict_dictinitoption - 1] =
465 nulls[Anum_pg_ts_dict_dictinitoption - 1] =
true;
497 Datum repl_val[Natts_pg_ts_dict];
498 bool repl_null[Natts_pg_ts_dict];
499 bool repl_repl[Natts_pg_ts_dict];
509 elog(
ERROR,
"cache lookup failed for text search dictionary %u",
519 Anum_pg_ts_dict_dictinitoption,
529 foreach(pl,
stmt->options)
537 foreach(cell, dictoptions)
549 dictoptions =
lappend(dictoptions, defel);
561 memset(repl_val, 0,
sizeof(repl_val));
562 memset(repl_null,
false,
sizeof(repl_null));
563 memset(repl_repl,
false,
sizeof(repl_repl));
566 repl_val[Anum_pg_ts_dict_dictinitoption - 1] =
569 repl_null[Anum_pg_ts_dict_dictinitoption - 1] =
true;
570 repl_repl[Anum_pg_ts_dict_dictinitoption - 1] =
true;
573 repl_val, repl_null, repl_repl);
611 retTypeId = INTERNALOID;
612 typeId[0] = INTERNALOID;
613 typeId[1] = INTERNALOID;
614 typeId[2] = INTERNALOID;
615 typeId[3] = INTERNALOID;
618 case Anum_pg_ts_template_tmplinit:
621 case Anum_pg_ts_template_tmpllexize:
626 elog(
ERROR,
"unrecognized attribute for text search template: %d",
634 (
errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
635 errmsg(
"function %s should return type %s",
670 referenced.
objectId = tmpl->tmplinit;
690 bool nulls[Natts_pg_ts_template];
700 (
errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
701 errmsg(
"must be superuser to create text search templates")));
708 for (
i = 0;
i < Natts_pg_ts_template;
i++)
715 Anum_pg_ts_dict_oid);
724 foreach(pl, parameters)
728 if (strcmp(defel->
defname,
"init") == 0)
730 values[Anum_pg_ts_template_tmplinit - 1] =
732 nulls[Anum_pg_ts_template_tmplinit - 1] =
false;
734 else if (strcmp(defel->
defname,
"lexize") == 0)
736 values[Anum_pg_ts_template_tmpllexize - 1] =
738 nulls[Anum_pg_ts_template_tmpllexize - 1] =
false;
742 (
errcode(ERRCODE_SYNTAX_ERROR),
743 errmsg(
"text search template parameter \"%s\" not recognized",
752 (
errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
753 errmsg(
"text search template lexize method is required")));
793 elog(
ERROR,
"cache lookup failed for text search configuration %u",
814 myself.
classId = TSConfigRelationId;
833 referenced.
classId = NamespaceRelationId;
834 referenced.
objectId = cfg->cfgnamespace;
845 referenced.
classId = TSParserRelationId;
846 referenced.
objectId = cfg->cfgparser;
861 Anum_pg_ts_config_map_mapcfg,
872 referenced.
classId = TSDictionaryRelationId;
873 referenced.
objectId = cfgmap->mapdict;
899 bool nulls[Natts_pg_ts_config];
922 foreach(pl, parameters)
926 if (strcmp(defel->
defname,
"parser") == 0)
928 else if (strcmp(defel->
defname,
"copy") == 0)
932 (
errcode(ERRCODE_SYNTAX_ERROR),
933 errmsg(
"text search configuration parameter \"%s\" not recognized",
939 (
errcode(ERRCODE_SYNTAX_ERROR),
940 errmsg(
"cannot specify both PARSER and COPY options")));
959 elog(
ERROR,
"cache lookup failed for text search configuration %u",
965 prsOid = cfg->cfgparser;
975 (
errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
976 errmsg(
"text search parser is required")));
984 memset(nulls,
false,
sizeof(nulls));
987 Anum_pg_ts_config_oid);
1027 Anum_pg_ts_config_map_mapcfg,
1035 slot_stored_count = 0;
1037 slot_init_count = 0;
1043 if (slot_init_count < max_slots)
1052 memset(slot[slot_stored_count]->tts_isnull,
false,
1053 slot[slot_stored_count]->tts_tupleDescriptor->natts *
sizeof(
bool));
1055 slot[slot_stored_count]->
tts_values[Anum_pg_ts_config_map_mapcfg - 1] = cfgOid;
1056 slot[slot_stored_count]->
tts_values[Anum_pg_ts_config_map_maptokentype - 1] = cfgmap->maptokentype;
1057 slot[slot_stored_count]->
tts_values[Anum_pg_ts_config_map_mapseqno - 1] = cfgmap->mapseqno;
1058 slot[slot_stored_count]->
tts_values[Anum_pg_ts_config_map_mapdict - 1] = cfgmap->mapdict;
1061 slot_stored_count++;
1064 if (slot_stored_count == max_slots)
1068 slot_stored_count = 0;
1073 if (slot_stored_count > 0)
1077 for (
int i = 0;
i < slot_init_count;
i++)
1116 elog(
ERROR,
"cache lookup failed for text search dictionary %u",
1129 Anum_pg_ts_config_map_mapcfg,
1161 (
errcode(ERRCODE_UNDEFINED_OBJECT),
1162 errmsg(
"text search configuration \"%s\" does not exist",
1177 else if (
stmt->tokentype)
1210 res = (
int *)
palloc(
sizeof(
int) * ntoken);
1213 elog(
ERROR,
"method lextype isn't defined for text search parser %u",
1221 foreach(tn, tokennames)
1240 (
errcode(ERRCODE_INVALID_PARAMETER_VALUE),
1241 errmsg(
"token type \"%s\" does not exist",
1272 cfgId = tsform->oid;
1273 prsId = tsform->cfgparser;
1283 for (
i = 0;
i < ntoken;
i++)
1286 Anum_pg_ts_config_map_mapcfg,
1290 Anum_pg_ts_config_map_maptokentype,
1312 foreach(
c,
stmt->dicts)
1327 Oid dictOld = dictIds[0],
1328 dictNew = dictIds[1];
1331 Anum_pg_ts_config_map_mapcfg,
1347 bool tokmatch =
false;
1349 for (
j = 0;
j < ntoken;
j++)
1351 if (cfgmap->maptokentype == tokens[
j])
1364 if (cfgmap->mapdict == dictOld)
1366 Datum repl_val[Natts_pg_ts_config_map];
1367 bool repl_null[Natts_pg_ts_config_map];
1368 bool repl_repl[Natts_pg_ts_config_map];
1371 memset(repl_val, 0,
sizeof(repl_val));
1372 memset(repl_null,
false,
sizeof(repl_null));
1373 memset(repl_repl,
false,
sizeof(repl_repl));
1376 repl_repl[Anum_pg_ts_config_map_mapdict - 1] =
true;
1380 repl_val, repl_null, repl_repl);
1394 nslots =
Min(ntoken * ndict,
1397 for (
i = 0;
i < nslots;
i++)
1404 for (
i = 0;
i < ntoken;
i++)
1406 for (
j = 0;
j < ndict;
j++)
1410 memset(slot[slotCount]->tts_isnull,
false,
1411 slot[slotCount]->tts_tupleDescriptor->natts *
sizeof(
bool));
1422 if (slotCount == nslots)
1436 for (
i = 0;
i < nslots;
i++)
1464 cfgId = tsform->oid;
1465 prsId = tsform->cfgparser;
1470 foreach(
c,
stmt->tokentype)
1476 Anum_pg_ts_config_map_mapcfg,
1480 Anum_pg_ts_config_map_maptokentype,
1497 if (!
stmt->missing_ok)
1500 (
errcode(ERRCODE_UNDEFINED_OBJECT),
1501 errmsg(
"mapping for token type \"%s\" does not exist",
1507 (
errmsg(
"mapping for token type \"%s\" does not exist, skipping",
1554 if (strchr(
val,
'\\'))
1567 if (
lnext(deflist, l) != NULL)
1605 ds_state
state = CS_WAITKEY;
1610 for (; ptr < endptr; ptr++)
1615 if (isspace((
unsigned char) *ptr) || *ptr ==
',')
1630 if (isspace((
unsigned char) *ptr))
1635 else if (*ptr ==
'=')
1638 state = CS_WAITVALUE;
1648 if (ptr + 1 < endptr && ptr[1] ==
'"')
1666 state = CS_WAITVALUE;
1667 else if (!isspace((
unsigned char) *ptr))
1669 (
errcode(ERRCODE_SYNTAX_ERROR),
1670 errmsg(
"invalid parameter list format: \"%s\"",
1677 state = CS_INSQVALUE;
1679 else if (*ptr ==
'E' && ptr + 1 < endptr && ptr[1] ==
'\'')
1683 state = CS_INSQVALUE;
1685 else if (*ptr ==
'"')
1688 state = CS_INDQVALUE;
1690 else if (!isspace((
unsigned char) *ptr))
1694 state = CS_INWVALUE;
1700 if (ptr + 1 < endptr && ptr[1] ==
'\'')
1715 else if (*ptr ==
'\\')
1717 if (ptr + 1 < endptr && ptr[1] ==
'\\')
1733 if (ptr + 1 < endptr && ptr[1] ==
'"')
1754 if (*ptr ==
',' || isspace((
unsigned char) *ptr))
1769 elog(
ERROR,
"unrecognized deserialize_deflist state: %d",
1774 if (
state == CS_INWVALUE)
1782 else if (
state != CS_WAITKEY)
1784 (
errcode(ERRCODE_SYNTAX_ERROR),
1785 errmsg(
"invalid parameter list format: \"%s\"",
1800 if (!was_quoted &&
val[0] !=
'\0')
1808 if (errno == 0 && *endptr ==
'\0')
1814 (void) strtod(
val, &endptr);
1815 if (errno == 0 && *endptr ==
'\0')
1820 if (strcmp(
val,
"true") == 0)
1824 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)
static void PGresult * res
elog(ERROR, "%s: %s", p2, msg)
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_form_tuple(TupleDesc tupleDescriptor, Datum *values, bool *isnull)
HeapTuple heap_modify_tuple(HeapTuple tuple, TupleDesc tupleDesc, Datum *replValues, bool *replIsnull, bool *doReplace)
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 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)
static ListCell * lnext(const List *l, const ListCell *c)
#define foreach_delete_current(lst, cell)
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 int * getTokenTypes(Oid prsId, List *tokennames)
static Datum get_ts_template_func(DefElem *defel, int attnum)
List * deserialize_deflist(Datum txt)
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)