/libsrc/Wi/sparql.sql

https://github.com/XixiLuo/virtuoso-opensource · SQL · 17566 lines · 15959 code · 657 blank · 950 comment · 3103 complexity · 9f0d15e8b932454fa58f529fe45da796 MD5 · raw file

  1. --
  2. -- $Id$
  3. --
  4. -- This file is part of the OpenLink Software Virtuoso Open-Source (VOS)
  5. -- project.
  6. --
  7. -- Copyright (C) 1998-2014 OpenLink Software
  8. --
  9. -- This project is free software; you can redistribute it and/or modify it
  10. -- under the terms of the GNU General Public License as published by the
  11. -- Free Software Foundation; only version 2 of the License, dated June 1991.
  12. --
  13. -- This program is distributed in the hope that it will be useful, but
  14. -- WITHOUT ANY WARRANTY; without even the implied warranty of
  15. -- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  16. -- General Public License for more details.
  17. --
  18. -- You should have received a copy of the GNU General Public License along
  19. -- with this program; if not, write to the Free Software Foundation, Inc.,
  20. -- 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
  21. --
  22. --
  23. create table DB.DBA.RDF_QUAD (
  24. G IRI_ID_8,
  25. S IRI_ID_8,
  26. P IRI_ID_8,
  27. O any,
  28. primary key (P, S, O, G) column
  29. )
  30. alter index RDF_QUAD on DB.DBA.RDF_QUAD partition (S int (0hexffff00))
  31. create distinct no primary key ref column index RDF_QUAD_SP on DB.DBA.RDF_QUAD (S, P) partition (S int (0hexffff00))
  32. create column index RDF_QUAD_POGS on DB.DBA.RDF_QUAD (P, O, S, G) partition (O varchar (-1, 0hexffff))
  33. create distinct no primary key ref column index RDF_QUAD_GS on DB.DBA.RDF_QUAD (G, S) partition (S int (0hexffff00))
  34. create distinct no primary key ref column index RDF_QUAD_OP on DB.DBA.RDF_QUAD (O, P) partition (O varchar (-1, 0hexffff))
  35. ;
  36. create table DB.DBA.RDF_QUAD_RECOV_TMP (
  37. G1 IRI_ID_8, S1 IRI_ID_8, P1 IRI_ID_8, O1 any, primary key (P1, S1, O1, G1) column)
  38. alter index RDF_QUAD_RECOV_TMP on DB.DBA.RDF_QUAD_RECOV_TMP partition (S1 int (0hexffff00))
  39. create column index RDF_QUAD_RECOV_TMP_POGS on DB.DBA.RDF_QUAD_RECOV_TMP (P1, O1, G1, S1) partition (O1 varchar (-1, 0hexffff))
  40. create distinct no primary key ref column index RDF_QUAD_RECOV_TMP_OP on DB.DBA.RDF_QUAD_RECOV_TMP (O1, P1) partition (O1 varchar (-1, 0hexffff))
  41. ;
  42. create function DB.DBA.RDF_MAKE_IID_OF_QNAME_SAFE (in qname any) returns IRI_ID
  43. {
  44. return iri_to_id_nosignal (qname);
  45. }
  46. ;
  47. create function DB.DBA.RDF_MAKE_IID_OF_QNAME_COMP (in qname any) returns IRI_ID
  48. {
  49. return iri_to_id_nosignal (qname, 0);
  50. }
  51. ;
  52. create function DB.DBA.RDF_QNAME_OF_IID (in iid IRI_ID) returns varchar -- DEPRECATED
  53. {
  54. return id_to_iri_nosignal (iid);
  55. }
  56. ;
  57. DB.DBA.RDF_MAKE_IID_OF_QNAME_SAFE (null)
  58. ;
  59. DB.DBA.RDF_MAKE_IID_OF_QNAME_COMP (null)
  60. ;
  61. DB.DBA.RDF_QNAME_OF_IID (null)
  62. ;
  63. --create trigger DB.DBA.RDF_QUAD_O_AUDIT before insert on DB.DBA.RDF_QUAD
  64. --{
  65. -- if (not rdf_box_is_storeable (O))
  66. -- signal ('RDFXX', 'non-storeable O');
  67. --}
  68. --;
  69. create table DB.DBA.RDF_OBJ (
  70. RO_ID bigint primary key,
  71. RO_VAL varchar not null,
  72. RO_LONG long varchar,
  73. RO_FLAGS smallint not null default 0,
  74. RO_DT_AND_LANG integer not null default 16843009 compress any
  75. )
  76. alter index RDF_OBJ on RDF_OBJ partition (RO_ID int (0hexffff00))
  77. create index RO_VAL on DB.DBA.RDF_OBJ (RO_VAL, RO_DT_AND_LANG)
  78. partition (RO_VAL varchar (-4, 0hexffff))
  79. ;
  80. create table DB.DBA.RO_START (RS_START varchar, RS_DT_AND_LANG int, RS_RO_ID any,
  81. primary key (RS_START, RS_DT_AND_LANG, RS_RO_ID))
  82. alter index RO_START on DB.DBA.RO_START partition (RS_RO_ID varchar (-1, 0hexffff))
  83. ;
  84. --create table DB.DBA.RDF_FT (
  85. -- RF_ID bigint primary key,
  86. -- RF_O any)
  87. --alter index RDF_FT on RDF_FT partition (RF_ID int (0hexffff00))
  88. --create index RF_O on RDF_FT (RF_O) partition (RF_O varchar (-1, 0hexffff))
  89. --;
  90. create table DB.DBA.RDF_DATATYPE (
  91. RDT_IID IRI_ID_8 not null primary key,
  92. RDT_TWOBYTE integer not null unique,
  93. RDT_QNAME varchar not null unique )
  94. alter index RDF_DATATYPE on RDF_DATATYPE partition cluster replicated
  95. alter index DB_DBA_RDF_DATATYPE_UNQC_RDT_TWOBYTE on RDF_DATATYPE partition cluster replicated
  96. alter index DB_DBA_RDF_DATATYPE_UNQC_RDT_QNAME on RDF_DATATYPE partition cluster replicated
  97. ;
  98. create table DB.DBA.RDF_LANGUAGE (
  99. RL_ID varchar not null primary key,
  100. RL_TWOBYTE integer not null unique )
  101. alter index RDF_LANGUAGE on RDF_LANGUAGE partition cluster replicated
  102. alter index DB_DBA_RDF_LANGUAGE_UNQC_RL_TWOBYTE on RDF_LANGUAGE partition cluster replicated
  103. ;
  104. create table DB.DBA.SYS_SPARQL_HOST (
  105. SH_HOST varchar not null primary key,
  106. SH_GRAPH_URI varchar,
  107. SH_USER_URI varchar,
  108. SH_BASE_URI varchar,
  109. SH_DEFINES long varchar
  110. )
  111. ;
  112. alter table DB.DBA.SYS_SPARQL_HOST add SH_BASE_URI varchar
  113. ;
  114. create table DB.DBA.RDF_OBJ_FT_RULES (
  115. ROFR_G varchar not null,
  116. ROFR_P varchar not null,
  117. ROFR_REASON varchar not null,
  118. primary key (ROFR_G, ROFR_P, ROFR_REASON) )
  119. alter index RDF_OBJ_FT_RULES on RDF_OBJ_FT_RULES partition cluster replicated
  120. ;
  121. create table DB.DBA.SYS_SPARQL_SW_LOG (
  122. PL_SERVER varchar,
  123. PL_URI varchar,
  124. PL_TS timestamp,
  125. PL_RC varchar,
  126. PL_MSG long varchar,
  127. primary key (PL_SERVER, PL_URI, PL_TS))
  128. ;
  129. create table DB.DBA.SYS_XML_PERSISTENT_NS_DECL
  130. (
  131. NS_PREFIX varchar not null primary key,
  132. NS_URL varchar not null
  133. )
  134. alter index SYS_XML_PERSISTENT_NS_DECL on SYS_XML_PERSISTENT_NS_DECL partition cluster replicated
  135. ;
  136. create table DB.DBA.RDF_EXPLICITLY_CREATED_GRAPH
  137. (
  138. REC_GRAPH_IID IRI_ID not null primary key
  139. )
  140. alter index RDF_EXPLICITLY_CREATED_GRAPH on RDF_EXPLICITLY_CREATED_GRAPH partition cluster replicated
  141. ;
  142. create table RDF_GEO (X real no compress, Y real no compress,X2 real no compress, Y2 real no compress, ID bigint no compress, primary key (X, Y, X2, Y2, ID))
  143. alter index RDF_GEO on RDF_GEO partition (ID int (0hexffff00))
  144. ;
  145. create table DB.DBA.RDF_LABEL (RL_O any primary key, RL_RO_ID bigint, RL_TEXT varchar, RL_LANG int)
  146. alter index RDF_LABEL on RDF_LABEL partition (RL_O varchar (-1, 0hexffff))
  147. create index RDF_LABEL_TEXT on RDF_LABEL (RL_TEXT, RL_O) partition (RL_TEXT varchar (6, 0hexffff))
  148. ;
  149. create table DB.DBA.RDF_QUAD_DELETE_QUEUE (
  150. EVENT_ID bigint not null,
  151. RULE_ID bigint not null,
  152. QG IRI_ID not null,
  153. QS IRI_ID not null,
  154. QP IRI_ID not null,
  155. QO any not null,
  156. primary key (EVENT_ID, RULE_ID, QG, QS, QP, QO)
  157. )
  158. ;
  159. create table DB.DBA.SYS_IDONLY_EMPTY
  160. (
  161. ID integer not null primary key
  162. )
  163. ;
  164. create table DB.DBA.SYS_IDONLY_ONE
  165. (
  166. ID integer not null primary key
  167. )
  168. ;
  169. insert soft DB.DBA.SYS_IDONLY_ONE (ID) values (0)
  170. ;
  171. sequence_set ('RDF_URL_IID_NAMED', 1000000, 1)
  172. ;
  173. sequence_set ('RDF_PREF_SEQ', 1, 1)
  174. ;
  175. sequence_set ('RDF_URL_IID_BLANK', iri_id_num (min_bnode_iri_id ()), 1)
  176. ;
  177. sequence_set ('RDF_URL_IID_NAMED_BLANK', iri_id_num (min_named_bnode_iri_id ()), 1)
  178. ;
  179. sequence_set ('RDF_RO_ID', 1, 1)
  180. ;
  181. sequence_set ('RDF_DATATYPE_TWOBYTE', 258, 1)
  182. ;
  183. sequence_set ('RDF_LANGUAGE_TWOBYTE', 258, 1)
  184. ;
  185. create procedure RDF_QUAD_FT_INIT ()
  186. {
  187. if (not exists (select 1 from SYS_VT_INDEX where VI_COL = 'o'))
  188. {
  189. insert soft SYS_VT_INDEX (VI_TABLE, VI_INDEX, VI_COL, VI_ID_COL, VI_INDEX_TABLE, VI_ID_IS_PK, VI_OPTIONS)
  190. values ('DB.DBA.RDF_QUAD', 'RDF_QUAD_OP', 'O', 'O', 'DB.DBA.RDF_GEO', 1, 'GR');
  191. insert soft SYS_VT_INDEX (VI_TABLE, VI_INDEX, VI_COL, VI_ID_COL, VI_INDEX_TABLE, VI_ID_IS_PK, VI_OPTIONS)
  192. values ('DB.DBA.RDF_QUAD', 'RDF_QUAD_OP', 'o', 'O', 'DB.DBA.RDF_OBJ_RO_FLAGS_WORDS', 1, null);
  193. __ddl_changed ('DB.DBA.RDF_QUAD');
  194. }
  195. }
  196. ;
  197. create procedure DB.DBA.RDF_OBJ_RO_FLAGS_INDEX_HOOK (inout vtb any, inout d_id any)
  198. {
  199. if (cl_current_slice () = 0hexffff)
  200. {
  201. for (select RO_LONG, RO_VAL, RO_FLAGS
  202. from DB.DBA.RDF_OBJ where RO_ID=d_id and bit_and (RO_FLAGS, 1)) do
  203. {
  204. if (bit_and (RO_FLAGS, 2))
  205. vt_batch_feed (vtb, xml_tree_doc (__xml_deserialize_packed (RO_LONG)), 0);
  206. else
  207. vt_batch_feed (vtb, coalesce (RO_LONG, RO_VAL), 0);
  208. }
  209. }
  210. else
  211. {
  212. for (select RO_LONG, RO_VAL, RO_FLAGS
  213. from DB.DBA.RDF_OBJ table option (no cluster) where RO_ID=d_id and bit_and (RO_FLAGS, 1)) do
  214. {
  215. if (bit_and (RO_FLAGS, 2))
  216. vt_batch_feed (vtb, xml_tree_doc (__xml_deserialize_packed (RO_LONG)), 0);
  217. else
  218. vt_batch_feed (vtb, coalesce (RO_LONG, RO_VAL), 0);
  219. }
  220. }
  221. return 1;
  222. }
  223. ;
  224. create procedure DB.DBA.RDF_OBJ_RO_FLAGS_UNINDEX_HOOK (inout vtb any, inout d_id any)
  225. {
  226. if (cl_current_slice () = 0hexffff)
  227. {
  228. for (select RO_LONG, RO_VAL, RO_FLAGS
  229. from DB.DBA.RDF_OBJ where RO_ID=d_id and bit_and (RO_FLAGS, 1)) do
  230. {
  231. if (bit_and (RO_FLAGS, 2))
  232. vt_batch_feed (vtb, xml_tree_doc (__xml_deserialize_packed (RO_LONG)), 1);
  233. else
  234. vt_batch_feed (vtb, coalesce (RO_LONG, RO_VAL), 1);
  235. }
  236. }
  237. else
  238. {
  239. for (select RO_LONG, RO_VAL, RO_FLAGS
  240. from DB.DBA.RDF_OBJ table option (no cluster) where RO_ID=d_id and bit_and (RO_FLAGS, 1)) do
  241. {
  242. if (bit_and (RO_FLAGS, 2))
  243. vt_batch_feed (vtb, xml_tree_doc (__xml_deserialize_packed (RO_LONG)), 1);
  244. else
  245. vt_batch_feed (vtb, coalesce (RO_LONG, RO_VAL), 1);
  246. }
  247. }
  248. return 1;
  249. }
  250. ;
  251. create procedure sparql_exec_quiet (in expn varchar)
  252. {
  253. declare sta, msg varchar;
  254. exec (expn, sta, msg);
  255. }
  256. ;
  257. sparql_exec_quiet ('DB.DBA.vt_create_text_index (
  258. fix_identifier_case (''DB.DBA.RDF_OBJ''),
  259. fix_identifier_case (''RO_FLAGS''),
  260. fix_identifier_case (''RO_ID''),
  261. 0, 0, vector (), 1, ''*ini*'', ''UTF-8-QR'')')
  262. ;
  263. sparql_exec_quiet ('DB.DBA.vt_batch_update (fix_identifier_case (''DB.DBA.RDF_OBJ''), ''ON'', 1)')
  264. ;
  265. --sparql_exec_quiet ('alter index VTLOG_DB_DBA_RDF_OBJ on VTLOG_DB_DBA_RDF_OBJ partition (VTLOG_RO_ID int (0hexffff00))')
  266. --;
  267. --!AWK PUBLIC
  268. create function DB.DBA.XML_SET_NS_DECL (in prefix varchar, in url varchar, in persist integer := 1) returns integer
  269. {
  270. declare res integer;
  271. res := __xml_set_ns_decl (prefix, url, persist);
  272. if (bit_and (res, 2))
  273. {
  274. declare exit handler for sqlstate '*' { __xml_remove_ns_by_prefix (prefix, persist); resignal; };
  275. if (exists (select 1 from DB.DBA.SYS_XML_PERSISTENT_NS_DECL where NS_PREFIX = prefix and NS_URL = url))
  276. return;
  277. delete from DB.DBA.SYS_XML_PERSISTENT_NS_DECL where NS_PREFIX = prefix;
  278. insert into DB.DBA.SYS_XML_PERSISTENT_NS_DECL (NS_PREFIX, NS_URL) values (prefix, url);
  279. commit work;
  280. }
  281. return res;
  282. }
  283. ;
  284. --!AWK PUBLIC
  285. create procedure DB.DBA.XML_REMOVE_NS_BY_PREFIX (in prefix varchar, in persist integer := 1)
  286. {
  287. declare res integer;
  288. __xml_remove_ns_by_prefix (prefix, persist);
  289. if (bit_and (persist, 2))
  290. {
  291. whenever sqlstate '*' goto again;
  292. again:
  293. delete from DB.DBA.SYS_XML_PERSISTENT_NS_DECL where NS_PREFIX=prefix;
  294. commit work;
  295. }
  296. }
  297. ;
  298. --!AWK PUBLIC
  299. create procedure DB.DBA.XML_CLEAR_ALL_NS_DECLS (in persist integer := 1)
  300. {
  301. declare res integer;
  302. __xml_clear_all_ns_decls (persist);
  303. if (bit_and (persist, 2))
  304. {
  305. whenever sqlstate '*' goto again;
  306. again:
  307. delete from DB.DBA.SYS_XML_PERSISTENT_NS_DECL;
  308. commit work;
  309. }
  310. }
  311. ;
  312. --!AWK PUBLIC
  313. create procedure DB.DBA.XML_SELECT_ALL_NS_DECLS (in persist integer := 3)
  314. {
  315. declare decls any;
  316. declare ctr, len integer;
  317. declare PREFIX, URI varchar;
  318. decls := __xml_get_all_ns_decls (persist);
  319. result_names (PREFIX, URI);
  320. len := length (decls);
  321. for (ctr := 0; ctr < len; ctr := ctr + 2)
  322. result (decls[ctr], decls[ctr+1]);
  323. }
  324. ;
  325. create procedure DB.DBA.XML_LOAD_ALL_NS_DECLS ()
  326. {
  327. for (select NS_PREFIX, NS_URL from DB.DBA.SYS_XML_PERSISTENT_NS_DECL) do
  328. {
  329. __xml_set_ns_decl (NS_PREFIX, NS_URL, 2);
  330. }
  331. DB.DBA.XML_SET_NS_DECL ( 'bif' , 'bif:' , 2);
  332. DB.DBA.XML_SET_NS_DECL ( 'dawgt' , 'http://www.w3.org/2001/sw/DataAccess/tests/test-dawg#' , 2);
  333. DB.DBA.XML_SET_NS_DECL ( 'dbpedia' , 'http://dbpedia.org/resource/' , 2);
  334. DB.DBA.XML_SET_NS_DECL ( 'dbpprop' , 'http://dbpedia.org/property/' , 2);
  335. DB.DBA.XML_SET_NS_DECL ( 'dc' , 'http://purl.org/dc/elements/1.1/' , 2);
  336. DB.DBA.XML_SET_NS_DECL ( 'go' , 'http://purl.org/obo/owl/GO#' , 2);
  337. DB.DBA.XML_SET_NS_DECL ( 'geo' , 'http://www.w3.org/2003/01/geo/wgs84_pos#' , 2);
  338. DB.DBA.XML_SET_NS_DECL ( 'fn' , 'http://www.w3.org/2005/xpath-functions/#' , 2);
  339. DB.DBA.XML_SET_NS_DECL ( 'foaf' , 'http://xmlns.com/foaf/0.1/' , 2);
  340. DB.DBA.XML_SET_NS_DECL ( 'obo' , 'http://www.geneontology.org/formats/oboInOwl#' , 2);
  341. DB.DBA.XML_SET_NS_DECL ( 'ogc' , 'http://www.opengis.net/' , 2);
  342. DB.DBA.XML_SET_NS_DECL ( 'ogcgml' , 'http://www.opengis.net/ont/gml#' , 2);
  343. DB.DBA.XML_SET_NS_DECL ( 'ogcgs' , 'http://www.opengis.net/ont/geosparql#' , 2);
  344. DB.DBA.XML_SET_NS_DECL ( 'ogcgsf' , 'http://www.opengis.net/def/function/geosparql/' , 2);
  345. DB.DBA.XML_SET_NS_DECL ( 'ogcgsr' , 'http://www.opengis.net/def/rule/geosparql/' , 2);
  346. DB.DBA.XML_SET_NS_DECL ( 'ogcsf' , 'http://www.opengis.net/ont/sf#' , 2);
  347. DB.DBA.XML_SET_NS_DECL ( 'owl' , 'http://www.w3.org/2002/07/owl#' , 2);
  348. DB.DBA.XML_SET_NS_DECL ( 'mesh' , 'http://purl.org/commons/record/mesh/' , 2);
  349. DB.DBA.XML_SET_NS_DECL ( 'math' , 'http://www.w3.org/2000/10/swap/math#' , 2);
  350. DB.DBA.XML_SET_NS_DECL ( 'mf' , 'http://www.w3.org/2001/sw/DataAccess/tests/test-manifest#' , 2);
  351. DB.DBA.XML_SET_NS_DECL ( 'nci' , 'http://ncicb.nci.nih.gov/xml/owl/EVS/Thesaurus.owl#' , 2);
  352. DB.DBA.XML_SET_NS_DECL ( 'product' , 'http://www.buy.com/rss/module/productV2/' , 2);
  353. DB.DBA.XML_SET_NS_DECL ( 'protseq' , 'http://purl.org/science/protein/bysequence/' , 2);
  354. DB.DBA.XML_SET_NS_DECL ( 'rdf' , 'http://www.w3.org/1999/02/22-rdf-syntax-ns#' , 2);
  355. DB.DBA.XML_SET_NS_DECL ( 'rdfa' , 'http://www.w3.org/ns/rdfa#' , 2);
  356. DB.DBA.XML_SET_NS_DECL ( 'rdfdf' , 'http://www.openlinksw.com/virtrdf-data-formats#' , 2);
  357. DB.DBA.XML_SET_NS_DECL ( 'rdfs' , 'http://www.w3.org/2000/01/rdf-schema#' , 2);
  358. DB.DBA.XML_SET_NS_DECL ( 'sc' , 'http://purl.org/science/owl/sciencecommons/' , 2);
  359. DB.DBA.XML_SET_NS_DECL ( 'sd' , 'http://www.w3.org/ns/sparql-service-description#' , 2);
  360. DB.DBA.XML_SET_NS_DECL ( 'sioc' , 'http://rdfs.org/sioc/ns#' , 2);
  361. DB.DBA.XML_SET_NS_DECL ( 'skos' , 'http://www.w3.org/2004/02/skos/core#' , 2);
  362. DB.DBA.XML_SET_NS_DECL ( 'sql' , 'sql:' , 2);
  363. DB.DBA.XML_SET_NS_DECL ( 'vcard' , 'http://www.w3.org/2001/vcard-rdf/3.0#' , 2);
  364. DB.DBA.XML_SET_NS_DECL ( 'vcard2006' , 'http://www.w3.org/2006/vcard/ns#' , 2);
  365. DB.DBA.XML_SET_NS_DECL ( 'virtrdf' , 'http://www.openlinksw.com/schemas/virtrdf#' , 2);
  366. DB.DBA.XML_SET_NS_DECL ( 'virtcxml' , 'http://www.openlinksw.com/schemas/virtcxml#' , 2);
  367. DB.DBA.XML_SET_NS_DECL ( 'void' , 'http://rdfs.org/ns/void#' , 2);
  368. DB.DBA.XML_SET_NS_DECL ( 'xf' , 'http://www.w3.org/2004/07/xpath-functions' , 2);
  369. DB.DBA.XML_SET_NS_DECL ( 'xml' , 'http://www.w3.org/XML/1998/namespace' , 2);
  370. DB.DBA.XML_SET_NS_DECL ( 'xsd' , 'http://www.w3.org/2001/XMLSchema#' , 2);
  371. DB.DBA.XML_SET_NS_DECL ( 'xsl10' , 'http://www.w3.org/XSL/Transform/1.0' , 2);
  372. DB.DBA.XML_SET_NS_DECL ( 'xsl1999' , 'http://www.w3.org/1999/XSL/Transform' , 2);
  373. DB.DBA.XML_SET_NS_DECL ( 'xslwd' , 'http://www.w3.org/TR/WD-xsl' , 2);
  374. DB.DBA.XML_SET_NS_DECL ( 'yago' , 'http://dbpedia.org/class/yago/' , 2);
  375. }
  376. ;
  377. DB.DBA.XML_LOAD_ALL_NS_DECLS ()
  378. ;
  379. rdf_inf_const_init ()
  380. ;
  381. create procedure DB.DBA.RDF_LOAD_ALL_FT_RULES ()
  382. {
  383. whenever sqlstate '*' goto again;
  384. again:
  385. for (select ROFR_G as rule_g, ROFR_P as rule_p, ROFR_REASON as reason from DB.DBA.RDF_OBJ_FT_RULES) do
  386. {
  387. declare rule_g_iid, rule_p_iid IRI_ID;
  388. rule_g_iid := case (rule_g) when '' then null else iri_to_id (rule_g) end;
  389. rule_p_iid := case (rule_p) when '' then null else iri_to_id (rule_p) end;
  390. -- dbg_obj_princ ('__rdf_obj_ft_rule_add (', rule_g_iid, rule_p_iid, reason, ')');
  391. __rdf_obj_ft_rule_add (rule_g_iid, rule_p_iid, reason);
  392. }
  393. }
  394. ;
  395. DB.DBA.RDF_LOAD_ALL_FT_RULES ()
  396. ;
  397. create procedure DB.DBA.RDF_REPL_START (in quiet integer := 0)
  398. {
  399. if (repl_this_server () is null)
  400. return;
  401. if (isstring (registry_get ('DB.DBA.RDF_REPL')))
  402. {
  403. if (quiet)
  404. return;
  405. signal ('RDF99', 'RDF replication is already enabled');
  406. }
  407. for (select RGGM_MEMBER_IID from DB.DBA.RDF_GRAPH_GROUP_MEMBER
  408. where RGGM_GROUP_IID = iri_to_id (UNAME'http://www.openlinksw.com/schemas/virtrdf#rdf_repl_graph_group')
  409. and not __rgs_ack_cbk (RGGM_MEMBER_IID, __rdf_repl_uid(), 1) ) do
  410. {
  411. signal ('RDF99', 'RDF replication can not be enabled because it will violate security rules for read access to graph <' || id_to_iri(RGGM_MEMBER_IID) || '> by __rdf_repl account');
  412. }
  413. repl_publish ('__rdf_repl', '__rdf_repl.log');
  414. repl_text ('__rdf_repl', '__rdf_repl_flush_queue()');
  415. DB.DBA.RDF_GRAPH_GROUP_CREATE (UNAME'http://www.openlinksw.com/schemas/virtrdf#rdf_repl_graph_group', 1);
  416. DB.DBA.CL_EXEC ('registry_set (?,?)', vector ('DB.DBA.RDF_REPL', cast (now() as varchar)));
  417. exec ('checkpoint');
  418. }
  419. ;
  420. create procedure DB.DBA.RDF_REPL_STOP (in quiet integer := 0)
  421. {
  422. if (not isstring (registry_get ('DB.DBA.RDF_REPL')))
  423. {
  424. if (quiet)
  425. return;
  426. signal ('RDF99', 'RDF replication is not enabled');
  427. }
  428. repl_unpublish ('__rdf_repl');
  429. DB.DBA.CL_EXEC ('registry_remove (?)', vector ('DB.DBA.RDF_REPL'));
  430. }
  431. ;
  432. create procedure DB.DBA.RDF_REPL_GRAPH_INS (in memb_iri varchar)
  433. {
  434. declare memb_iid IRI_ID;
  435. memb_iid := iri_to_id (memb_iri);
  436. memb_iri := id_to_iri (memb_iid);
  437. DB.DBA.RDF_GRAPH_GROUP_INS (UNAME'http://www.openlinksw.com/schemas/virtrdf#rdf_repl_graph_group', memb_iri);
  438. }
  439. ;
  440. create procedure DB.DBA.RDF_REPL_GRAPH_DEL (in memb_iri varchar)
  441. {
  442. declare memb_iid IRI_ID;
  443. DB.DBA.RDF_GRAPH_GROUP_DEL (UNAME'http://www.openlinksw.com/schemas/virtrdf#rdf_repl_graph_group', memb_iri);
  444. }
  445. ;
  446. create procedure DB.DBA.RDF_REPL_SYNC (in publisher varchar, in u varchar, in pwd varchar)
  447. {
  448. declare lvl, stat integer;
  449. if (repl_this_server () is null)
  450. return;
  451. commit work;
  452. retr:
  453. repl_sync (publisher, '__rdf_repl', u, pwd);
  454. again:
  455. repl_status (publisher, '__rdf_repl', lvl, stat);
  456. if (0 = stat)
  457. {
  458. __rdf_repl_flush_queue();
  459. return;
  460. }
  461. if (1 = stat)
  462. {
  463. delay (0.1);
  464. goto again;
  465. }
  466. if (2 = stat)
  467. {
  468. __rdf_repl_flush_queue();
  469. return;
  470. }
  471. goto retr;
  472. }
  473. ;
  474. create procedure DB.DBA.RDF_REPL_INSERT_TRIPLES (in graph_iri varchar, inout triples any)
  475. {
  476. declare ctr integer;
  477. for (ctr := length (triples) - 1; ctr >= 0; ctr := ctr - 1)
  478. {
  479. declare s_iri, p_iri, o_val, o_type, o_lang any;
  480. s_iri := iri_canonicalize (triples[ctr][0]);
  481. p_iri := iri_canonicalize (triples[ctr][1]);
  482. o_val := triples[ctr][2];
  483. if (isiri_id (o_val))
  484. __rdf_repl_quad (84, graph_iri, s_iri, p_iri, iri_canonicalize (o_val));
  485. else if (__tag of rdf_box <> __tag (o_val))
  486. __rdf_repl_quad (80, graph_iri, s_iri, p_iri, o_val);
  487. else
  488. {
  489. declare dt_twobyte, lang_twobyte integer;
  490. dt_twobyte := rdf_box_type (o_val);
  491. lang_twobyte := rdf_box_lang (o_val);
  492. if (257 <> dt_twobyte)
  493. __rdf_repl_quad (81, graph_iri, s_iri, p_iri, rdf_box_data (o_val), (select RDT_QNAME from DB.DBA.RDF_DATATYPE where RDT_TWOBYTE = dt_twobyte), NULL);
  494. else if (257 <> lang_twobyte)
  495. __rdf_repl_quad (82, graph_iri, s_iri, p_iri, rdf_box_data (o_val), NULL, (select RL_ID from DB.DBA.RDF_LANGUAGE where RL_TWOBYTE = lang_twobyte));
  496. else
  497. __rdf_repl_quad (80, graph_iri, s_iri, p_iri, rdf_box_data (o_val));
  498. }
  499. }
  500. }
  501. ;
  502. create procedure DB.DBA.RDF_REPL_DELETE_TRIPLES (in graph_iri varchar, inout triples any)
  503. {
  504. declare ctr integer;
  505. for (ctr := length (triples) - 1; ctr >= 0; ctr := ctr - 1)
  506. {
  507. declare s_iri, p_iri, o_val, o_type, o_lang any;
  508. s_iri := iri_canonicalize (triples[ctr][0]);
  509. p_iri := iri_canonicalize (triples[ctr][1]);
  510. o_val := triples[ctr][2];
  511. if (isiri_id (o_val))
  512. __rdf_repl_quad (164, graph_iri, s_iri, p_iri, iri_canonicalize (o_val));
  513. else if (__tag of rdf_box <> __tag (o_val))
  514. __rdf_repl_quad (160, graph_iri, s_iri, p_iri, o_val);
  515. else
  516. {
  517. declare dt_twobyte, lang_twobyte integer;
  518. dt_twobyte := rdf_box_type (o_val);
  519. lang_twobyte := rdf_box_lang (o_val);
  520. if (257 <> dt_twobyte)
  521. __rdf_repl_quad (161, graph_iri, s_iri, p_iri, rdf_box_data (o_val), (select RDT_QNAME from DB.DBA.RDF_DATATYPE where RDT_TWOBYTE = dt_twobyte), NULL);
  522. else if (257 <> lang_twobyte)
  523. __rdf_repl_quad (162, graph_iri, s_iri, p_iri, rdf_box_data (o_val), NULL, (select RL_ID from DB.DBA.RDF_LANGUAGE where RL_TWOBYTE = lang_twobyte));
  524. else
  525. __rdf_repl_quad (160, graph_iri, s_iri, p_iri, rdf_box_data (o_val));
  526. }
  527. }
  528. }
  529. ;
  530. --!AFTER
  531. create procedure DB.DBA.RDF_GLOBAL_RESET (in hard integer := 0)
  532. {
  533. if (isstring (registry_get ('DB.DBA.RDF_REPL')))
  534. {
  535. signal ('42RDF', 'Can not make DB.DBA.RDF_GLOBAL_RESET while an RDF replication is enabled');
  536. }
  537. -- checkpoint;
  538. __atomic (1);
  539. iri_id_cache_flush ();
  540. __rdf_obj_ft_rule_zap_all ();
  541. dict_zap (__rdf_graph_group_dict(), 2);
  542. dict_zap (__rdf_graph_group_of_privates_dict(), 2);
  543. dict_zap (__rdf_graph_default_perms_of_user_dict(0), 2);
  544. dict_zap (__rdf_graph_default_perms_of_user_dict(1), 2);
  545. dict_zap (__rdf_graph_public_perms_dict(), 2);
  546. for select RS_NAME from DB.DBA.SYS_RDF_SCHEMA do
  547. rdf_inf_clear (RS_NAME);
  548. delete from sys_rdf_schema;
  549. delete from DB.DBA.RDF_QUAD;
  550. delete from DB.DBA.RDF_OBJ_FT_RULES;
  551. delete from DB.DBA.RDF_GRAPH_GROUP;
  552. for (select __id2i(t.RGU_GRAPH_IID) as graph_iri from (select distinct RGU_GRAPH_IID from DB.DBA.RDF_GRAPH_USER) as t) do
  553. {
  554. if (graph_iri is not null)
  555. {
  556. jso_mark_affected (graph_iri);
  557. log_text ('jso_mark_affected (?)', graph_iri);
  558. jso_mark_affected (iri_canonicalize (graph_iri));
  559. log_text ('jso_mark_affected (?)', iri_canonicalize (graph_iri));
  560. log_text ('jso_mark_affected (iri_canonicalize (?))', graph_iri);
  561. }
  562. }
  563. for (select __id2i(t.RGGM_GROUP_IID) as group_iri from (select distinct RGGM_GROUP_IID from DB.DBA.RDF_GRAPH_GROUP_MEMBER) as t) do
  564. {
  565. if (group_iri is not null)
  566. {
  567. jso_mark_affected (group_iri);
  568. log_text ('jso_mark_affected (?)', group_iri);
  569. }
  570. }
  571. for (select __id2i(RGGM_MEMBER_IID) as memb_iri from DB.DBA.RDF_GRAPH_GROUP_MEMBER where RGGM_GROUP_IID = __i2id ('http://www.openlinksw.com/schemas/virtrdf#PrivateGraphs')) do
  572. {
  573. if (memb_iri is not null)
  574. {
  575. jso_mark_affected (memb_iri);
  576. log_text ('jso_mark_affected (?)', memb_iri);
  577. }
  578. }
  579. for (sparql define input:storage "" select distinct str (?qms) as ?qms_iri from virtrdf: where { ?qms a virtrdf:QuadStorage } ) do
  580. {
  581. if ("qms_iri" is not null)
  582. {
  583. jso_mark_affected ("qms_iri");
  584. log_text ('jso_mark_affected (?)', "qms_iri");
  585. }
  586. }
  587. jso_mark_affected ('http://www.openlinksw.com/schemas/virtrdf#PrivateGraphs');
  588. log_text ('jso_mark_affected (?)', 'http://www.openlinksw.com/schemas/virtrdf#PrivateGraphs');
  589. jso_mark_affected ('http://www.openlinksw.com/schemas/virtrdf#DefaultQuadStorage');
  590. log_text ('jso_mark_affected (?)', 'http://www.openlinksw.com/schemas/virtrdf#DefaultQuadStorage');
  591. jso_mark_affected ('http://www.openlinksw.com/schemas/virtrdf#DefaultQuadMap');
  592. log_text ('jso_mark_affected (?)', 'http://www.openlinksw.com/schemas/virtrdf#DefaultQuadMap');
  593. delete from DB.DBA.RDF_GRAPH_GROUP_MEMBER;
  594. delete from DB.DBA.RDF_GRAPH_USER;
  595. delete from DB.DBA.RDF_LABEL;
  596. delete from DB.DBA.RDF_GEO;
  597. commit work;
  598. if (hard)
  599. {
  600. --delete from DB.DBA.RDF_URL;
  601. delete from DB.DBA.RDF_IRI;
  602. delete from DB.DBA.RDF_PREFIX;
  603. delete from DB.DBA.RDF_OBJ;
  604. delete from DB.DBA.RO_START;
  605. delete from DB.DBA.RDF_DATATYPE;
  606. delete from DB.DBA.RDF_LANGUAGE;
  607. --__rdf_twobyte_cache_zap();
  608. --log_text ('__rdf_twobyte_cache_zap()');
  609. delete from DB.DBA.VTLOG_DB_DBA_RDF_OBJ;
  610. delete from DB.DBA.RDF_OBJ_RO_FLAGS_WORDS;
  611. sequence_set ('RDF_URL_IID_NAMED', 1000000, 0);
  612. sequence_set ('RDF_URL_IID_BLANK', iri_id_num (min_bnode_iri_id ()), 0);
  613. sequence_set ('RDF_URL_IID_NAMED_BLANK', iri_id_num (min_named_bnode_iri_id ()), 0);
  614. sequence_set ('RDF_PREF_SEQ', 1, 0);
  615. sequence_set ('RDF_RO_ID', 1, 0);
  616. sequence_set ('RDF_DATATYPE_TWOBYTE', 258, 0);
  617. sequence_set ('RDF_LANGUAGE_TWOBYTE', 258, 0);
  618. __atomic (0);
  619. exec ('checkpoint');
  620. raw_exit ();
  621. }
  622. sequence_set ('RDF_URL_IID_NAMED', 1000000, 1);
  623. sequence_set ('RDF_URL_IID_BLANK', iri_id_num (min_bnode_iri_id ()), 1);
  624. sequence_set ('RDF_URL_IID_NAMED_BLANK', iri_id_num (min_named_bnode_iri_id ()), 1);
  625. sequence_set ('RDF_PREF_SEQ', 1, 1);
  626. sequence_set ('RDF_RO_ID', 1, 1);
  627. sequence_set ('RDF_DATATYPE_TWOBYTE', 258, 1);
  628. sequence_set ('RDF_LANGUAGE_TWOBYTE', 258, 1);
  629. DB.DBA.RDF_LOAD_ALL_FT_RULES ();
  630. DB.DBA.TTLP (
  631. cast ( DB.DBA.XML_URI_GET (
  632. 'http://www.openlinksw.com/sparql/virtrdf-data-formats.ttl', '' ) as varchar ),
  633. '', 'http://www.openlinksw.com/schemas/virtrdf#' );
  634. DB.DBA.TTLP ('
  635. @prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .
  636. @prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> .
  637. @prefix owl: <http://www.w3.org/2002/07/owl#> .
  638. @prefix xsd: <http://www.w3.org/2001/XMLSchema#> .
  639. @prefix virtrdf: <http://www.openlinksw.com/schemas/virtrdf#> .
  640. @prefix rdfdf: <http://www.openlinksw.com/virtrdf-data-formats#> .
  641. @prefix atom: <http://atomowl.org/ontologies/atomrdf#> .
  642. virtrdf:DefaultQuadStorage
  643. rdf:type virtrdf:QuadStorage ;
  644. virtrdf:qsUserMaps virtrdf:DefaultQuadStorage-UserMaps ;
  645. virtrdf:qsDefaultMap virtrdf:DefaultQuadMap ;
  646. virtrdf:qsMatchingFlags virtrdf:SPART_QS_NO_IMPLICIT_USER_QM .
  647. virtrdf:DefaultQuadStorage-UserMaps
  648. rdf:type virtrdf:array-of-QuadMap .
  649. virtrdf:DefaultServiceStorage
  650. rdf:type virtrdf:QuadStorage ;
  651. virtrdf:qsUserMaps virtrdf:DefaultServiceStorage-UserMaps ;
  652. virtrdf:qsDefaultMap virtrdf:DefaultServiceMap ;
  653. virtrdf:qsMatchingFlags virtrdf:SPART_QS_NO_IMPLICIT_USER_QM .
  654. virtrdf:DefaultServiceStorage-UserMaps
  655. rdf:type virtrdf:array-of-QuadMap .
  656. virtrdf:SyncToQuads
  657. rdf:type virtrdf:QuadStorage ;
  658. virtrdf:qsUserMaps virtrdf:SyncToQuads-UserMaps .
  659. virtrdf:SyncToQuads-UserMaps
  660. rdf:type virtrdf:array-of-QuadMap .
  661. ', '', 'http://www.openlinksw.com/schemas/virtrdf#' );
  662. delete from SYS_HTTP_SPONGE where HS_PARSER = 'DB.DBA.RDF_LOAD_HTTP_RESPONSE';
  663. commit work;
  664. sequence_set ('RDF_URL_IID_NAMED', 1010000, 1);
  665. sequence_set ('RDF_URL_IID_BLANK', iri_id_num (min_bnode_iri_id ()) + 10000, 1);
  666. sequence_set ('RDF_URL_IID_NAMED_BLANK', iri_id_num (min_named_bnode_iri_id ()) + 10000, 1);
  667. sequence_set ('RDF_PREF_SEQ', 101, 1);
  668. sequence_set ('RDF_RO_ID', 1001, 1);
  669. iri_id_cache_flush ();
  670. DB.DBA.SPARQL_RELOAD_QM_GRAPH ();
  671. __atomic (0);
  672. exec ('checkpoint');
  673. }
  674. ;
  675. -----
  676. -- Handling of IRI IDs
  677. create function DB.DBA.RDF_MAKE_IID_OF_QNAME (in qname varchar) returns IRI_ID
  678. {
  679. return iri_to_id (qname);
  680. }
  681. ;
  682. create function DB.DBA.RDF_MAKE_IID_OF_LONG (in qname any) returns IRI_ID -- DEPRECATED
  683. {
  684. if (isiri_id (qname))
  685. return qname;
  686. if (not isstring (qname))
  687. {
  688. if (__tag of rdf_box = __tag (qname) and rdf_box_is_complete (qname))
  689. qname := rdf_box_data (qname, 1);
  690. else
  691. qname := __rdf_strsqlval (qname);
  692. }
  693. return iri_to_id_nosignal (qname);
  694. }
  695. ;
  696. create function DB.DBA.RDF_MAKE_GRAPH_IIDS_OF_QNAMES (in qnames any) returns any
  697. {
  698. if (__tag of vector <> __tag (qnames))
  699. return vector ();
  700. declare res_acc any;
  701. vectorbld_init (res_acc);
  702. foreach (any qname in qnames) do
  703. {
  704. declare iid IRI_ID;
  705. whenever sqlstate '*' goto skip_acc;
  706. iid := iri_to_id (qname, 0, 0);
  707. if (not isinteger (iid))
  708. vectorbld_acc (res_acc, iid);
  709. skip_acc: ;
  710. }
  711. vectorbld_final (res_acc);
  712. return res_acc;
  713. }
  714. ;
  715. -----
  716. -- Datatypes and languages
  717. create function DB.DBA.RDF_TWOBYTE_OF_DATATYPE (in iid any) returns integer
  718. {
  719. declare res integer;
  720. declare qname varchar;
  721. if (iid is null)
  722. return 257;
  723. if (not isiri_id (iid))
  724. {
  725. declare new_iid IRI_ID;
  726. new_iid := iri_to_id (iid);
  727. if (new_iid is NULL or new_iid >= min_bnode_iri_id ())
  728. signal ('RDFXX', 'Invalid datatype IRI_ID passes as an argument to DB.DBA.RDF_TWOBYTE_OF_DATATYPE()');
  729. iid := new_iid;
  730. }
  731. qname := id_to_iri (iid);
  732. res := rdf_cache_id ('t', qname);
  733. if (res)
  734. return res;
  735. whenever not found goto mknew;
  736. set isolation='committed';
  737. select RDT_TWOBYTE into res from DB.DBA.RDF_DATATYPE where RDT_IID = iid;
  738. return res;
  739. mknew:
  740. set isolation='serializable';
  741. declare tb_cr cursor for select RDT_TWOBYTE from DB.DBA.RDF_DATATYPE where RDT_IID = iid;
  742. open tb_cr (exclusive);
  743. whenever not found goto mknew_ser;
  744. fetch tb_cr into res;
  745. return res;
  746. mknew_ser:
  747. res := sequence_next ('RDF_DATATYPE_TWOBYTE');
  748. if (0 = bit_and (res, 255))
  749. {
  750. if (res = 0hex7F00)
  751. {
  752. sequence_set ('RDF_DATATYPE_TWOBYTE', 0hex7F00, 0);
  753. res := 0hex7F01;
  754. qname := 'http://www.openlinksw.com/schemas/virtrdf#Unsaved';
  755. iid := iri_to_id (qname);
  756. insert soft DB.DBA.RDF_DATATYPE
  757. (RDT_IID, RDT_TWOBYTE, RDT_QNAME)
  758. values (iid, res, qname);
  759. goto cache_and_log;
  760. }
  761. res := sequence_next ('RDF_DATATYPE_TWOBYTE');
  762. }
  763. insert into DB.DBA.RDF_DATATYPE
  764. (RDT_IID, RDT_TWOBYTE, RDT_QNAME)
  765. values (iid, res, qname);
  766. cache_and_log:
  767. rdf_cache_id ('t', qname, res);
  768. log_text ('rdf_cache_id (\'t\', ?, ?)', qname, res); --'
  769. return res;
  770. }
  771. ;
  772. create function DB.DBA.RDF_PRESET_TWOBYTES_OF_DATATYPES ()
  773. {
  774. declare xsd_lnames any;
  775. xsd_lnames := vector (
  776. 'ENTITY',
  777. 'ENTITIES',
  778. 'ID',
  779. 'IDREF',
  780. 'IDREFS',
  781. 'NCName',
  782. 'Name',
  783. 'NMTOKEN',
  784. 'NMTOKENS',
  785. 'NOTATION',
  786. 'QName',
  787. 'any',
  788. 'anyAtomicType',
  789. 'anySimpleType',
  790. 'anyType',
  791. 'anyURI',
  792. 'base64Binary',
  793. 'boolean',
  794. 'byte',
  795. 'date',
  796. 'dateTime',
  797. 'dateTimeStamp',
  798. 'dayTimeDuration',
  799. 'decimal',
  800. 'double',
  801. 'duration',
  802. 'float',
  803. 'gDay',
  804. 'gMonth',
  805. 'gMonthDay',
  806. 'gYear',
  807. 'gYearMonth',
  808. 'hexBinary',
  809. 'int',
  810. 'integer',
  811. 'language',
  812. 'long',
  813. 'negativeInteger',
  814. 'nonNegativeInteger',
  815. 'nonPositiveInteger',
  816. 'normalizedString',
  817. 'positiveInteger',
  818. 'short',
  819. 'string',
  820. 'time',
  821. 'token',
  822. 'unsignedByte',
  823. 'unsignedInt',
  824. 'unsignedLong',
  825. 'unsignedShort',
  826. 'yearMonthDuration' );
  827. foreach (varchar n in xsd_lnames) do
  828. {
  829. __dbf_set ('rb_type__xsd:' || n, DB.DBA.RDF_TWOBYTE_OF_DATATYPE (iri_to_id ('http://www.w3.org/2001/XMLSchema#' || n)));
  830. }
  831. commit work;
  832. }
  833. ;
  834. DB.DBA.RDF_PRESET_TWOBYTES_OF_DATATYPES ()
  835. ;
  836. create function DB.DBA.RDF_TWOBYTE_OF_LANGUAGE (in id varchar) returns integer
  837. {
  838. declare res integer;
  839. if (id is null)
  840. return 257;
  841. id := lower (id);
  842. res := rdf_cache_id ('l', id);
  843. if (res)
  844. return res;
  845. whenever not found goto mknew;
  846. set isolation='committed';
  847. select RL_TWOBYTE into res from DB.DBA.RDF_LANGUAGE where RL_ID = id;
  848. return res;
  849. mknew:
  850. set isolation='serializable';
  851. declare tb_cr cursor for select RL_TWOBYTE from DB.DBA.RDF_LANGUAGE where RL_ID = id;
  852. open tb_cr (exclusive);
  853. whenever not found goto mknew_ser;
  854. fetch tb_cr into res;
  855. return res;
  856. mknew_ser:
  857. res := sequence_next ('RDF_LANGUAGE_TWOBYTE');
  858. if (0 = bit_and (res, 255))
  859. {
  860. if (res = 0hex7F00)
  861. {
  862. sequence_set ('RDF_LANGUAGE_TWOBYTE', 0hex7F00, 0);
  863. res := 0hex7F01;
  864. id := 'x-unsaved';
  865. insert soft DB.DBA.RDF_LANGUAGE (RL_ID, RL_TWOBYTE) values (id, res);
  866. goto cache_and_log;
  867. }
  868. res := sequence_next ('RDF_LANGUAGE_TWOBYTE');
  869. }
  870. insert into DB.DBA.RDF_LANGUAGE (RL_ID, RL_TWOBYTE) values (id, res);
  871. cache_and_log:
  872. rdf_cache_id ('l', id, res);
  873. log_text ('rdf_cache_id (\'l\', ?, ?)', id, res); --'
  874. return res;
  875. }
  876. ;
  877. -----
  878. -- Conversions from and to _table fields_ in short representation
  879. create function DB.DBA.RQ_LONG_OF_O (in o_col any) returns any -- DEPRECATED
  880. {
  881. return __rdf_long_of_obj (o_col);
  882. }
  883. ;
  884. create procedure DB.DBA.RDF_BOX_COMPLETE (inout o_col any) -- DEPRECATED
  885. {
  886. __rdf_box_make_complete (o_col);
  887. }
  888. ;
  889. create function DB.DBA.RQ_SQLVAL_OF_O (in o_col any) returns any -- DEPRECATED
  890. {
  891. return __rdf_sqlval_of_obj (o_col);
  892. }
  893. ;
  894. create function DB.DBA.RQ_BOOL_OF_O (in o_col any) returns any
  895. {
  896. declare t, len integer;
  897. if (isiri_id (o_col))
  898. return NULL;
  899. if (isinteger (o_col))
  900. {
  901. if (o_col)
  902. return 1;
  903. return 0;
  904. }
  905. if (__tag of rdf_box = __tag (o_col))
  906. {
  907. declare twobyte integer;
  908. declare dtqname any;
  909. if (__tag of varchar <> rdf_box_data_tag (o_col))
  910. {
  911. whenever sqlstate '*' goto retnull;
  912. return neq (rdf_box_data (o_col), 0.0);
  913. }
  914. twobyte := rdf_box_type (o_col);
  915. if (257 = twobyte)
  916. goto type_ok;
  917. whenever not found goto badtype;
  918. select RDT_QNAME into dtqname from DB.DBA.RDF_DATATYPE where RDT_TWOBYTE = twobyte;
  919. if (dtqname <> UNAME'http://www.w3.org/2001/XMLSchema#string')
  920. return null;
  921. type_ok:
  922. return case (length (rdf_box_data (o_col))) when 0 then 0 else 1 end;
  923. badtype:
  924. signal ('RDFXX', signal ('RDFXX', sprintf ('Unknown datatype in DB.DBA.RQ_BOOL_OF_O, bad type id %d, string value "%s"',
  925. twobyte, cast (rdf_box_data (o_col) as varchar) ) );
  926. }
  927. if (o_col is null)
  928. return null;
  929. whenever sqlstate '*' goto retnull;
  930. return neq (o_col, 0.0);
  931. retnull:
  932. return null;
  933. }
  934. ;
  935. create function DB.DBA.RQ_IID_OF_O (in shortobj any) returns IRI_ID -- DEPRECATED
  936. {
  937. return id_to_iri_nosignal (shortobj);
  938. }
  939. ;
  940. create function DB.DBA.RQ_O_IS_LIT (in shortobj any) returns integer -- DEPRECATED
  941. {
  942. if (isiri_id (shortobj))
  943. return 0;
  944. return 1;
  945. }
  946. ;
  947. -----
  948. -- Conversions from and to values in short representation that may be not field values (may perform more validation checks)
  949. create procedure RDF_G_INS (in id int, in g any)
  950. {
  951. geo_insert ('DB.DBA.RDF_GEO', g, id);
  952. }
  953. ;
  954. create procedure cl_rdf_geo_insert (in id int, inout g any)
  955. {
  956. declare daq any;
  957. daq := daq (1);
  958. daq_call (daq, 'DB.DBA.RDF_OBJ', 'RDF_OBJ', 'DB.DBA.RDF_G_INS', vector (id, g), 1);
  959. daq_results (daq);
  960. }
  961. ;
  962. create function rdf_geo_add (in v any)
  963. {
  964. declare id, h, ser, g any;
  965. if (rdf_box_ro_id (v))
  966. return v;
  967. g := rdf_box_data (v);
  968. if (not isgeometry (g))
  969. signal ('22023', 'RDFXX', 'Must be geometry box if to be stored as geo object');
  970. ser := serialize (g);
  971. if (length (ser) > 50)
  972. h := mdigest5 (ser);
  973. else
  974. {
  975. h := ser;
  976. ser := null;
  977. }
  978. set isolation = 'committed';
  979. id := (select ro_id, ro_val, ro_long from rdf_obj where ro_val = h and ro_dt_and_lang = 0hex1000101 and case when ro_long is not null then equ (blob_to_string (ro_long), ser) else 1 end );
  980. if (id is not null)
  981. {
  982. rdf_box_set_ro_id (v, id);
  983. return v;
  984. }
  985. set isolation = 'serializable';
  986. id := (select ro_id, ro_val, ro_long from rdf_obj where ro_val = h and ro_dt_and_lang = 0hex1000101 and case when ro_long is not null then equ (blob_to_string (ro_long), ser) else 1 end for update);
  987. if (id is not null)
  988. {
  989. rdf_box_set_ro_id (v, id);
  990. return v;
  991. }
  992. id := sequence_next ('RDF_RO_ID');
  993. set triggers off;
  994. -- dbg_obj_princ ('zero RO_FLAGS in sparql.sql:997 ', ro_val, ro_long);
  995. insert into rdf_obj (ro_id, ro_val, ro_long, ro_dt_and_lang)
  996. values (id, h, ser, 0hex1000101);
  997. if (1 = sys_stat ('cl_run_local_only'))
  998. geo_insert ('DB.DBA.RDF_GEO', g, id);
  999. else
  1000. cl_rdf_geo_insert (id, g);
  1001. rdf_box_set_ro_id (v, id);
  1002. return v;
  1003. }
  1004. ;
  1005. create function rdf_geo_set_id (inout v any)
  1006. {
  1007. declare id, h, ser, g any;
  1008. if (rdf_box_ro_id (v))
  1009. return v;
  1010. g := rdf_box_data (v);
  1011. if (not isgeometry (g))
  1012. signal ('22023', 'RDFXX', 'Must be geometry box if to be stored as geo object');
  1013. ser := serialize (g);
  1014. if (length (ser) > 50)
  1015. h := mdigest5 (ser);
  1016. else
  1017. {
  1018. h := ser;
  1019. ser := null;
  1020. }
  1021. set isolation = 'committed';
  1022. id := (select RO_ID from RDF_OBJ where RO_VAL = h and RO_DT_AND_LANG = 0hex1000101
  1023. and case when RO_LONG is not null then equ (blob_to_string (RO_LONG), ser) else 1 end );
  1024. if (id is not null)
  1025. {
  1026. rdf_box_set_ro_id (v, id);
  1027. return v;
  1028. }
  1029. return null;
  1030. }
  1031. ;
  1032. create function DB.DBA.RDF_OBJ_ADD (in dt_twobyte integeR, in v varchar, in lang_twobyte integeR, in ro_id_dict any := 0) returns varchar
  1033. {
  1034. declare llong, id, need_digest integer;
  1035. declare digest any;
  1036. declare old_flags, dt_and_lang integer;
  1037. -- dbg_obj_princ ('DB.DBA.RDF_OBJ_ADD (', dt_twobyte, v, lang_twobyte, case (isnull (ro_id_dict)) when 1 then '/*no_ft*/' else '/*want_ft*/' end,')');
  1038. if (isinteger (ro_id_dict))
  1039. {
  1040. if (__rdf_obj_ft_rule_check (null, null))
  1041. ro_id_dict := dict_new ();
  1042. else
  1043. ro_id_dict := null;
  1044. }
  1045. if (126 = __tag (v))
  1046. v := blob_to_string (v);
  1047. if (isstring (rdf_box_data (v)))
  1048. need_digest := rdf_box_needs_digest (v, ro_id_dict);
  1049. else if (__tag of XML = __tag (v))
  1050. need_digest := 1;
  1051. if (__tag of rdf_box = __tag (v))
  1052. {
  1053. if (256 = rdf_box_type (v))
  1054. return rdf_geo_add (v);
  1055. if (0 = need_digest)
  1056. return v;
  1057. if (1 = need_digest)
  1058. {
  1059. if (0 <> rdf_box_ro_id (v))
  1060. return v;
  1061. }
  1062. dt_twobyte := rdf_box_type (v);
  1063. lang_twobyte := rdf_box_lang (v);
  1064. v := __rdf_sqlval_of_obj (v, 1);
  1065. }
  1066. else
  1067. {
  1068. if (dt_twobyte <> 257 or lang_twobyte <> 257)
  1069. need_digest := 3;
  1070. else if (0 = need_digest)
  1071. return v;
  1072. if (dt_twobyte < 257)
  1073. signal ('RDFXX', sprintf ('Bad datatype code: DB.DBA.RDF_OBJ_ADD (%d, %s, %d)',
  1074. dt_twobyte, "LEFT" (cast (v as varchar), 100), lang_twobyte) );
  1075. if (lang_twobyte < 257)
  1076. signal ('RDFXX', sprintf ('Bad lang code: DB.DBA.RDF_OBJ_ADD (%d, %s, %d)',
  1077. dt_twobyte, "LEFT" (cast (v as varchar), 100), lang_twobyte) );
  1078. }
  1079. dt_and_lang := bit_or (bit_shift (dt_twobyte, 16), lang_twobyte);
  1080. if (not isstring (v))
  1081. {
  1082. declare sum64 varchar;
  1083. if (__tag of XML <> __tag (v))
  1084. signal ('RDFXX', sprintf ('Bad call: DB.DBA.RDF_OBJ_ADD (%d, %s, %d)',
  1085. dt_twobyte, "LEFT" (cast (v as varchar), 100), lang_twobyte) );
  1086. sum64 := xtree_sum64 (v);
  1087. whenever not found goto serializable_xtree;
  1088. set isolation='committed';
  1089. select RO_ID, RO_FLAGS into id, old_flags
  1090. from DB.DBA.RDF_OBJ table option (index RO_VAL)
  1091. where RO_VAL = sum64
  1092. and RO_DT_AND_LANG = dt_and_lang
  1093. and bit_and (RO_FLAGS, 2);
  1094. --!TBD ... and paranoid check
  1095. goto found_xtree;
  1096. serializable_xtree:
  1097. whenever not found goto new_xtree;
  1098. set isolation='serializable';
  1099. declare id_cr cursor for
  1100. select RO_ID, RO_FLAGS from DB.DBA.RDF_OBJ table option (index RO_VAL) where RO_VAL = sum64
  1101. and RO_DT_AND_LANG = dt_and_lang
  1102. and bit_and (RO_FLAGS, 2);
  1103. --!TBD ... and paranoid check
  1104. open id_cr (exclusive);
  1105. fetch id_cr into id, old_flags;
  1106. found_xtree:
  1107. digest := rdf_box (v, dt_twobyte, lang_twobyte, id, 1);
  1108. if (ro_id_dict is not null)
  1109. {
  1110. if (not (bit_and (old_flags, 1)))
  1111. {
  1112. update DB.DBA.RDF_OBJ set RO_FLAGS = bit_or (RO_FLAGS, 1) where RO_ID = id;
  1113. --insert soft rdf_ft (rf_id, rf_o) values (id, digest);
  1114. }
  1115. dict_put (ro_id_dict, id, 1);
  1116. }
  1117. if (not (rdf_box_is_storeable (digest)))
  1118. signal ('RDFX2', 'DB.DBA.RDF_OBJ_ADD() tries to return bad digest');
  1119. return digest;
  1120. -- goto recheck;
  1121. new_xtree:
  1122. id := sequence_next ('RDF_RO_ID');
  1123. digest := rdf_box (v, dt_twobyte, lang_twobyte, id, 1);
  1124. -- if (ro_id_dict is null)
  1125. -- {
  1126. -- dbg_obj_princ ('zero RO_FLAGS in sparql.sql:1124');
  1127. -- ;
  1128. -- }
  1129. insert into DB.DBA.RDF_OBJ (RO_ID, RO_VAL, RO_LONG, RO_FLAGS, RO_DT_AND_LANG) values
  1130. (id, sum64, __xml_serialize_packed (v), case (isnull (ro_id_dict)) when 0 then 3 else 2 end, dt_and_lang);
  1131. --if (ro_id_dict is not null)
  1132. --insert soft rdf_ft (rf_id, rf_o) values (id, digest);
  1133. if (ro_id_dict is not null)
  1134. dict_put (ro_id_dict, id, 1);
  1135. if (not (rdf_box_is_storeable (digest)))
  1136. signal ('RDFX3', 'DB.DBA.RDF_OBJ_ADD() tries to return bad digest');
  1137. return digest;
  1138. -- old_digest := null;
  1139. -- goto recheck;
  1140. }
  1141. if ((dt_twobyte = 257) and (lang_twobyte = 257) and (length (v) <= -1))
  1142. {
  1143. if (1 >= need_digest)
  1144. return v;
  1145. whenever not found goto serializable_veryshort;
  1146. set isolation='committed';
  1147. select RO_ID into id
  1148. from DB.DBA.RDF_OBJ table option (index RO_VAL)
  1149. where RO_VAL = v and RO_DT_AND_LANG = dt_and_lang and not (bit_and (RO_FLAGS, 2));
  1150. goto found_veryshort;
  1151. serializable_veryshort:
  1152. whenever not found goto new_veryshort;
  1153. set isolation='serializable';
  1154. declare id_cr cursor for select RO_ID
  1155. from DB.DBA.RDF_OBJ table option (index RO_VAL)
  1156. where RO_VAL = v and RO_DT_AND_LANG = dt_and_lang and not (bit_and (RO_FLAGS, 2));
  1157. open id_cr (exclusive);
  1158. fetch id_cr into id;
  1159. found_veryshort:
  1160. if (ro_id_dict is not null)
  1161. {
  1162. dict_put (ro_id_dict, id, 1);
  1163. --insert soft rdf_ft (rf_id, rf_o) values (id, v);
  1164. }
  1165. if (not (rdf_box_is_storeable (v)))
  1166. signal ('RDFX4', 'DB.DBA.RDF_OBJ_ADD() tries to return bad digest');
  1167. return v;
  1168. new_veryshort:
  1169. id := sequence_next ('RDF_RO_ID');
  1170. insert into DB.DBA.RDF_OBJ (RO_ID, RO_VAL, RO_FLAGS, RO_DT_AND_LANG) values (id, v, 1, dt_and_lang);
  1171. if (ro_id_dict is not null)
  1172. {
  1173. dict_put (ro_id_dict, id, 1);
  1174. }
  1175. insert into DB.DBA.RO_START (RS_START, RS_DT_AND_LANG, RS_RO_ID)
  1176. values (subseq (v, 0, case when length (v) > 10 then 10 else length (v) end), dt_and_lang, rdf_box (0, 257, 257, id, 0));
  1177. if (not (rdf_box_is_storeable (v)))
  1178. signal ('RDFX5', 'DB.DBA.RDF_OBJ_ADD() tries to return bad digest');
  1179. return v;
  1180. }
  1181. llong := 50;
  1182. if (length (v) > llong)
  1183. {
  1184. declare chksm varchar;
  1185. chksm := mdigest5 (v, 1);
  1186. whenever not found goto serializable_long;
  1187. set isolation='committed';
  1188. select RO_ID, RO_FLAGS into id, old_flags
  1189. from DB.DBA.RDF_OBJ table option (index RO_VAL)
  1190. where RO_VAL = chksm
  1191. and RO_DT_AND_LANG = dt_and_lang
  1192. and not (bit_and (RO_FLAGS, 2))
  1193. and blob_to_string (RO_LONG) = v;
  1194. goto found_long;
  1195. serializable_long:
  1196. whenever not found goto new_long;
  1197. set isolation='serializable';
  1198. declare id_cr cursor for
  1199. select RO_ID, RO_FLAGS from DB.DBA.RDF_OBJ
  1200. table option (index RO_VAL) where RO_VAL = chksm
  1201. and RO_DT_AND_LANG = dt_and_lang
  1202. and not (bit_and (RO_FLAGS, 2))
  1203. and blob_to_string (RO_LONG) = v;
  1204. open id_cr (exclusive);
  1205. fetch id_cr into id, old_flags;
  1206. found_long:
  1207. digest := rdf_box (v, dt_twobyte, lang_twobyte, id, 1);
  1208. if ((not (bit_and (old_flags, 1))) and (1 < need_digest))
  1209. update DB.DBA.RDF_OBJ set RO_FLAGS = bit_or (RO_FLAGS, 1) where RO_ID = id;
  1210. if (ro_id_dict is not null)
  1211. {
  1212. dict_put (ro_id_dict, id, 1);
  1213. }
  1214. if (not (rdf_box_is_storeable (digest)))
  1215. signal ('RDFX6', 'DB.DBA.RDF_OBJ_ADD() tries to return bad digest');
  1216. return digest;
  1217. new_long:
  1218. id := sequence_next ('RDF_RO_ID');
  1219. digest := rdf_box (v, dt_twobyte, lang_twobyte, id, 1);
  1220. if (1 < need_digest)
  1221. insert into DB.DBA.RDF_OBJ (RO_ID, RO_VAL, RO_LONG, RO_FLAGS, RO_DT_AND_LANG)
  1222. values (id, chksm, v, 1, dt_and_lang);
  1223. else
  1224. {
  1225. set triggers off;
  1226. -- dbg_obj_princ ('zero RO_FLAGS in sparql.sql:1225 ', chksm, v);
  1227. insert into DB.DBA.RDF_OBJ (RO_ID, RO_VAL, RO_LONG, RO_DT_AND_LANG)
  1228. values (id, chksm, v, dt_and_lang);
  1229. set triggers on;
  1230. }
  1231. if (ro_id_dict is not null)
  1232. {
  1233. dict_put (ro_id_dict, id, 1);
  1234. }
  1235. insert into DB.DBA.RO_START (RS_START, RS_DT_AND_LANG, RS_RO_ID)
  1236. -- no need in values (subseq (v, 0, case when length (v) > 10 then 10 else length (v), RO_DT_AND_LANG, rdf_box (0, 257, 257, id, 0));
  1237. values (subseq (v, 0, 10), dt_and_lang, rdf_box (0, 257, 257, id, 0));
  1238. if (not (rdf_box_is_storeable (digest)))
  1239. signal ('RDFX7', 'DB.DBA.RDF_OBJ_ADD() tries to return bad digest');
  1240. return digest;
  1241. }
  1242. else
  1243. {
  1244. whenever not found goto serializable_short;
  1245. set isolation='committed';
  1246. select RO_ID, RO_FLAGS into id, old_flags
  1247. from DB.DBA.RDF_OBJ table option (index RO_VAL)
  1248. where RO_VAL = v
  1249. and RO_DT_AND_LANG = dt_and_lang;
  1250. goto found_short;
  1251. serializable_short:
  1252. whenever not found goto new_short;
  1253. set isolation='serializable';
  1254. declare id_cr cursor for select RO_ID, RO_FLAGS
  1255. from DB.DBA.RDF_OBJ table option (index RO_VAL)
  1256. where RO_VAL = v
  1257. and RO_DT_AND_LANG = dt_and_lang;
  1258. open id_cr (exclusive);
  1259. fetch id_cr into id, old_flags;
  1260. found_short:
  1261. digest := rdf_box (v, dt_twobyte, lang_twobyte, id, 1);
  1262. if ((not (bit_and (old_flags, 1))) and (1 < need_digest))
  1263. update DB.DBA.RDF_OBJ set RO_FLAGS = bit_or (RO_FLAGS, 1) where RO_ID = id;
  1264. if (ro_id_dict is not null)
  1265. {
  1266. dict_put (ro_id_dict, id, 1);
  1267. }
  1268. if (not (rdf_box_is_storeable (digest)))
  1269. signal ('RDFX8', 'DB.DBA.RDF_OBJ_ADD() tries to return bad digest');
  1270. return digest;
  1271. new_short:
  1272. id := sequence_next ('RDF_RO_ID');
  1273. digest := rdf_box (v, dt_twobyte, lang_twobyte, id, 1);
  1274. if (1 < need_digest)
  1275. insert into DB.DBA.RDF_OBJ (RO_ID, RO_VAL, RO_FLAGS, RO_DT_AND_LANG)
  1276. values (id, v, 1, dt_and_lang);
  1277. else
  1278. {
  1279. -- dbg_obj_princ ('zero RO_FLAGS in sparql.sql:1271 ', v);
  1280. set triggers off;
  1281. insert into DB.DBA.RDF_OBJ (RO_ID, RO_VAL, RO_FLAGS, RO_DT_AND_LANG)
  1282. values (id, v, 0, dt_and_lang);
  1283. set triggers on;
  1284. }
  1285. insert into DB.DBA.RO_START (RS_START, RS_DT_AND_LANG, RS_RO_ID)
  1286. values (subseq (v, 0, case when length (v) > 10 then 10 else length (v) end), dt_and_lang, rdf_box (0, 257, 257, id, 0));
  1287. if (ro_id_dict is not null)
  1288. {
  1289. dict_put (ro_id_dict, id, 1);
  1290. }
  1291. if (not (rdf_box_is_storeable (digest)))
  1292. signal ('RDFX9', 'DB.DBA.RDF_OBJ_ADD() tries to return bad digest');
  1293. return digest;
  1294. }
  1295. recheck:
  1296. -- dbg_obj_princ ('recheck: id=', id, ', old_digest=', old_digest, ', need_digest=', need_digest, ', digest=', digest);
  1297. signal ('FUNNY', 'Debug code of DB.DBA.RDF_OBJ_ADD() is reached. This can not happen (I believe). Please report this error.');
  1298. }
  1299. ;
  1300. create function DB.DBA.RDF_FIND_RO_DIGEST (in dt_twobyte integeR, in v varchar, in lang_twobyte integeR) returns varchar
  1301. {
  1302. declare llong, dt_and_lang int;
  1303. declare dt_s, lang_s, chksm, sum64 varchar;
  1304. declare digest, old_digest any;
  1305. if (126 = __tag (v))
  1306. v := blob_to_string (v);
  1307. dt_and_lang := bit_or (bit_shift (dt_twobyte, 16), lang_twobyte);
  1308. if (not (isstring (v)))
  1309. {
  1310. if (__tag of XML <> __tag (v))
  1311. return v;
  1312. sum64 := xtree_sum64 (v);
  1313. return (select rdf_box (v, dt_twobyte, lang_twobyte, RO_ID, 1)
  1314. from DB.DBA.RDF_OBJ table option (index RO_VAL)
  1315. where RO_VAL = sum64
  1316. and RO_DT_AND_LANG = dt_and_lang
  1317. and bit_and (RO_FLAGS, 2)
  1318. --!TBD ... and paranoid check
  1319. );
  1320. }
  1321. if ((dt_twobyte = 257) and (lang_twobyte = 257) and (length (v) <= 20))
  1322. return v;
  1323. llong := 50;
  1324. if (length (v) > llong)
  1325. {
  1326. chksm := mdigest5 (v, 1);
  1327. return (select rdf_box (v, dt_twobyte, lang_twobyte, RO_ID, 1)
  1328. from DB.DBA.RDF_OBJ table option (index RO_VAL)
  1329. where RO_VAL = chksm
  1330. and RO_DT_AND_LANG = dt_and_lang
  1331. and not (bit_and (RO_FLAGS, 2))
  1332. and blob_to_string (RO_LONG) = v );
  1333. }
  1334. else
  1335. {
  1336. return (select rdf_box (v, dt_twobyte, lang_twobyte, RO_ID, 1)
  1337. from DB.DBA.RDF_OBJ table option (index RO_VAL)
  1338. where RO_VAL = v
  1339. and RO_DT_AND_LANG = dt_and_lang
  1340. and not (bit_and (RO_FLAGS, 2)) );
  1341. }
  1342. }
  1343. ;
  1344. create function DB.DBA.RDF_MAKE_OBJ_OF_SQLVAL (in v any) returns any array
  1345. {
  1346. declare t int;
  1347. t := __tag (v);
  1348. if (not (t in (126, __tag of varchar, 217, __tag of nvarchar, __tag of XML, __tag of rdf_box)))
  1349. return v;
  1350. if (__tag of nvarchar = t)
  1351. v := charset_recode (v, '_WIDE_', 'UTF-8');
  1352. else if (t in (126, 217))
  1353. v := cast (v as varchar);
  1354. return DB.DBA.RDF_OBJ_ADD (257, v, 257);
  1355. }
  1356. ;
  1357. create function DB.DBA.RDF_MAKE_OBJ_OF_SQLVAL_FT (in v any, in g_iid IRI_ID, in p_iid IRI_ID, in ro_id_dict any := null) returns any
  1358. {
  1359. declare t int;
  1360. -- dbg_obj_princ ('DB.DBA.RDF_MAKE_OBJ_OF_SQLVAL_FT (', v, g_iid, p_iid, ro_id_dict, ')');
  1361. t := __tag (v);
  1362. if (not (t in (126, __tag of varchar, 217, __tag of nvarchar, __tag of XML, __tag of rdf_box)))
  1363. return v;
  1364. if (__tag of nvarchar = t)
  1365. v := charset_recode (v, '_WIDE_', 'UTF-8');
  1366. else if (t in (126, 217))
  1367. v := cast (v as varchar);
  1368. if (not __rdf_obj_ft_rule_check (g_iid, p_iid))
  1369. ro_id_dict := null;
  1370. else
  1371. {
  1372. if (ro_id_dict is null)
  1373. {
  1374. declare res any;
  1375. ro_id_dict := dict_new ();
  1376. res := DB.DBA.RDF_OBJ_ADD (257, v, 257, ro_id_dict);
  1377. DB.DBA.RDF_OBJ_ADD_KEYWORD_FOR_GRAPH (g_iid, ro_id_dict);
  1378. return res;
  1379. }
  1380. }
  1381. return DB.DBA.RDF_OBJ_ADD (257, v, 257, ro_id_dict);
  1382. }
  1383. ;
  1384. create function DB.DBA.RDF_MAKE_OBJ_OF_TYPEDSQLVAL (in v any, in dt_iid IRI_ID, in lang varchar) returns any array
  1385. {
  1386. declare t, dt_twobyte, lang_twobyte int;
  1387. -- dbg_obj_princ ('DB.DBA.RDF_MAKE_OBJ_OF_TYPEDSQLVAL (', v, dt_iid, lang, ')');
  1388. retry_unrdf:
  1389. t := __tag (v);
  1390. if (not (t in (126, __tag of varchar, 217, __tag of nvarchar, __tag of XML)))
  1391. {
  1392. if (__tag of rdf_box = t)
  1393. {
  1394. v := rdf_box_data (v);
  1395. goto retry_unrdf;
  1396. }
  1397. -- dbg_obj_princ ('DB.DBA.RDF_MAKE_OBJ_OF_TYPEDSQLVAL() should accept only string representations of typed values, real arguments are ', v, dt_iid, lang);
  1398. return v;
  1399. }
  1400. if (__tag of nvarchar = t)
  1401. v := charset_recode (v, '_WIDE_', 'UTF-8');
  1402. else if (217 = t or 126 = t)
  1403. v := cast (v as varchar);
  1404. if (dt_iid is not null)
  1405. dt_twobyte := DB.DBA.RDF_TWOBYTE_OF_DATATYPE (dt_iid);
  1406. else
  1407. dt_twobyte := 257;
  1408. if (lang is not null)
  1409. lang_twobyte := DB.DBA.RDF_TWOBYTE_OF_LANGUAGE (lang);
  1410. else
  1411. lang_twobyte := 257;
  1412. -- dbg_obj_princ ('DB.DBA.RDF_MAKE_OBJ_OF_TYPEDSQLVAL (', v, dt_iid, lang, ') calls DB.DBA.RDF_OBJ_ADD (', dt_twobyte, v, lang_twobyte, ')');
  1413. return DB.DBA.RDF_OBJ_ADD (dt_twobyte, v, lang_twobyte);
  1414. }
  1415. ;
  1416. create function DB.DBA.RDF_MAKE_OBJ_OF_TYPEDSQLVAL_FT (in v any, in dt_iid IRI_ID, in lang varchar, in g_iid IRI_ID, in p_iid IRI_ID, in ro_id_dict any := null) returns any array
  1417. {
  1418. declare t, dt_twobyte, lang_twobyte int;
  1419. -- dbg_obj_princ ('DB.DBA.RDF_MAKE_OBJ_OF_TYPEDSQLVAL_FT (', v, dt_iid, lang, g_iid, p_iid, ro_id_dict, ')');
  1420. retry_unrdf:
  1421. t := __tag (v);
  1422. if (not (t in (126, __tag of varchar, 217, __tag of nvarchar, __tag of XML)))
  1423. {
  1424. if (__tag of rdf_box = t)
  1425. {
  1426. v := rdf_box_data (v);
  1427. goto retry_unrdf;
  1428. }
  1429. -- dbg_obj_princ ('DB.DBA.RDF_MAKE_OBJ_OF_TYPEDSQLVAL_FT() should accept only string representations of typed values, real arguments are ', v, dt_iid, lang, g_iid, p_iid);
  1430. return v;
  1431. }
  1432. if (__tag of nvarchar = t)
  1433. v := charset_recode (v, '_WIDE_', 'UTF-8');
  1434. else if (217 = t or 126 = t)
  1435. v := cast (v as varchar);
  1436. if (dt_iid is not null)
  1437. dt_twobyte := DB.DBA.RDF_TWOBYTE_OF_DATATYPE (dt_iid);
  1438. else
  1439. dt_twobyte := 257;
  1440. if (lang is not null)
  1441. lang_twobyte := DB.DBA.RDF_TWOBYTE_OF_LANGUAGE (lang);
  1442. else
  1443. lang_twobyte := 257;
  1444. if (not __rdf_obj_ft_rule_check (g_iid, p_iid))
  1445. ro_id_dict := null;
  1446. else
  1447. {
  1448. if (ro_id_dict is null)
  1449. {
  1450. declare res any;
  1451. ro_id_dict := dict_new ();
  1452. res := DB.DBA.RDF_OBJ_ADD (dt_twobyte, v, lang_twobyte, ro_id_dict);
  1453. DB.DBA.RDF_OBJ_ADD_KEYWORD_FOR_GRAPH (g_iid, ro_id_dict);
  1454. return res;
  1455. }
  1456. }
  1457. return DB.DBA.RDF_OBJ_ADD (dt_twobyte, v, lang_twobyte, ro_id_dict);
  1458. }
  1459. ;
  1460. create function DB.DBA.RDF_MAKE_OBJ_OF_TYPEDSQLVAL_STRINGS (
  1461. in o_val any, in o_type varchar, in o_lang varchar ) returns any array
  1462. {
  1463. -- dbg_obj_princ ('DB.DBA.RDF_MAKE_OBJ_OF_TYPEDSQLVAL_STRINGS (', o_val, o_type, o_lang, ')');
  1464. if (__tag (o_type) in (__tag of varchar, 217))
  1465. {
  1466. declare parsed any;
  1467. parsed := __xqf_str_parse_to_rdf_box (o_val, o_type, isstring (o_val));
  1468. if (parsed is not null)
  1469. {
  1470. if (__tag of XML = __tag (parsed))
  1471. {
  1472. return DB.DBA.RDF_MAKE_OBJ_OF_TYPEDSQLVAL (
  1473. parsed, iri_to_id (o_type), null );
  1474. }
  1475. if (__tag of rdf_box = __tag (parsed))
  1476. {
  1477. if (256 = rdf_box_type (parsed))
  1478. db..rdf_geo_add (parsed);
  1479. else
  1480. rdf_box_set_type (parsed,
  1481. DB.DBA.RDF_TWOBYTE_OF_DATATYPE (iri_to_id (o_type)));
  1482. parsed := DB.DBA.RDF_OBJ_ADD (257, parsed, 257, null);
  1483. }
  1484. return parsed;
  1485. }
  1486. return DB.DBA.RDF_MAKE_OBJ_OF_TYPEDSQLVAL (
  1487. o_val,
  1488. iri_to_id (o_type),
  1489. o_lang );
  1490. }
  1491. if (isstring (o_lang))
  1492. {
  1493. return DB.DBA.RDF_MAKE_OBJ_OF_TYPEDSQLVAL (
  1494. o_val, NULL, o_lang );
  1495. }
  1496. return DB.DBA.RDF_MAKE_OBJ_OF_SQLVAL (o_val);
  1497. }
  1498. ;
  1499. create function DB.DBA.RDF_LONG_OF_OBJ (in shortobj any) returns any -- DEPRECATED
  1500. {
  1501. return __rdf_long_of_obj (shortobj);
  1502. }
  1503. ;
  1504. create function DB.DBA.RDF_DATATYPE_OF_OBJ (in shortobj any, in dflt varchar := UNAME'http://www.w3.org/2001/XMLSchema#string') returns any
  1505. {
  1506. declare twobyte integer;
  1507. declare res any;
  1508. if (__tag of rdf_box <> __tag (shortobj))
  1509. {
  1510. if (isiri_id (shortobj))
  1511. return null;
  1512. if (isstring (shortobj) and bit_and (__box_flags (shortobj), 1))
  1513. return null;
  1514. -- dbg_obj_princ ('DB.DBA.RDF_DATATYPE_OF_OBJ (', shortobj, ') will return ', __xsd_type (shortobj, dflt), ' for non-rdfbox');
  1515. return __xsd_type (shortobj, dflt);
  1516. }
  1517. twobyte := rdf_box_type (shortobj);
  1518. -- dbg_obj_princ ('DB.DBA.RDF_DATATYPE_OF_OBJ (', shortobj, ') found twobyte ', twobyte);
  1519. if (257 = twobyte)
  1520. return case (rdf_box_lang (shortobj)) when 257 then __uname (dflt) else null end;
  1521. whenever not found goto badtype;
  1522. select __uname (RDT_QNAME) into res from DB.DBA.RDF_DATATYPE where RDT_TWOBYTE = twobyte;
  1523. return res;
  1524. badtype:
  1525. signal ('RDFXX', sprintf ('Unknown datatype in DB.DBA.RQ_DATATYPE_OF_OBJ, bad type id %d, string value "%s"',
  1526. twobyte, cast (rdf_box_data (shortobj) as varchar) ) );
  1527. }
  1528. ;
  1529. create function DB.DBA.RDF_LANGUAGE_OF_OBJ (in shortobj any array, in dflt varchar := '') returns any
  1530. {
  1531. vectored;
  1532. declare twobyte integer;
  1533. declare res varchar;
  1534. if (__tag of rdf_box <> __tag (shortobj))
  1535. {
  1536. if (isiri_id (shortobj))
  1537. return null;
  1538. if (isstring (shortobj) and bit_and (__box_flags (shortobj), 1))
  1539. return null;
  1540. -- dbg_obj_princ ('DB.DBA.RDF_LANGUAGE_OF_OBJ (', shortobj, ') got a non-rdfbox');
  1541. return dflt;
  1542. }
  1543. twobyte := rdf_box_lang (shortobj);
  1544. -- dbg_obj_princ ('DB.DBA.RDF_LANGUAGE_OF_OBJ (', shortobj, ') found twobyte ', twobyte);
  1545. if (257 = twobyte)
  1546. return dflt;
  1547. return coalesce ((select lower (RL_ID) from DB.DBA.RDF_LANGUAGE where RL_TWOBYTE = twobyte),
  1548. signal ('RDFXX', sprintf ('Unknown language in DB.DBA.RDF_LANGUAGE_OF_OBJ, bad string "%s"', cast (shortobj as varchar))));
  1549. }
  1550. ;
  1551. create function DB.DBA.RDF_SQLVAL_OF_OBJ (in shortobj any) returns any -- DEPRECATED
  1552. {
  1553. return __rdf_sqlval_of_obj (shortobj);
  1554. }
  1555. ;
  1556. create function DB.DBA.RDF_BOOL_OF_OBJ (in shortobj any) returns any
  1557. {
  1558. if (isiri_id (shortobj))
  1559. return null;
  1560. if (isinteger (shortobj))
  1561. {
  1562. if (shortobj)
  1563. return 1;
  1564. return 0;
  1565. }
  1566. if (__tag of rdf_box <> __tag (shortobj))
  1567. {
  1568. if (shortobj is null)
  1569. return null;
  1570. if (equ (shortobj, 0.0) or equ (shortobj, '')) return 0; else return 1;
  1571. }
  1572. declare twobyte integer;
  1573. twobyte := rdf_box_type (shortobj);
  1574. if (257 = twobyte)
  1575. goto type_ok;
  1576. declare dtqname varchar;
  1577. whenever not found goto badtype;
  1578. select RDT_QNAME into dtqname from DB.DBA.RDF_DATATYPE where RDT_TWOBYTE = twobyte;
  1579. if (dtqname <> UNAME'http://www.w3.org/2001/XMLSchema#string')
  1580. return null;
  1581. type_ok:
  1582. return case length (rdf_box_data (shortobj)) when 0 then 0 else 1 end;
  1583. badtype:
  1584. signal ('RDFXX', sprintf ('Unknown datatype in DB.DBA.RDF_BOOL_OF_OBJ, bad type id %d, string value "%s"',
  1585. twobyte, cast (rdf_box_data (shortobj) as varchar) ) );
  1586. }
  1587. ;
  1588. create function DB.DBA.RDF_QNAME_OF_OBJ (in shortobj any) returns varchar -- DEPRECATED
  1589. {
  1590. return id_to_iri_nosignal (shortobj);
  1591. }
  1592. ;
  1593. create function DB.DBA.RDF_STRSQLVAL_OF_OBJ (in shortobj any) -- DEPRECATED
  1594. {
  1595. return __rdf_strsqlval (shortobj, 0);
  1596. }
  1597. ;
  1598. create function DB.DBA.RDF_OBJ_OF_LONG (in longobj any) returns any
  1599. {
  1600. declare t int;
  1601. t := __tag (longobj);
  1602. if (__tag of rdf_box <> t)
  1603. {
  1604. if (not (t in (__tag of varchar, 126, 217, __tag of nvarchar, 133, 226)))
  1605. return longobj;
  1606. if (t = 133)
  1607. {
  1608. longobj := cast (longobj as nvarchar);
  1609. t := __tag (longobj);
  1610. }
  1611. if (__tag of nvarchar = t or t = 226)
  1612. longobj := charset_recode (longobj, '_WIDE_', 'UTF-8');
  1613. else if (t in (126, 217))
  1614. longobj := cast (longobj as varchar);
  1615. else if (bit_and (1, __box_flags (longobj)))
  1616. return iri_to_id (longobj);
  1617. return DB.DBA.RDF_OBJ_ADD (257, longobj, 257);
  1618. }
  1619. if (0 = rdf_box_needs_digest (longobj))
  1620. return longobj;
  1621. return DB.DBA.RDF_OBJ_ADD (257, longobj, 257);
  1622. }
  1623. ;
  1624. create function DB.DBA.RDF_OBJ_OF_SQLVAL (in v any) returns any array
  1625. {
  1626. declare t int;
  1627. t := __tag (v);
  1628. if (not (t in (__tag of varchar, 126, 217, __tag of nvarchar)))
  1629. {
  1630. if (__tag of rdf_box = __tag(v) and 0 = rdf_box_ro_id (v))
  1631. return DB.DBA.RDF_OBJ_ADD (257, v, 257);
  1632. return v;
  1633. }
  1634. if (__tag of nvarchar = t)
  1635. v := charset_recode (v, '_WIDE_', 'UTF-8');
  1636. else if (t in (126, 217))
  1637. v := cast (v as varchar);
  1638. else if (bit_and (1, __box_flags (v)))
  1639. return iri_to_id (v);
  1640. return DB.DBA.RDF_OBJ_ADD (257, v, 257);
  1641. }
  1642. ;
  1643. -----
  1644. -- Functions for long object representation.
  1645. create function DB.DBA.RDF_MAKE_LONG_OF_SQLVAL (in v any) returns any
  1646. {
  1647. declare t int;
  1648. declare res any;
  1649. t := __tag (v);
  1650. if (not (t in (126, __tag of varchar, 217, __tag of nvarchar, __tag of XML)))
  1651. return v;
  1652. if (__tag of nvarchar = t)
  1653. v := charset_recode (v, '_WIDE_', 'UTF-8');
  1654. else if (217 = t or 126 = t)
  1655. v := cast (v as varchar);
  1656. else if (bit_and (1, __box_flags (v)))
  1657. return iri_to_id (v);
  1658. res := rdf_box (v, 257, 257, 0, 1);
  1659. return res;
  1660. }
  1661. ;
  1662. create function DB.DBA.RDF_MAKE_LONG_OF_TYPEDSQLVAL (in v any, in dt_iid IRI_ID, in lang varchar) returns any
  1663. {
  1664. declare t, dt_twobyte, lang_twobyte int;
  1665. declare res any;
  1666. t := __tag (v);
  1667. -- if (not (t in (__tag of varchar, 217, __tag of nvarchar, __tag of XML)))
  1668. -- signal ('RDFXX', 'DB.DBA.RDF_MAKE_LONG_OF_TYPEDSQLVAL() accepts only string representations of typed values');
  1669. if (__tag of nvarchar = t)
  1670. v := charset_recode (v, '_WIDE_', 'UTF-8');
  1671. else if (217 = t)
  1672. v := cast (v as varchar);
  1673. else if (__tag of varchar = t and 1 = __box_flags (v) and dt_iid is null and lang is null)
  1674. return iri_to_id (v);
  1675. if (__tag of varchar <> __tag (v))
  1676. {
  1677. declare xsdt IRI_ID;
  1678. if (lang is not null)
  1679. {
  1680. if (is_rdf_box (v) and rdf_box_type (v) = 257)
  1681. {
  1682. v := rdf_box_data (v, 1);
  1683. if (__tag of varchar <> __tag (v))
  1684. signal ('RDFXX', 'Language is set and the argument is invalid RDF box in DB.DBA.RDF_MAKE_LONG_OF_TYPEDSQLVAL()');
  1685. }
  1686. else
  1687. signal ('RDFXX', 'Language is specified for typed literal in DB.DBA.RDF_MAKE_LONG_OF_TYPEDSQLVAL()');
  1688. if (dt_iid is not null)
  1689. signal ('RDFXX', 'Both language and type are specified in call of DB.DBA.RDF_MAKE_LONG_OF_TYPEDSQLVAL()');
  1690. }
  1691. else
  1692. {
  1693. if (is_rdf_box (v))
  1694. v := rdf_box_data (v, 1);
  1695. xsdt := cast (__xsd_type (v, UNAME'http://www.w3.org/2001/XMLSchema#string', NULL) as varchar);
  1696. if (dt_iid = case (isiri_id (dt_iid)) when 1 then iri_to_id (xsdt) else xsdt end)
  1697. return v;
  1698. -- dbg_obj_princ ('no opt -- ', dt_iid, case (isiri_id (dt_iid)) when 1 then iri_to_id (xsdt) else xsdt end);
  1699. }
  1700. }
  1701. if (dt_iid is not null)
  1702. dt_twobyte := DB.DBA.RDF_TWOBYTE_OF_DATATYPE (dt_iid);
  1703. else
  1704. dt_twobyte := 257;
  1705. if (lang is not null)
  1706. lang_twobyte := DB.DBA.RDF_TWOBYTE_OF_LANGUAGE (lang);
  1707. else
  1708. lang_twobyte := 257;
  1709. res := rdf_box (v, dt_twobyte, lang_twobyte, 0, 1);
  1710. return res;
  1711. }
  1712. ;
  1713. create function DB.DBA.RDF_MAKE_LONG_OF_TYPEDSQLVAL_STRINGS (
  1714. in o_val any, in o_type varchar, in o_lang varchar ) returns any
  1715. {
  1716. if (__tag (o_type) in (__tag of varchar, 217))
  1717. {
  1718. declare parsed any;
  1719. parsed := __xqf_str_parse_to_rdf_box (o_val, o_type, isstring (o_val));
  1720. if (parsed is not null)
  1721. {
  1722. if (__tag of XML = __tag (parsed))
  1723. parsed := rdf_box (parsed, 257, 257, 0, 1);
  1724. if (__tag of rdf_box = __tag (parsed))
  1725. rdf_box_set_type (parsed,
  1726. DB.DBA.RDF_TWOBYTE_OF_DATATYPE (iri_to_id (o_type)));
  1727. return parsed;
  1728. }
  1729. return DB.DBA.RDF_MAKE_LONG_OF_TYPEDSQLVAL (
  1730. o_val,
  1731. iri_to_id (o_type),
  1732. null );
  1733. }
  1734. if (__tag (o_lang) in (__tag of varchar, 217))
  1735. return DB.DBA.RDF_MAKE_LONG_OF_TYPEDSQLVAL (o_val, NULL, o_lang);
  1736. return DB.DBA.RDF_MAKE_LONG_OF_SQLVAL (o_val);
  1737. }
  1738. ;
  1739. create function DB.DBA.RDF_QNAME_OF_LONG_SAFE (in longobj any) returns varchar -- DEPRECATED
  1740. {
  1741. return id_to_iri_nosignal (longobj);
  1742. }
  1743. ;
  1744. create function DB.DBA.RDF_SQLVAL_OF_LONG (in longobj any) returns any -- DEPRECATED
  1745. {
  1746. return __rdf_sqlval_of_obj (longobj);
  1747. }
  1748. ;
  1749. create function DB.DBA.RDF_BOOL_OF_LONG (in longobj any) returns any
  1750. {
  1751. if (isiri_id (longobj))
  1752. return NULL;
  1753. if (isinteger (longobj))
  1754. {
  1755. if (longobj)
  1756. return 1;
  1757. return 0;
  1758. }
  1759. if (__tag of rdf_box <> __tag (longobj))
  1760. {
  1761. if (longobj is null)
  1762. return null;
  1763. if (equ (longobj, 0.0) or equ (longobj, '')) return 0; else return 1;
  1764. }
  1765. declare dtqname any;
  1766. if (257 = rdf_box_type (longobj))
  1767. goto type_ok;
  1768. whenever not found goto badtype;
  1769. select RDT_QNAME into dtqname from DB.DBA.RDF_DATATYPE where RDT_TWOBYTE = rdf_box_type (longobj);
  1770. if (dtqname <> UNAME'http://www.w3.org/2001/XMLSchema#string')
  1771. return null;
  1772. type_ok:
  1773. return case (length (rdf_box_data (longobj))) when 0 then 0 else 1 end;
  1774. badtype:
  1775. signal ('RDFXX', sprintf ('Unknown datatype in DB.DBA.RDF_BOOL_OF_LONG (code %d)', rdf_box_type (longobj)));
  1776. }
  1777. ;
  1778. create function DB.DBA.RDF_DATATYPE_OF_LONG (in longobj any, in dflt any := UNAME'http://www.w3.org/2001/XMLSchema#string') returns any
  1779. {
  1780. if (__tag of rdf_box = __tag (longobj))
  1781. {
  1782. declare twobyte integer;
  1783. declare res IRI_ID;
  1784. twobyte := rdf_box_type (longobj);
  1785. if (257 = twobyte)
  1786. return case (rdf_box_lang (longobj)) when 257 then __uname (dflt) else null end;
  1787. whenever not found goto badtype;
  1788. select __uname (RDT_QNAME) into res from DB.DBA.RDF_DATATYPE where RDT_TWOBYTE = twobyte;
  1789. return res;
  1790. badtype:
  1791. signal ('RDFXX', sprintf ('Unknown datatype in DB.DBA.RDF_DATATYPE_OF_LONG, bad id %d', twobyte));
  1792. }
  1793. if (isiri_id (longobj))
  1794. return NULL;
  1795. return __xsd_type (longobj, dflt);
  1796. }
  1797. ;
  1798. create function DB.DBA.RDF_DATATYPE_IRI_OF_LONG (in longobj any, in dflt any := UNAME'http://www.w3.org/2001/XMLSchema#string') returns any
  1799. {
  1800. if (__tag of rdf_box = __tag (longobj))
  1801. {
  1802. declare twobyte integer;
  1803. declare res varchar;
  1804. twobyte := rdf_box_type (longobj);
  1805. if (257 = twobyte)
  1806. return case (rdf_box_lang (longobj)) when 257 then dflt else null end;
  1807. whenever not found goto badtype;
  1808. select RDT_QNAME into res from DB.DBA.RDF_DATATYPE where RDT_TWOBYTE = twobyte;
  1809. return res;
  1810. badtype:
  1811. signal ('RDFXX', sprintf ('Unknown datatype in DB.DBA.RDF_DATATYPE_IRI_OF_LONG, bad id %d', twobyte));
  1812. }
  1813. if (isiri_id (longobj))
  1814. return NULL;
  1815. return __xsd_type (longobj, dflt);
  1816. }
  1817. ;
  1818. create function DB.DBA.RDF_LANGUAGE_OF_LONG (in longobj any, in dflt varchar := '') returns any
  1819. {
  1820. if (__tag of rdf_box = __tag (longobj))
  1821. {
  1822. declare twobyte integer;
  1823. declare res varchar;
  1824. twobyte := rdf_box_lang (longobj);
  1825. if (257 = twobyte)
  1826. return dflt;
  1827. whenever not found goto badlang;
  1828. select lower (RL_ID) into res from DB.DBA.RDF_LANGUAGE where RL_TWOBYTE = twobyte;
  1829. return res;
  1830. badlang:
  1831. signal ('RDFXX', sprintf ('Unknown language in DB.DBA.RDF_LANGUAGE_OF_LONG, bad id %d', twobyte));
  1832. }
  1833. return case (isiri_id (longobj)) when 0 then dflt else null end;
  1834. }
  1835. ;
  1836. create function DB.DBA.RDF_STRSQLVAL_OF_LONG (in longobj any) -- DEPRECATED
  1837. {
  1838. return __rdf_strsqlval (longobj, 0);
  1839. }
  1840. ;
  1841. create function DB.DBA.RDF_WIDESTRSQLVAL_OF_LONG (in longobj any)
  1842. {
  1843. declare t, len integer;
  1844. if (__tag of rdf_box = __tag (longobj))
  1845. {
  1846. if (rdf_box_is_complete (longobj))
  1847. {
  1848. if (__tag of varchar = rdf_box_data_tag (longobj))
  1849. return charset_recode (rdf_box_data (longobj), 'UTF-8', '_WIDE_');
  1850. if (__tag of datetime = rdf_box_data_tag (longobj))
  1851. {
  1852. declare vc varchar;
  1853. vc := cast (rdf_box_data (longobj) as varchar); --!!!TBD: replace with proper serialization
  1854. return cast (replace (vc, ' ', 'T') as nvarchar);
  1855. }
  1856. if (__tag of XML = rdf_box_data_tag (longobj))
  1857. {
  1858. return charset_recode (serialize_to_UTF8_xml (rdf_box_data (longobj)), 'UTF-8', '_WIDE_');
  1859. }
  1860. return cast (rdf_box_data (longobj) as nvarchar);
  1861. }
  1862. declare id integer;
  1863. declare v2 any;
  1864. id := rdf_box_ro_id (longobj);
  1865. if (__tag of XML = rdf_box_data_tag (longobj))
  1866. {
  1867. v2 := (select xml_tree_doc (__xml_deserialize_packed (RO_LONG)) from DB.DBA.RDF_OBJ where RO_ID = id);
  1868. rdf_box_set_data (longobj, v2, 1);
  1869. return charset_recode (serialize_to_UTF8_xml (v2), 'UTF-8', '_WIDE_');
  1870. }
  1871. else
  1872. v2 := (select case (isnull (RO_LONG)) when 0 then blob_to_string (RO_LONG) else RO_VAL end from DB.DBA.RDF_OBJ where RO_ID = id);
  1873. if (v2 is null)
  1874. signal ('RDFXX', sprintf ('Integrity violation in DB.DBA.RDF_WIDESTRSQLVAL_OF_LONG, bad id %d', id));
  1875. rdf_box_set_data (longobj, v2, 1);
  1876. return charset_recode (v2, 'UTF-8', '_WIDE_');
  1877. }
  1878. if (isiri_id (longobj))
  1879. {
  1880. declare res varchar;
  1881. res := id_to_iri (longobj);
  1882. -- res := coalesce ((select RU_QNAME from DB.DBA.RDF_URL where RU_IID = longobj));
  1883. if (res is null)
  1884. signal ('RDFXX', 'Wrong iid in DB.DBA.RDF_WIDESTRSQLVAL_OF_LONG()');
  1885. return charset_recode (res, 'UTF-8', '_WIDE_');
  1886. }
  1887. if (__tag of datetime = __tag (longobj))
  1888. {
  1889. declare vc varchar;
  1890. vc := cast (longobj as varchar); --!!!TBD: replace with proper serialization
  1891. return cast (replace (vc, ' ', 'T') as nvarchar);
  1892. }
  1893. if (__tag of nvarchar = __tag (longobj))
  1894. return longobj;
  1895. if (__tag of XML = __tag (longobj))
  1896. {
  1897. return charset_recode (serialize_to_UTF8_xml (longobj), 'UTF-8', '_WIDE_');
  1898. }
  1899. return cast (longobj as nvarchar);
  1900. }
  1901. ;
  1902. --!AWK PUBLIC
  1903. create function DB.DBA.RDF_DATATYPE_OF_SQLVAL (in v any,
  1904. in strg_datatype any := UNAME'http://www.w3.org/2001/XMLSchema#string',
  1905. in default_res any := NULL) returns any
  1906. {
  1907. if (__tag of rdf_box = __tag (v))
  1908. {
  1909. declare twobyte integer;
  1910. declare res IRI_ID;
  1911. twobyte := rdf_box_type (v);
  1912. if (257 = twobyte)
  1913. return case (rdf_box_lang (v)) when 257 then __uname (strg_datatype) else null end;
  1914. whenever not found goto badtype;
  1915. select __uname (RDT_QNAME) into res from DB.DBA.RDF_DATATYPE where RDT_TWOBYTE = twobyte;
  1916. return res;
  1917. badtype:
  1918. signal ('RDFXX', sprintf ('Unknown datatype in DB.DBA.RDF_DATATYPE_OF_SQLVAL, bad id %d', twobyte));
  1919. }
  1920. return __uname (__xsd_type (v, strg_datatype, default_res));
  1921. }
  1922. ;
  1923. -- /* keep the input parameter as varchar in order to make jdbc happy and receive 182 instead of 242 on which it breaks the utf8 support */
  1924. create function DB.DBA.RDF_LONG_OF_SQLVAL (in v varchar) returns any
  1925. {
  1926. declare t int;
  1927. t := __tag (v);
  1928. if (not (t in (126, __tag of varchar, 217, __tag of nvarchar)))
  1929. return v;
  1930. if (__tag of nvarchar = t)
  1931. v := charset_recode (v, '_WIDE_', 'UTF-8');
  1932. else if (t in (126, 217))
  1933. v := cast (v as varchar);
  1934. else if ((t = __tag of varchar) and (1 = __box_flags (v)))
  1935. return iri_to_id (v);
  1936. -- if ((t = __tag of varchar) and (v like 'http://%'))
  1937. -- {
  1938. -- -- dbg_obj_princ ('DB.DBA.RDF_LONG_OF_SQLVAL (', v, '): no box flag, suspicious value');
  1939. -- ;
  1940. -- }
  1941. return rdf_box (v, 257, 257, 0, 1);
  1942. }
  1943. ;
  1944. -----
  1945. -- Conversions for SQL values
  1946. --!AWK PUBLIC
  1947. create function DB.DBA.RDF_STRSQLVAL_OF_SQLVAL (in sqlval any) -- DEPRECATED
  1948. {
  1949. declare t, len integer;
  1950. if (__tag of rdf_box = __tag (sqlval))
  1951. sqlval := __ro2sq (sqlval, 1);
  1952. if (isiri_id (sqlval))
  1953. {
  1954. declare res varchar;
  1955. res := id_to_iri (sqlval);
  1956. -- res := coalesce ((select RU_QNAME from DB.DBA.RDF_URL where RU_IID = sqlval));
  1957. if (res is null)
  1958. signal ('RDFXX', 'Wrong iid in DB.DBA.RDF_STRSQLVAL_OF_SQLVAL()');
  1959. __box_flags_set (res, 2);
  1960. return res;
  1961. }
  1962. if (__tag of datetime = __tag (sqlval))
  1963. {
  1964. declare vc varchar;
  1965. vc := cast (sqlval as varchar); --!!!TBD: replace with proper serialization
  1966. return replace (vc, ' ', 'T');
  1967. }
  1968. if (__tag of nvarchar = __tag (sqlval))
  1969. return charset_recode (sqlval, '_WIDE_', 'UTF-8');
  1970. return cast (sqlval as varchar);
  1971. }
  1972. ;
  1973. --!AWK PUBLIC
  1974. create function DB.DBA.RDF_LANGUAGE_OF_SQLVAL (in v any, in dflt varchar := '') returns any
  1975. {
  1976. declare t int;
  1977. if (__tag of rdf_box = __tag (v))
  1978. {
  1979. declare twobyte integer;
  1980. declare res varchar;
  1981. twobyte := rdf_box_lang (v);
  1982. whenever not found goto badtype;
  1983. select RL_ID into res from DB.DBA.RDF_LANGUAGE where RL_TWOBYTE = twobyte;
  1984. return res;
  1985. badtype:
  1986. signal ('RDFXX', sprintf ('Unknown language in DB.DBA.RDF_LANGUAGE_OF_SQLVAL, bad id %d', twobyte));
  1987. }
  1988. return case (isiri_id (v)) when 0 then dflt else null end;
  1989. -- t := __tag (v);
  1990. -- if (not (t in (__tag of varchar, 217, __tag of nvarchar)))
  1991. -- return NULL;
  1992. -- return NULL; -- !!!TBD: uncomment this and make a support for UTF8 'language name' codepoint plane
  1993. }
  1994. ;
  1995. --!AWK PUBLIC
  1996. create function DB.DBA.RDF_IS_BLANK_REF (in v any) returns any
  1997. {
  1998. if ((__tag (v) = 217) or ((__tag (v) = __tag of varchar) and bit_and (1, __box_flags (v))))
  1999. {
  2000. if ("LEFT" (v, 9) <> 'nodeID://')
  2001. return 0;
  2002. return 1;
  2003. }
  2004. if (__tag (v) = 243)
  2005. {
  2006. if (v < min_bnode_iri_id ())
  2007. return 0;
  2008. return 1;
  2009. }
  2010. return 0;
  2011. }
  2012. ;
  2013. --!AWK PUBLIC
  2014. create function DB.DBA.RDF_IS_URI_REF (in v any) returns any
  2015. {
  2016. if ((__tag (v) = 217) or ((__tag (v) = __tag of varchar) and bit_and (1, __box_flags (v))))
  2017. {
  2018. if ("LEFT" (v, 9) <> 'nodeID://')
  2019. return 1;
  2020. return 0;
  2021. }
  2022. if (__tag (v) = 243)
  2023. {
  2024. if (v < min_bnode_iri_id ())
  2025. return 1;
  2026. return 0;
  2027. }
  2028. return 0;
  2029. }
  2030. ;
  2031. --!AWK PUBLIC
  2032. create function DB.DBA.RDF_IS_REF (in v any) returns any
  2033. {
  2034. if (__tag (v) in (217, 243))
  2035. return 1;
  2036. if ((__tag of varchar = __tag (v)) and bit_and (1, __box_flags (v)))
  2037. return 1;
  2038. return 0;
  2039. }
  2040. ;
  2041. --!AWK PUBLIC
  2042. create function DB.DBA.RDF_IS_LITERAL (in v any) returns any
  2043. {
  2044. if (__tag (v) in (217, 243))
  2045. return 0;
  2046. if ((__tag of varchar = __tag (v)) and bit_and (1, __box_flags (v)))
  2047. return 0;
  2048. return 1;
  2049. }
  2050. ;
  2051. -----
  2052. -- Partial emulation of XQuery Core Function Library (temporary, to be deleted soon)
  2053. --!AWK PUBLIC
  2054. create function DB.DBA."http://www.w3.org/2001/XMLSchema#boolean" (in strg any) returns integer
  2055. {
  2056. if (isstring (strg))
  2057. {
  2058. if (('true' = strg) or ('1' = strg))
  2059. return 1;
  2060. if (('false' = strg) or ('0' = strg))
  2061. return 0;
  2062. }
  2063. if (isinteger (strg))
  2064. return case (strg) when 0 then 0 else 1 end;
  2065. return NULL;
  2066. }
  2067. ;
  2068. --!AWK PUBLIC
  2069. create function DB.DBA."http://www.w3.org/2001/XMLSchema#date" (in strg any) returns date
  2070. {
  2071. if (__tag of datetime = __tag (strg))
  2072. return strg;
  2073. whenever sqlstate '*' goto ret_null;
  2074. if (isstring (strg))
  2075. return __xqf_str_parse ('date', strg);
  2076. return cast (strg as date);
  2077. ret_null:
  2078. return NULL;
  2079. }
  2080. ;
  2081. --!AWK PUBLIC
  2082. create function DB.DBA."http://www.w3.org/2001/XMLSchema#dateTime" (in strg any) returns datetime
  2083. {
  2084. if (__tag of datetime = __tag (strg))
  2085. return strg;
  2086. whenever sqlstate '*' goto ret_null;
  2087. if (isstring (strg))
  2088. return __xqf_str_parse ('dateTime', strg);
  2089. return cast (strg as datetime);
  2090. ret_null:
  2091. return NULL;
  2092. }
  2093. ;
  2094. --!AWK PUBLIC
  2095. create function DB.DBA."http://www.w3.org/2001/XMLSchema#double" (in strg varchar) returns double precision
  2096. {
  2097. whenever sqlstate '*' goto ret_null;
  2098. return cast (strg as double precision);
  2099. ret_null:
  2100. return NULL;
  2101. }
  2102. ;
  2103. --!AWK PUBLIC
  2104. create function DB.DBA."http://www.w3.org/2001/XMLSchema#float" (in strg varchar) returns float
  2105. {
  2106. whenever sqlstate '*' goto ret_null;
  2107. return cast (strg as float);
  2108. ret_null:
  2109. return NULL;
  2110. }
  2111. ;
  2112. --!AWK PUBLIC
  2113. create function DB.DBA."http://www.w3.org/2001/XMLSchema#integer" (in strg varchar) returns integer
  2114. {
  2115. whenever sqlstate '*' goto ret_null;
  2116. return cast (strg as integer);
  2117. ret_null:
  2118. return NULL;
  2119. }
  2120. ;
  2121. --!AWK PUBLIC
  2122. create function DB.DBA."http://www.w3.org/2001/XMLSchema#int" (in strg varchar) returns integer
  2123. {
  2124. whenever sqlstate '*' goto ret_null;
  2125. return cast (strg as integer);
  2126. ret_null:
  2127. return NULL;
  2128. }
  2129. ;
  2130. --!AWK PUBLIC
  2131. create function DB.DBA."http://www.w3.org/2001/XMLSchema#time" (in strg any) returns time
  2132. {
  2133. if (__tag of datetime = __tag (strg))
  2134. return strg;
  2135. whenever sqlstate '*' goto ret_null;
  2136. if (isstring (strg))
  2137. return __xqf_str_parse ('time', strg);
  2138. return cast (strg as time);
  2139. ret_null:
  2140. return NULL;
  2141. }
  2142. ;
  2143. --!AWK PUBLIC
  2144. create function DB.DBA."http://www.w3.org/2001/XMLSchema#string" (in strg any) returns any
  2145. {
  2146. whenever sqlstate '*' goto ret_null;
  2147. declare t, dt_twobyte, lang_twobyte int;
  2148. t := __tag (strg);
  2149. if (__tag of nvarchar = t)
  2150. strg := charset_recode (strg, '_WIDE_', 'UTF-8');
  2151. else if (__tag of varchar <> t)
  2152. strg := cast (strg as varchar);
  2153. return DB.DBA.RDF_OBJ_ADD (
  2154. DB.DBA.RDF_TWOBYTE_OF_DATATYPE ('http://www.w3.org/2001/XMLSchema#string'),
  2155. strg, 257 );
  2156. ret_null:
  2157. return NULL;
  2158. }
  2159. ;
  2160. -----
  2161. -- Boolean operators as functions (temporary, will be replaced with 'LET' SQL extension soon)
  2162. --!AWK PUBLIC
  2163. create function DB.DBA.__and (in e1 any, in e2 any) returns integer
  2164. {
  2165. if (e1 and e2)
  2166. return 1;
  2167. return 0;
  2168. }
  2169. ;
  2170. --!AWK PUBLIC
  2171. create function DB.DBA.__or (in e1 any, in e2 any) returns integer
  2172. {
  2173. if (e1 or e2)
  2174. return 1;
  2175. return 0;
  2176. }
  2177. ;
  2178. --!AWK PUBLIC
  2179. create function DB.DBA.__not (in e1 any) returns integer
  2180. {
  2181. if (e1)
  2182. return 0;
  2183. return 1;
  2184. }
  2185. ;
  2186. -----
  2187. -- SPARQL 1.1 built-in functions, implemented as stored procedures
  2188. create function DB.DBA.rdf_strdt_impl (in str varchar, in dt_iri any)
  2189. {
  2190. declare dt_iid IRI_ID;
  2191. declare parsed any;
  2192. dt_iid := __i2id (dt_iri);
  2193. if (dt_iid is null)
  2194. signal ('22007', 'Function rdf_strdt_impl needs a valid datatype IRI as its second argument');
  2195. if (__tag of IRI_ID = __tag (dt_iri))
  2196. dt_iri := __id2i (dt_iri);
  2197. parsed := __xqf_str_parse_to_rdf_box (str, dt_iri, isstring (str));
  2198. if (parsed is not null)
  2199. {
  2200. if (__tag of rdf_box = __tag (parsed))
  2201. rdf_box_set_type (parsed,
  2202. DB.DBA.RDF_TWOBYTE_OF_DATATYPE (dt_iid));
  2203. return parsed;
  2204. }
  2205. return DB.DBA.RDF_MAKE_LONG_OF_TYPEDSQLVAL (str, dt_iid, null);
  2206. }
  2207. ;
  2208. create function DB.DBA.rdf_strlang_impl (in str varchar, in lang any)
  2209. {
  2210. declare t integer;
  2211. lang := cast (lang as varchar);
  2212. if ((lang is null) or (regexp_match ('^(([a-z][a-z](-[A-Z][A-Z])?)|(x-[A-Za-z0-9]+))\044', lang) is null))
  2213. signal ('22007', 'Function rdf_strlang_impl needs a valid language ID as its second argument');
  2214. if (is_rdf_box (str))
  2215. str := rdf_box_data (str, 1);
  2216. t := __tag (str);
  2217. if (__tag of nvarchar = t)
  2218. str := charset_recode (str, '_WIDE_', 'UTF-8');
  2219. else if (__tag of varchar <> t)
  2220. {
  2221. if (str is null)
  2222. signal ('22007', 'Function rdf_strlang_impl needs a bound value as its first argument, not a NULL');
  2223. str := cast (str as varchar);
  2224. }
  2225. return rdf_box (str, 257, DB.DBA.RDF_TWOBYTE_OF_LANGUAGE (lang), 0, 1);
  2226. }
  2227. ;
  2228. --!AWK PUBLIC
  2229. create function DB.DBA.rdf_replace_impl (in src varchar, in needle varchar, in rpl varchar, in opts varchar := '')
  2230. {
  2231. declare src_tag, needle_tag, rpl_tag integer;
  2232. declare res varchar;
  2233. src_tag := __tag (src);
  2234. needle_tag := __tag (needle);
  2235. rpl_tag := __tag (rpl);
  2236. if (__tag of rdf_box = src_tag)
  2237. {
  2238. src := rdf_box_data (src);
  2239. src_tag := __tag (src);
  2240. }
  2241. if (__tag of rdf_box = needle_tag)
  2242. {
  2243. needle := rdf_box_data (needle);
  2244. needle_tag := __tag (needle);
  2245. }
  2246. if (__tag of rdf_box = rpl_tag)
  2247. {
  2248. rpl := rdf_box_data (rpl);
  2249. rpl_tag := __tag (rpl);
  2250. }
  2251. if (__tag of nvarchar = src_tag)
  2252. src := charset_recode (src, '_WIDE_', 'UTF-8');
  2253. else if (__tag of varchar <> src_tag)
  2254. src := cast (src as varchar);
  2255. if (__tag of nvarchar = needle_tag)
  2256. needle := charset_recode (needle, '_WIDE_', 'UTF-8');
  2257. else if (__tag of varchar <> needle_tag)
  2258. needle := cast (needle as varchar);
  2259. if (__tag of nvarchar = rpl_tag)
  2260. rpl := charset_recode (rpl, '_WIDE_', 'UTF-8');
  2261. else if (__tag of varchar <> rpl_tag)
  2262. rpl := cast (rpl as varchar);
  2263. if (__tag of varchar <> __tag (opts))
  2264. opts := cast (opts as varchar);
  2265. if (opts is null)
  2266. opts := '';
  2267. if (src is null or needle is null or rpl is null)
  2268. return null;
  2269. if ('' = needle)
  2270. return src;
  2271. if (regexp_match ('^[^()|+?.:^\044\\\\\\[\\]-]+\044', needle, 0, 'u') is not null and strchr (rpl, '\044') is null and strchr (rpl, 92) is null)
  2272. {
  2273. if ('' = opts)
  2274. {
  2275. res := replace (src, needle, rpl);
  2276. __box_flags_set (res, 2);
  2277. return res;
  2278. }
  2279. if (opts in ('i', 'I'))
  2280. {
  2281. declare src_lc varchar;
  2282. declare hit, needle_len integer;
  2283. declare ses any;
  2284. src_lc := lcase (src);
  2285. needle := lcase (needle);
  2286. hit := strstr (src_lc, needle);
  2287. if (hit is null)
  2288. {
  2289. res := src;
  2290. __box_flags_set (res, 2);
  2291. return res;
  2292. }
  2293. ses := string_output();
  2294. needle_len := length (needle);
  2295. while (hit is not null)
  2296. {
  2297. http (subseq (src, 0, hit), ses);
  2298. http (rpl, ses);
  2299. src := subseq (src, hit + needle_len);
  2300. src_lc := subseq (src_lc, hit + needle_len);
  2301. hit := strstr (src_lc, needle);
  2302. }
  2303. http (src, ses);
  2304. res := string_output_string (ses);
  2305. __box_flags_set (res, 2);
  2306. return res;
  2307. }
  2308. }
  2309. if (strchr (opts, 'u') is null and strchr (opts, 'U') is null)
  2310. opts := opts || 'u';
  2311. res := regexp_xfn_replace (src, needle, rpl, 0, null, opts);
  2312. __box_flags_set (res, 2);
  2313. return res;
  2314. }
  2315. ;
  2316. --!AWK PUBLIC
  2317. create function DB.DBA.regexp_xfn_replace (in src varchar, in needle varchar, in tmpl varchar, in search_begin_pos integer, in hit_max_count integer, in opts varchar)
  2318. {
  2319. declare hit_list any;
  2320. if (0 = length (src))
  2321. return '';
  2322. if (regexp_parse (needle, '', 0, opts) is not null)
  2323. signal ('22023', 'The regex-based XPATH/XQuery/SPARQL replace() function can not search for a pattern that can be found even in an empty string');
  2324. hit_list := regexp_parse_list (needle, src, search_begin_pos, opts, coalesce (hit_max_count, 2097152));
  2325. return regexp_replace_hits_with_template (src, tmpl, hit_list, 1);
  2326. }
  2327. ;
  2328. create function DB.DBA.rdf_uuid_impl ()
  2329. {
  2330. return iri_to_id ('urn:uuid:' || uuid());
  2331. }
  2332. ;
  2333. --!AWK PUBLIC
  2334. create function DB.DBA.rdf_timezone_impl (in dt datetime)
  2335. {
  2336. declare minutes integer;
  2337. declare sign, str varchar;
  2338. minutes := timezone (dt);
  2339. if (minutes is null)
  2340. signal ('22007', 'Function rdf_timezone_impl needs a datetime with some timezone set as its argument');
  2341. if (minutes < 0)
  2342. {
  2343. sign := '-';
  2344. minutes := -minutes;
  2345. }
  2346. else
  2347. sign := '';
  2348. if (mod (minutes, 60))
  2349. str := sprintf ('%sPT%dH%dM', sign, minutes / 60, mod (minutes, 60));
  2350. else if (minutes = 0)
  2351. str := 'PT0S';
  2352. else
  2353. str := sprintf ('%sPT%dH', sign, minutes / 60);
  2354. return DB.DBA.RDF_MAKE_LONG_OF_TYPEDSQLVAL (str, __i2id (UNAME'http://www.w3.org/2001/XMLSchema#dayTimeDuration'), null);
  2355. }
  2356. ;
  2357. --!AWK PUBLIC
  2358. create function DB.DBA.rdf_tz_impl (in dt datetime)
  2359. {
  2360. declare minutes integer;
  2361. declare sign varchar;
  2362. minutes := timezone (dt);
  2363. if (minutes is null)
  2364. return '';
  2365. if (minutes = 0)
  2366. return 'Z';
  2367. if (minutes < 0)
  2368. {
  2369. sign := '-';
  2370. minutes := -minutes;
  2371. }
  2372. else
  2373. sign := '';
  2374. return sprintf ('%s%02d:%02d', sign, minutes / 60, mod (minutes, 60));
  2375. }
  2376. ;
  2377. -----
  2378. -- Data loading
  2379. create procedure DB.DBA.RDF_QUAD_URI (in g_uri varchar, in s_uri varchar, in p_uri varchar, in o_uri varchar)
  2380. {
  2381. declare g_iid IRI_ID;
  2382. g_iid := iri_to_id (g_uri);
  2383. if (__rdf_graph_is_in_enabled_repl (g_iid))
  2384. __rdf_repl_quad (84, iri_canonicalize (g_uri), iri_canonicalize (s_uri), iri_canonicalize (p_uri), iri_canonicalize (o_uri));
  2385. insert soft DB.DBA.RDF_QUAD (G,S,P,O)
  2386. values (
  2387. g_iid,
  2388. iri_to_id (s_uri),
  2389. iri_to_id (p_uri),
  2390. iri_to_id (o_uri) );
  2391. }
  2392. ;
  2393. create procedure DB.DBA.RDF_QUAD_URI_L (in g_uri varchar, in s_uri varchar, in p_uri varchar, in o_lit any, in ro_id_dict any := null)
  2394. {
  2395. declare g_iid, s_iid, p_iid IRI_ID;
  2396. declare o_obj any;
  2397. g_iid := iri_to_id (g_uri);
  2398. s_iid := iri_to_id (s_uri);
  2399. p_iid := iri_to_id (p_uri);
  2400. o_obj := DB.DBA.RDF_MAKE_OBJ_OF_SQLVAL_FT (o_lit, g_iid, p_iid, ro_id_dict);
  2401. if (__rdf_graph_is_in_enabled_repl (g_iid))
  2402. {
  2403. declare triples any;
  2404. triples := vector (vector (s_iid, p_iid, o_obj));
  2405. DB.DBA.RDF_REPL_INSERT_TRIPLES (id_to_iri (g_iid), triples);
  2406. }
  2407. insert soft DB.DBA.RDF_QUAD (G,S,P,O) values (g_iid, s_iid, p_iid, o_obj);
  2408. }
  2409. ;
  2410. create procedure DB.DBA.RDF_QUAD_URI_L_TYPED (in g_uri varchar, in s_uri varchar, in p_uri varchar, in o_lit any, in dt any, in lang varchar, in ro_id_dict any := null)
  2411. {
  2412. declare g_iid, s_iid, p_iid IRI_ID;
  2413. declare o_obj any;
  2414. g_iid := iri_to_id (g_uri);
  2415. s_iid := iri_to_id (s_uri);
  2416. p_iid := iri_to_id (p_uri);
  2417. if (dt is null and lang is null)
  2418. o_obj := DB.DBA.RDF_MAKE_OBJ_OF_SQLVAL_FT (o_lit, g_iid, p_iid, ro_id_dict);
  2419. else
  2420. o_obj := DB.DBA.RDF_MAKE_OBJ_OF_TYPEDSQLVAL_FT (o_lit, iri_to_id (dt), lang, g_iid, p_iid, ro_id_dict);
  2421. if (__rdf_graph_is_in_enabled_repl (g_iid))
  2422. {
  2423. declare triples any;
  2424. triples := vector (vector (s_iid, p_iid, o_obj));
  2425. DB.DBA.RDF_REPL_INSERT_TRIPLES (id_to_iri (g_iid), triples);
  2426. }
  2427. insert soft DB.DBA.RDF_QUAD (G,S,P,O) values (g_iid, s_iid, p_iid, o_obj);
  2428. }
  2429. ;
  2430. create procedure DB.DBA.RDF_QUAD_L_RDB2RDF (in g_iid varchar, in s_iid varchar, in p_iid varchar, inout o_val any, inout old_g_iid any, inout ro_id_dict any)
  2431. {
  2432. declare t int;
  2433. if (__rdf_graph_is_in_enabled_repl (g_iid))
  2434. {
  2435. declare triples any;
  2436. triples := vector (vector (s_iid, p_iid, o_val));
  2437. DB.DBA.RDF_REPL_INSERT_TRIPLES (id_to_iri (g_iid), triples);
  2438. }
  2439. t := __tag (o_val);
  2440. if (__tag of rdf_box <> t)
  2441. {
  2442. if (not (t in (__tag of varchar, 126, 133, 217, __tag of nvarchar, 226)))
  2443. {
  2444. goto o_val_done;
  2445. }
  2446. if (t = 133)
  2447. {
  2448. o_val := cast (o_val as nvarchar);
  2449. t := __tag (o_val);
  2450. }
  2451. if (__tag of nvarchar = t or t = 226)
  2452. o_val := charset_recode (o_val, '_WIDE_', 'UTF-8');
  2453. else if (t in (126, 217))
  2454. o_val := cast (o_val as varchar);
  2455. else if (bit_and (1, __box_flags (o_val)))
  2456. {
  2457. o_val := iri_to_id (o_val);
  2458. goto o_val_done;
  2459. }
  2460. }
  2461. if (__rdf_obj_ft_rule_check (g_iid, p_iid))
  2462. {
  2463. if (old_g_iid <> g_iid)
  2464. {
  2465. if (dict_size (ro_id_dict))
  2466. DB.DBA.RDF_OBJ_ADD_KEYWORD_FOR_GRAPH (old_g_iid, ro_id_dict);
  2467. old_g_iid := g_iid;
  2468. }
  2469. if (ro_id_dict is null)
  2470. ro_id_dict := dict_new ();
  2471. o_val := DB.DBA.RDF_OBJ_ADD (257, o_val, 257, ro_id_dict);
  2472. }
  2473. else
  2474. o_val := DB.DBA.RDF_OBJ_ADD (257, o_val, 257);
  2475. o_val_done:
  2476. if (o_val is null or s_iid is null)
  2477. {
  2478. -- cannot have null values
  2479. return;
  2480. }
  2481. insert soft DB.DBA.RDF_QUAD (G,S,P,O) values (g_iid, s_iid, p_iid, o_val);
  2482. }
  2483. ;
  2484. create procedure DB.DBA.TTLP_EV_NEW_GRAPH (inout g varchar, inout g_iid IRI_ID, inout app_env any) {
  2485. -- dbg_obj_princ ('DB.DBA.TTLP_EV_NEW_GRAPH(', g, g_iid, app_env, ')');
  2486. if (__rdf_obj_ft_rule_count_in_graph (g_iid))
  2487. app_env[1] := dict_new (app_env[2]);
  2488. else
  2489. app_env[1] := null;
  2490. if (__rdf_graph_is_in_enabled_repl (g_iid))
  2491. app_env[3] := g;
  2492. else
  2493. app_env[3] := null;
  2494. }
  2495. ;
  2496. create procedure DB.DBA.TTLP_EV_NEW_BLANK (inout g_iid IRI_ID, inout app_env any, inout res IRI_ID) {
  2497. res := iri_id_from_num (sequence_next ('RDF_URL_IID_BLANK'));
  2498. -- dbg_obj_princ ('DB.DBA.TTLP_EV_NEW_BLANK (', g_iid, app_env, ') returns ', res);
  2499. }
  2500. ;
  2501. create procedure DB.DBA.TTLP_EV_GET_IID (inout uri varchar, inout g_iid IRI_ID, inout app_env any, inout res IRI_ID) {
  2502. -- dbg_obj_princ ('DB.DBA.TTLP_EV_GET_IID (', uri, g_iid, app_env, ')');
  2503. res := iri_to_id (uri);
  2504. -- dbg_obj_princ ('DB.DBA.TTLP_EV_GET_IID (', uri, g_iid, app_env, ') returns ', res);
  2505. }
  2506. ;
  2507. create procedure DB.DBA.TTLP_EV_TRIPLE (
  2508. inout g_iid IRI_ID, inout s_uri varchar, inout p_uri varchar,
  2509. inout o_uri varchar,
  2510. inout app_env any )
  2511. {
  2512. -- dbg_obj_princ ('DB.DBA.TTLP_EV_TRIPLE (', g_iid, s_uri, p_uri, o_uri, ');');
  2513. if (app_env[3] is not null)
  2514. __rdf_repl_quad (84, app_env[3], iri_canonicalize (s_uri), iri_canonicalize (p_uri), iri_canonicalize (o_uri));
  2515. insert soft DB.DBA.RDF_QUAD (G,S,P,O) values (g_iid, iri_to_id (s_uri), iri_to_id (p_uri), iri_to_id (o_uri));
  2516. }
  2517. ;
  2518. create procedure DB.DBA.TTLP_EV_TRIPLE_L (
  2519. inout g_iid IRI_ID, inout s_uri varchar, inout p_uri varchar,
  2520. inout o_val any, inout o_type varchar, inout o_lang varchar,
  2521. inout app_env any )
  2522. {
  2523. -- dbg_obj_princ ('DB.DBA.TTLP_EV_TRIPLE_L (', g_iid, s_uri, p_uri, o_val, o_type, o_lang, app_env, ');');
  2524. declare log_mode integer;
  2525. declare p_iid IRI_ID;
  2526. declare ro_id_dict any;
  2527. if (app_env[3] is not null)
  2528. {
  2529. if (isstring (o_type))
  2530. __rdf_repl_quad (81, app_env[3], iri_canonicalize (s_uri), iri_canonicalize (p_uri), o_val, iri_canonicalize (o_type), NULL);
  2531. else if (isstring (o_lang))
  2532. __rdf_repl_quad (82, app_env[3], iri_canonicalize (s_uri), iri_canonicalize (p_uri), o_val, null, o_lang);
  2533. else
  2534. __rdf_repl_quad (80, app_env[3], iri_canonicalize (s_uri), iri_canonicalize (p_uri), o_val);
  2535. }
  2536. log_mode := app_env[0];
  2537. ro_id_dict := app_env[1];
  2538. p_iid := iri_to_id (p_uri);
  2539. if (isstring (o_type))
  2540. {
  2541. declare parsed any;
  2542. parsed := __xqf_str_parse_to_rdf_box (o_val, o_type, isstring (o_val));
  2543. if (parsed is not null)
  2544. {
  2545. if (__tag of XML = __tag (parsed))
  2546. {
  2547. insert soft DB.DBA.RDF_QUAD (G,S,P,O)
  2548. values (g_iid, iri_to_id (s_uri), p_iid,
  2549. DB.DBA.RDF_MAKE_OBJ_OF_SQLVAL_FT (
  2550. parsed, g_iid, p_iid, ro_id_dict ) );
  2551. return;
  2552. }
  2553. if (__tag of rdf_box = __tag (parsed))
  2554. {
  2555. if (256 = rdf_box_type (parsed))
  2556. db..rdf_geo_add (parsed);
  2557. else
  2558. rdf_box_set_type (parsed,
  2559. DB.DBA.RDF_TWOBYTE_OF_DATATYPE (iri_to_id (o_type)));
  2560. parsed := DB.DBA.RDF_OBJ_ADD (257, parsed, 257, ro_id_dict);
  2561. }
  2562. insert soft DB.DBA.RDF_QUAD (G,S,P,O)
  2563. values (g_iid, iri_to_id (s_uri), p_iid, parsed);
  2564. return;
  2565. }
  2566. insert soft DB.DBA.RDF_QUAD (G,S,P,O)
  2567. values (g_iid, iri_to_id (s_uri), p_iid,
  2568. DB.DBA.RDF_MAKE_OBJ_OF_TYPEDSQLVAL_FT (
  2569. o_val,
  2570. iri_to_id (o_type),
  2571. case (isstring (o_lang)) when 0 then null else o_lang end,
  2572. g_iid, p_iid, ro_id_dict ) );
  2573. return;
  2574. }
  2575. if (isstring (o_lang))
  2576. {
  2577. insert soft DB.DBA.RDF_QUAD (G,S,P,O)
  2578. values (g_iid, iri_to_id (s_uri), p_iid,
  2579. DB.DBA.RDF_MAKE_OBJ_OF_TYPEDSQLVAL_FT (o_val, NULL, o_lang, g_iid, p_iid, ro_id_dict) );
  2580. return;
  2581. }
  2582. if (isstring (o_val) or (__tag of XML = __tag (o_val)))
  2583. {
  2584. insert soft DB.DBA.RDF_QUAD (G,S,P,O)
  2585. values (g_iid, iri_to_id (s_uri), p_iid,
  2586. DB.DBA.RDF_MAKE_OBJ_OF_SQLVAL_FT (o_val, g_iid, p_iid, ro_id_dict) );
  2587. }
  2588. else
  2589. {
  2590. insert soft DB.DBA.RDF_QUAD (G,S,P,O)
  2591. values (g_iid, iri_to_id (s_uri), p_iid,
  2592. o_val );
  2593. }
  2594. }
  2595. ;
  2596. create procedure DB.DBA.TTLP_EV_COMMIT (inout g varchar, inout app_env any) {
  2597. -- dbg_obj_princ ('DB.DBA.TTLP_COMMIT(', g, app_env, ')');
  2598. declare log_mode integer;
  2599. declare ro_id_dict any;
  2600. log_mode := app_env[0];
  2601. ro_id_dict := app_env[1];
  2602. if (ro_id_dict is not null)
  2603. DB.DBA.RDF_OBJ_ADD_KEYWORD_FOR_GRAPH (iri_to_id (g), ro_id_dict);
  2604. }
  2605. ;
  2606. create procedure DB.DBA.TTLP_EV_REPORT_DEFAULT (
  2607. inout msg_no integer, inout msg_type varchar,
  2608. inout src varchar, inout base varchar, inout graph varchar,
  2609. inout line_no integer, inout triple_no integer,
  2610. inout sstate varchar, inout smore varchar, inout descr varchar,
  2611. inout env any )
  2612. {
  2613. -- dbg_obj_princ ('DB.DBA.TTLP_EV_REPORT_DEFAULT (', msg_no, msg_type, src, base, graph, line_no, triple_no, sstate, smore, descr, env, ')');
  2614. ;
  2615. }
  2616. ;
  2617. create procedure DB.DBA.TTLP_EV_TRIPLE_XLAT (
  2618. inout g_iid IRI_ID, inout s_uri varchar, inout p_uri varchar,
  2619. inout o_uri varchar,
  2620. inout app_env any )
  2621. {
  2622. declare xlat_cbk, s_xlat, o_xlat varchar;
  2623. declare xlat_env any;
  2624. -- dbg_obj_princ ('DB.DBA.TTLP_EV_TRIPLE_XLAT (', g_iid, s_uri, p_uri, o_uri, ');');
  2625. xlat_cbk := app_env[4];
  2626. xlat_env := app_env[5];
  2627. s_xlat := call(xlat_cbk)(s_uri, xlat_env);
  2628. o_xlat := call(xlat_cbk)(o_uri, xlat_env);
  2629. DB.DBA.TTLP_EV_TRIPLE (g_iid, s_xlat, p_uri, o_xlat, app_env);
  2630. }
  2631. ;
  2632. create procedure DB.DBA.TTLP_EV_TRIPLE_L_XLAT (
  2633. inout g_iid IRI_ID, inout s_uri varchar, inout p_uri varchar,
  2634. inout o_val any, inout o_type varchar, inout o_lang varchar,
  2635. inout app_env any )
  2636. {
  2637. declare xlat_cbk, s_xlat varchar;
  2638. declare xlat_env any;
  2639. -- dbg_obj_princ ('DB.DBA.TTLP_EV_TRIPLE_L_XLAT (', g_iid, s_uri, p_uri, o_val, o_type, o_lang, app_env, ');');
  2640. xlat_cbk := app_env[4];
  2641. xlat_env := app_env[5];
  2642. s_xlat := call(xlat_cbk)(s_uri, xlat_env);
  2643. DB.DBA.TTLP_EV_TRIPLE_L (g_iid, s_xlat, p_uri, o_val, o_type, o_lang, app_env);
  2644. }
  2645. ;
  2646. --!AWK PUBLIC
  2647. create procedure DB.DBA.TTLP_XLAT_CONCAT (
  2648. inout iri varchar, inout env any )
  2649. {
  2650. if (__tag (iri) <> __tag of varchar)
  2651. return iri;
  2652. if (iri like 'http://%')
  2653. return concat (env, subseq (iri, 7));
  2654. return iri;
  2655. }
  2656. ;
  2657. create procedure DB.DBA.TTLP (in strg varchar, in base varchar, in graph varchar := null, in flags integer := 0,
  2658. in log_enable int := null, in transactional int := 0)
  2659. {
  2660. declare app_env any;
  2661. declare old_log_mode int;
  2662. declare ret any;
  2663. if (graph = '')
  2664. signal ('22023', 'Empty string is not a valid graph IRI in DB.DBA.TTLP()');
  2665. else if (graph is null)
  2666. {
  2667. graph := base;
  2668. if ((graph is null) or (graph = ''))
  2669. signal ('22023', 'DB.DBA.TTLP() requires a valid IRI as a base argument if graph is not specified');
  2670. }
  2671. old_log_mode := null;
  2672. if (transactional = 0)
  2673. {
  2674. if (log_enable = 0 or log_enable = 1)
  2675. log_enable := log_enable + 2;
  2676. }
  2677. if (log_enable is not null)
  2678. {
  2679. old_log_mode := log_enable (log_enable, 1);
  2680. }
  2681. if (1 <> sys_stat ('cl_run_local_only'))
  2682. {
  2683. DB.DBA.TTLP_CL (strg, 0, base, graph, flags);
  2684. return;
  2685. }
  2686. if (1 = sys_stat ('enable_vec') and not is_atomic ())
  2687. {
  2688. DB.DBA.TTLP_V (strg, base, graph, flags, 3, log_enable => log_enable, transactional => transactional);
  2689. return;
  2690. }
  2691. if (126 = __tag (strg))
  2692. strg := cast (strg as varchar);
  2693. app_env := vector (flags, null, __max (length (strg) / 100, 100000), null);
  2694. ret := rdf_load_turtle (strg, base, graph, flags,
  2695. vector (
  2696. 'DB.DBA.TTLP_EV_NEW_GRAPH',
  2697. 'DB.DBA.TTLP_EV_NEW_BLANK',
  2698. 'DB.DBA.TTLP_EV_GET_IID',
  2699. 'DB.DBA.TTLP_EV_TRIPLE',
  2700. 'DB.DBA.TTLP_EV_TRIPLE_L',
  2701. 'DB.DBA.TTLP_EV_COMMIT',
  2702. 'DB.DBA.TTLP_EV_REPORT_DEFAULT' ),
  2703. app_env);
  2704. if (__rdf_graph_is_in_enabled_repl (iri_to_id (graph)))
  2705. repl_text ('__rdf_repl', '__rdf_repl_flush_queue ()');
  2706. return ret;
  2707. }
  2708. ;
  2709. create procedure DB.DBA.TTLP_WITH_IRI_TRANSLATION (in strg varchar, in base varchar, in graph varchar, in flags integer,
  2710. in log_enable integer, in transactional integer,
  2711. in iri_xlate_cbk varchar, in iri_xlate_env any )
  2712. {
  2713. declare app_env any;
  2714. declare old_log_mode int;
  2715. if (graph = '')
  2716. signal ('22023', 'Empty string is not a valid graph IRI in DB.DBA.TTLP()');
  2717. else if (graph is null)
  2718. {
  2719. graph := base;
  2720. if ((graph is null) or (graph = ''))
  2721. signal ('22023', 'DB.DBA.TTLP() requires a valid IRI as a base argument if graph is not specified');
  2722. }
  2723. old_log_mode := null;
  2724. if (transactional = 0)
  2725. {
  2726. if (log_enable = 0 or log_enable = 1)
  2727. log_enable := log_enable + 2;
  2728. }
  2729. if (log_enable is not null)
  2730. {
  2731. old_log_mode := log_enable (log_enable, 1);
  2732. }
  2733. if (1 <> sys_stat ('cl_run_local_only'))
  2734. {
  2735. DB.DBA.TTLP_CL (strg, 0, base, graph, flags);
  2736. return;
  2737. }
  2738. if (126 = __tag (strg))
  2739. strg := cast (strg as varchar);
  2740. app_env := vector (flags, null, __max (length (strg) / 100, 100000), null, iri_xlate_cbk, iri_xlate_env);
  2741. return rdf_load_turtle (strg, base, graph, flags,
  2742. vector (
  2743. 'DB.DBA.TTLP_EV_NEW_GRAPH',
  2744. 'DB.DBA.TTLP_EV_NEW_BLANK',
  2745. 'DB.DBA.TTLP_EV_GET_IID',
  2746. 'DB.DBA.TTLP_EV_TRIPLE_XLAT',
  2747. 'DB.DBA.TTLP_EV_TRIPLE_L_XLAT',
  2748. 'DB.DBA.TTLP_EV_COMMIT',
  2749. 'DB.DBA.TTLP_EV_REPORT_DEFAULT' ),
  2750. app_env);
  2751. }
  2752. ;
  2753. create procedure DB.DBA.TTLP_VALIDATE (in strg varchar, in base varchar, in graph varchar := null, in flags integer := 0, in report_cbk varchar := '')
  2754. {
  2755. declare app_env any;
  2756. declare old_log_mode int;
  2757. if (126 = __tag (strg))
  2758. strg := cast (strg as varchar);
  2759. return rdf_load_turtle (strg, base, graph, flags,
  2760. vector ('', '', '', '', '', '', report_cbk),
  2761. app_env);
  2762. }
  2763. ;
  2764. create procedure DB.DBA.TTLP_VALIDATE_LOCAL_FILE (in strg varchar, in base varchar, in graph varchar := null, in flags integer := 0, in report_cbk varchar := '')
  2765. {
  2766. declare app_env any;
  2767. declare old_log_mode int;
  2768. if (126 = __tag (strg))
  2769. strg := cast (strg as varchar);
  2770. return rdf_load_turtle_local_file (strg, base, graph, flags,
  2771. vector ('', '', '', '', '', '', report_cbk),
  2772. app_env);
  2773. }
  2774. ;
  2775. create procedure DB.DBA.RDF_VALIDATE_RDFXML (in strg varchar, in base varchar, in graph varchar)
  2776. {
  2777. declare app_env any;
  2778. declare old_log_mode int;
  2779. if (graph = '')
  2780. signal ('22023', 'Empty string is not a valid graph IRI in DB.DBA.RDF_VALIDATE_RDFXML()');
  2781. else if (graph is null)
  2782. {
  2783. graph := base;
  2784. if ((graph is null) or (graph = ''))
  2785. signal ('22023', 'DB.DBA.RDF_VALIDATE_RDFXML() requires a valid IRI as a base argument if graph is not specified');
  2786. }
  2787. rdf_load_rdfxml (strg, 0, graph, vector ( '', '', '', '', '', '', '' ), app_env, base );
  2788. return graph;
  2789. }
  2790. ;
  2791. create procedure DB.DBA.RDF_TTL2HASH_EXEC_NEW_GRAPH (inout g varchar, inout g_iid IRI_ID, inout app_env any) {
  2792. -- dbg_obj_princ ('DB.DBA.RDF_TTL2HASH_EXEC_NEW_GRAPH(', g, g_iid, app_env, ')');
  2793. ;
  2794. }
  2795. ;
  2796. create procedure DB.DBA.RDF_TTL2HASH_EXEC_NEW_BLANK (inout g_iid IRI_ID, inout app_env any, inout res IRI_ID) {
  2797. res := iri_id_from_num (sequence_next ('RDF_URL_IID_BLANK'));
  2798. -- dbg_obj_princ ('DB.DBA.RDF_TTL2HASH_EXEC_NEW_BLANK (', g_iid, app_env, ') returns ', res);
  2799. }
  2800. ;
  2801. create procedure DB.DBA.RDF_TTL2HASH_EXEC_GET_IID (inout uri varchar, inout g_iid IRI_ID, inout app_env any, inout res IRI_ID) {
  2802. -- dbg_obj_princ ('DB.DBA.RDF_TTL2HASH_EXEC_GET_IID (', uri, g_iid, app_env, ')');
  2803. res := iri_to_id (uri);
  2804. -- dbg_obj_princ ('DB.DBA.RDF_TTL2HASH_EXEC_GET_IID (', uri, g_iid, app_env, ') returns ', res);
  2805. }
  2806. ;
  2807. create procedure DB.DBA.RDF_TTL2HASH_EXEC_TRIPLE (
  2808. inout g_iid IRI_ID, inout s_uri varchar, inout p_uri varchar,
  2809. inout o_uri varchar,
  2810. inout app_env any )
  2811. {
  2812. dict_put (app_env,
  2813. vector (iri_to_id (s_uri), iri_to_id (p_uri), iri_to_id (o_uri)),
  2814. 0 );
  2815. }
  2816. ;
  2817. create procedure DB.DBA.RDF_TTL2HASH_EXEC_TRIPLE_L (
  2818. inout g_iid IRI_ID, inout s_uri varchar, inout p_uri varchar,
  2819. inout o_val any, inout o_type varchar, inout o_lang varchar,
  2820. inout app_env any )
  2821. {
  2822. dict_put (app_env,
  2823. vector (
  2824. iri_to_id (s_uri),
  2825. iri_to_id (p_uri),
  2826. DB.DBA.RDF_MAKE_LONG_OF_TYPEDSQLVAL_STRINGS (o_val,
  2827. case when (isstring (o_type) or isuname (o_type)) then o_type else null end,
  2828. case when (isstring (o_lang) or isuname (o_lang)) then o_lang else null end) ),
  2829. 0 );
  2830. }
  2831. ;
  2832. create procedure DB.DBA.RDF_TTL2HASH_EXEC_TRIPLE_XLAT (
  2833. inout g_iid IRI_ID, inout s_uri varchar, inout p_uri varchar,
  2834. inout o_uri varchar,
  2835. inout app_env any )
  2836. {
  2837. declare xlat_cbk, s_xlat, o_xlat varchar;
  2838. declare xlat_env, dict any;
  2839. -- dbg_obj_princ (current_proc_name (), ' (', g_iid, s_uri, p_uri, o_uri, ');');
  2840. dict := app_env[0];
  2841. xlat_cbk := app_env[1];
  2842. xlat_env := app_env[2];
  2843. if (__proc_params_num (xlat_cbk) = 2)
  2844. {
  2845. s_xlat := call(xlat_cbk)(s_uri, xlat_env);
  2846. o_xlat := call(xlat_cbk)(o_uri, xlat_env);
  2847. }
  2848. else
  2849. {
  2850. s_xlat := call(xlat_cbk)(s_uri, p_uri, 's', xlat_env);
  2851. o_xlat := call(xlat_cbk)(o_uri, p_uri, 'o', xlat_env);
  2852. }
  2853. dict_put (dict, vector (iri_to_id (s_xlat), iri_to_id (p_uri), iri_to_id (o_xlat)), 0);
  2854. }
  2855. ;
  2856. create procedure DB.DBA.RDF_TTL2HASH_EXEC_TRIPLE_L_XLAT (
  2857. inout g_iid IRI_ID, inout s_uri varchar, inout p_uri varchar,
  2858. inout o_val any, inout o_type varchar, inout o_lang varchar,
  2859. inout app_env any )
  2860. {
  2861. declare xlat_cbk, s_xlat, o_xlat varchar;
  2862. declare xlat_env, dict any;
  2863. -- dbg_obj_princ (current_proc_name (),' (', g_iid, s_uri, p_uri, o_uri, ');');
  2864. dict := app_env[0];
  2865. xlat_cbk := app_env[1];
  2866. xlat_env := app_env[2];
  2867. if (__proc_params_num (xlat_cbk) = 2)
  2868. s_xlat := call(xlat_cbk)(s_uri, xlat_env);
  2869. else
  2870. s_xlat := call(xlat_cbk)(s_uri, p_uri, 's', xlat_env);
  2871. dict_put (dict,
  2872. vector (
  2873. iri_to_id (s_xlat),
  2874. iri_to_id (p_uri),
  2875. DB.DBA.RDF_MAKE_LONG_OF_TYPEDSQLVAL_STRINGS (o_val,
  2876. case when (isstring (o_type) or __tag (o_type) = 217) then o_type else null end,
  2877. case when (isstring (o_lang) or __tag (o_lang) = 217) then o_lang else null end) ),
  2878. 0);
  2879. }
  2880. ;
  2881. create function DB.DBA.RDF_TTL2HASH (in strg varchar, in base varchar, in graph varchar := null, in flags integer := 0) returns any
  2882. {
  2883. declare res any;
  2884. res := dict_new ();
  2885. if (126 = __tag (strg))
  2886. strg := cast (strg as varchar);
  2887. res := dict_new (length (strg) / 100);
  2888. rdf_load_turtle (strg, base, graph, flags,
  2889. vector (
  2890. 'DB.DBA.RDF_TTL2HASH_EXEC_NEW_GRAPH',
  2891. 'DB.DBA.RDF_TTL2HASH_EXEC_NEW_BLANK',
  2892. 'DB.DBA.RDF_TTL2HASH_EXEC_GET_IID',
  2893. 'DB.DBA.RDF_TTL2HASH_EXEC_TRIPLE',
  2894. 'DB.DBA.RDF_TTL2HASH_EXEC_TRIPLE_L',
  2895. '',
  2896. 'DB.DBA.TTLP_EV_REPORT_DEFAULT' ),
  2897. res);
  2898. return res;
  2899. }
  2900. ;
  2901. create function DB.DBA.RDF_TTL_LOAD_DICT (in strg varchar, in base varchar, in graph varchar, in dict any, in flags integer := 0) returns any
  2902. {
  2903. if (__tag (dict) <> 214)
  2904. signal ('22023', 'RDFXX', 'The dict argument must be of type dictionary');
  2905. if (126 = __tag (strg))
  2906. strg := cast (strg as varchar);
  2907. rdf_load_turtle (strg, base, graph, flags,
  2908. vector (
  2909. 'DB.DBA.RDF_TTL2HASH_EXEC_NEW_GRAPH',
  2910. 'DB.DBA.RDF_TTL2HASH_EXEC_NEW_BLANK',
  2911. 'DB.DBA.RDF_TTL2HASH_EXEC_GET_IID',
  2912. 'DB.DBA.RDF_TTL2HASH_EXEC_TRIPLE',
  2913. 'DB.DBA.RDF_TTL2HASH_EXEC_TRIPLE_L',
  2914. '',
  2915. 'DB.DBA.TTLP_EV_REPORT_DEFAULT' ),
  2916. dict);
  2917. return;
  2918. }
  2919. ;
  2920. create procedure DB.DBA.RDF_TTL2SQLHASH_EXEC_GET_IID (inout uri varchar, inout g_iid IRI_ID, inout app_env any, inout res IRI_ID) {
  2921. -- dbg_obj_princ ('DB.DBA.RDF_TTL2SQLHASH_EXEC_GET_IID (', uri, g_iid, app_env, ')');
  2922. res := __bft (uri, 1);
  2923. -- dbg_obj_princ ('DB.DBA.RDF_TTL2SQLHASH_EXEC_GET_IID (', uri, g_iid, app_env, ') returns ', res);
  2924. }
  2925. ;
  2926. create procedure DB.DBA.RDF_TTL2SQLHASH_EXEC_TRIPLE (
  2927. inout g_iid IRI_ID, inout s_uri varchar, inout p_uri varchar,
  2928. inout o_uri varchar,
  2929. inout app_env any )
  2930. {
  2931. dict_put (app_env,
  2932. vector (
  2933. __bft (s_uri, 1),
  2934. __bft (p_uri, 1),
  2935. __bft (o_uri, 1) ),
  2936. 0 );
  2937. }
  2938. ;
  2939. create procedure DB.DBA.RDF_TTL2SQLHASH_EXEC_TRIPLE_L (
  2940. inout g_iid IRI_ID, inout s_uri varchar, inout p_uri varchar,
  2941. inout o_val any, inout o_type varchar, inout o_lang varchar,
  2942. inout app_env any )
  2943. {
  2944. dict_put (app_env,
  2945. vector (
  2946. __bft (s_uri, 1),
  2947. __bft (p_uri, 1),
  2948. DB.DBA.RDF_MAKE_LONG_OF_TYPEDSQLVAL_STRINGS (o_val,
  2949. case when (isstring (o_type) or isuname (o_type)) then o_type else null end,
  2950. case when (isstring (o_lang) or isuname (o_lang)) then o_lang else null end) ),
  2951. 0 );
  2952. }
  2953. ;
  2954. create function DB.DBA.RDF_TTL2SQLHASH (in strg varchar, in base varchar, in graph varchar := null, in flags integer := 0) returns any
  2955. {
  2956. declare res any;
  2957. res := dict_new ();
  2958. if (126 = __tag (strg))
  2959. strg := cast (strg as varchar);
  2960. res := dict_new (length (strg) / 100);
  2961. rdf_load_turtle (strg, base, graph, flags,
  2962. vector (
  2963. 'DB.DBA.RDF_TTL2HASH_EXEC_NEW_GRAPH',
  2964. 'DB.DBA.RDF_TTL2HASH_EXEC_NEW_BLANK',
  2965. 'DB.DBA.RDF_TTL2SQLHASH_EXEC_GET_IID',
  2966. 'DB.DBA.RDF_TTL2SQLHASH_EXEC_TRIPLE',
  2967. 'DB.DBA.RDF_TTL2SQLHASH_EXEC_TRIPLE_L',
  2968. '',
  2969. 'DB.DBA.TTLP_EV_REPORT_DEFAULT' ),
  2970. res);
  2971. return res;
  2972. }
  2973. ;
  2974. create procedure DB.DBA.RDF_LOAD_RDFXML_IMPL (inout strg varchar, in base varchar, in graph varchar,
  2975. in parse_mode integer, in log_enable int := null, in transactional int := 0)
  2976. {
  2977. declare app_env any;
  2978. declare old_log_mode int;
  2979. if (graph = '')
  2980. signal ('22023', 'Empty string is not a valid graph IRI in DB.DBA.RDF_LOAD_RDFXML() and the like');
  2981. else if (graph is null)
  2982. {
  2983. graph := base;
  2984. if ((graph is null) or (graph = ''))
  2985. signal ('22023', 'DB.DBA.RDF_LOAD_RDFXML() and similar functions require a valid IRI as a base argument if graph is not specified');
  2986. }
  2987. old_log_mode := null;
  2988. if (transactional = 0)
  2989. {
  2990. if (log_enable = 0 or log_enable = 1)
  2991. log_enable := log_enable + 2;
  2992. }
  2993. if (log_enable is not null)
  2994. {
  2995. old_log_mode := log_enable (log_enable, 1);
  2996. }
  2997. if (1 <> sys_stat ('cl_run_local_only'))
  2998. return DB.DBA.RDF_LOAD_RDFXML_CL (strg, base, graph, parse_mode);
  2999. if (not is_atomic ())
  3000. return db.dba.rdf_load_rdfxml_v (strg, base, graph, transactional => transactional, log_mode => log_enable, parse_mode => parse_mode);
  3001. app_env := vector (
  3002. null,
  3003. null,
  3004. __max (length (strg) / 100, 100000),
  3005. null );
  3006. rdf_load_rdfxml (strg, parse_mode,
  3007. graph,
  3008. vector (
  3009. 'DB.DBA.TTLP_EV_NEW_GRAPH',
  3010. 'DB.DBA.TTLP_EV_NEW_BLANK',
  3011. 'DB.DBA.TTLP_EV_GET_IID',
  3012. 'DB.DBA.TTLP_EV_TRIPLE',
  3013. 'DB.DBA.TTLP_EV_TRIPLE_L',
  3014. 'DB.DBA.TTLP_EV_COMMIT',
  3015. 'DB.DBA.TTLP_EV_REPORT_DEFAULT' ),
  3016. app_env,
  3017. base );
  3018. if (__rdf_graph_is_in_enabled_repl (iri_to_id (graph)))
  3019. repl_text ('__rdf_repl', '__rdf_repl_flush_queue ()');
  3020. return graph;
  3021. }
  3022. ;
  3023. create procedure DB.DBA.RDF_LOAD_RDFXML (in strg varchar, in base varchar, in graph varchar := null,
  3024. in xml_parse_mode integer := 0, in log_enable int := null, in transactional int := 0 )
  3025. {
  3026. return DB.DBA.RDF_LOAD_RDFXML_IMPL (strg, base, graph, bit_shift (xml_parse_mode, 8), log_enable, transactional);
  3027. }
  3028. ;
  3029. create procedure DB.DBA.RDF_RDFXML_TO_DICT (in strg varchar, in base varchar, in graph varchar := null)
  3030. {
  3031. declare res any;
  3032. res := dict_new (length (strg) / 100);
  3033. rdf_load_rdfxml (strg, 0,
  3034. graph,
  3035. vector (
  3036. 'DB.DBA.RDF_TTL2HASH_EXEC_NEW_GRAPH',
  3037. 'DB.DBA.RDF_TTL2HASH_EXEC_NEW_BLANK',
  3038. 'DB.DBA.RDF_TTL2HASH_EXEC_GET_IID',
  3039. 'DB.DBA.RDF_TTL2HASH_EXEC_TRIPLE',
  3040. 'DB.DBA.RDF_TTL2HASH_EXEC_TRIPLE_L',
  3041. '',
  3042. 'DB.DBA.TTLP_EV_REPORT_DEFAULT' ),
  3043. res,
  3044. base );
  3045. return res;
  3046. }
  3047. ;
  3048. create procedure DB.DBA.RDF_RDFXML_LOAD_DICT (in strg varchar, in base varchar, in graph varchar, inout dict any, in flag int := 0, in xml_parse_mode int := 0)
  3049. {
  3050. if (__tag (dict) <> 214)
  3051. signal ('22023', 'RDFXX', 'The dict argument must be of type dictionary');
  3052. if (flag = 0)
  3053. xml_parse_mode := 0;
  3054. rdf_load_rdfxml (strg, bit_or (flag, bit_shift (xml_parse_mode, 8)), -- 0 rdfxml, 2 rdfa
  3055. graph,
  3056. vector (
  3057. 'DB.DBA.RDF_TTL2HASH_EXEC_NEW_GRAPH',
  3058. 'DB.DBA.RDF_TTL2HASH_EXEC_NEW_BLANK',
  3059. 'DB.DBA.RDF_TTL2HASH_EXEC_GET_IID',
  3060. 'DB.DBA.RDF_TTL2HASH_EXEC_TRIPLE',
  3061. 'DB.DBA.RDF_TTL2HASH_EXEC_TRIPLE_L',
  3062. '',
  3063. 'DB.DBA.TTLP_EV_REPORT_DEFAULT' ),
  3064. dict,
  3065. base );
  3066. }
  3067. ;
  3068. create procedure DB.DBA.RDFA_LOAD_DICT (in strg varchar, in base varchar, in graph varchar, inout dict any, in xml_parse_mode int := 0)
  3069. {
  3070. declare app_env any;
  3071. if (__tag (dict) <> 214)
  3072. signal ('22023', 'RDFXX', 'The dict argument must be of type dictionary');
  3073. rdf_load_rdfxml (strg, bit_or (2, bit_shift (xml_parse_mode, 8)), -- 0 rdfxml, 2 rdfa
  3074. graph,
  3075. vector (
  3076. 'DB.DBA.RDF_TTL2HASH_EXEC_NEW_GRAPH',
  3077. 'DB.DBA.RDF_TTL2HASH_EXEC_NEW_BLANK',
  3078. 'DB.DBA.RDF_TTL2HASH_EXEC_GET_IID',
  3079. 'DB.DBA.RDF_TTL2HASH_EXEC_TRIPLE',
  3080. 'DB.DBA.RDF_TTL2HASH_EXEC_TRIPLE_L',
  3081. '',
  3082. 'DB.DBA.TTLP_EV_REPORT_DEFAULT'),
  3083. dict,
  3084. base );
  3085. }
  3086. ;
  3087. create procedure DB.DBA.RDFA_LOAD_DICT_XLAT (in strg varchar, in base varchar, in graph varchar, inout dict any, in xml_parse_mode int := 0, in iri_xlate_cbk varchar, in iri_xlate_env any)
  3088. {
  3089. declare app_env any;
  3090. if (__tag (dict) <> 214)
  3091. signal ('22023', 'RDFXX', 'The dict argument must be of type dictionary');
  3092. rdf_load_rdfxml (strg, bit_or (2, bit_shift (xml_parse_mode, 8)), -- 0 rdfxml, 2 rdfa
  3093. graph,
  3094. vector (
  3095. 'DB.DBA.RDF_TTL2HASH_EXEC_NEW_GRAPH',
  3096. 'DB.DBA.RDF_TTL2HASH_EXEC_NEW_BLANK',
  3097. 'DB.DBA.RDF_TTL2HASH_EXEC_GET_IID',
  3098. 'DB.DBA.RDF_TTL2HASH_EXEC_TRIPLE_XLAT',
  3099. 'DB.DBA.RDF_TTL2HASH_EXEC_TRIPLE_L_XLAT',
  3100. '',
  3101. 'DB.DBA.TTLP_EV_REPORT_DEFAULT' ),
  3102. vector (dict, iri_xlate_cbk, iri_xlate_env),
  3103. base );
  3104. }
  3105. ;
  3106. create procedure DB.DBA.RDF_RDFA11_FETCH_PROFILES (in profile_iris any, inout prefixes any, inout terms any, inout vocab any)
  3107. {
  3108. declare agg any;
  3109. -- dbg_obj_princ ('DB.DBA.RDF_RDFA11_FETCH_PROFILES (', profile_iris, ')');
  3110. foreach (varchar profile_iri in profile_iris) do
  3111. {
  3112. if (not exists (sparql define input:storage "" ask where { graph `iri(?:profile_iri)` { ?s ?p ?o }}))
  3113. DB.DBA.SPARUL_LOAD (profile_iri, profile_iri, 0, NULL, 0);
  3114. }
  3115. vectorbld_init (agg);
  3116. foreach (varchar profile_iri in profile_iris) do
  3117. {
  3118. for (sparql define input:storage "" prefix rdfa: <http://www.w3.org/ns/rdfa#>
  3119. select ?p, ?u
  3120. where {
  3121. graph `iri(?:profile_iri)` {
  3122. ?s rdfa:prefix ?p ; rdfa:uri ?u .
  3123. optional { ?s rdfa:uri ?u2 . filter (?u != ?u2). }
  3124. filter (isliteral (?p))
  3125. filter (isliteral (?u))
  3126. filter (?u != '')
  3127. filter (!bound (?u2)) } }
  3128. ) do { vectorbld_acc (agg, "p", "u"); }
  3129. }
  3130. vectorbld_final (agg);
  3131. prefixes := agg;
  3132. vectorbld_init (agg);
  3133. foreach (varchar profile_iri in profile_iris) do
  3134. {
  3135. for (sparql define input:storage "" prefix rdfa: <http://www.w3.org/ns/rdfa#>
  3136. select ?t, ?u
  3137. where {
  3138. graph `iri(?:profile_iri)` {
  3139. ?s rdfa:term ?t ; rdfa:uri ?u .
  3140. optional { ?s rdfa:uri ?u2 . filter (?u != ?u2). }
  3141. optional { ?s rdfa:term ?t2 . filter (?t != ?t2). }
  3142. filter (isliteral (?t))
  3143. filter (isliteral (?u))
  3144. filter (?t != '')
  3145. filter (?u != '')
  3146. filter (!bound (?t2))
  3147. filter (!bound (?u2)) } }
  3148. order by ?t
  3149. ) do { vectorbld_acc (agg, "t", "u"); }
  3150. }
  3151. vectorbld_final (agg);
  3152. if (1 < length (profile_iris))
  3153. gvector_sort (agg, 2, 0, 1);
  3154. terms := agg;
  3155. vocab := null;
  3156. foreach (varchar profile_iri in profile_iris) do
  3157. {
  3158. vocab := (sparql define input:storage "" prefix rdfa: <http://www.w3.org/ns/rdfa#>
  3159. select (max(str(?v)))
  3160. where {
  3161. graph `iri(?:profile_iri)` {
  3162. ?s rdfa:vocabulary ?v } } );
  3163. if (isstring (vocab))
  3164. goto vocab_is_set;
  3165. }
  3166. vocab_is_set: ;
  3167. -- dbg_obj_princ ('DB.DBA.RDF_RDFA11_FETCH_PROFILES (', profile_iris, ' returned ', prefixes, terms, vocab);
  3168. }
  3169. ;
  3170. create procedure DB.DBA.RDF_LOAD_RDFA (in strg varchar, in base varchar, in graph varchar := null,
  3171. in xml_parse_mode integer := 0, in log_enable int := null, in transactional int := 0 )
  3172. {
  3173. return DB.DBA.RDF_LOAD_RDFXML_IMPL (strg, base, graph, bit_or (2, bit_shift (xml_parse_mode, 8)), log_enable, transactional);
  3174. }
  3175. ;
  3176. create procedure DB.DBA.RDF_LOAD_RDFA_WITH_IRI_TRANSLATION (in strg varchar, in base varchar, in graph varchar, in xml_parse_mode integer,
  3177. in iri_xlate_cbk varchar, in iri_xlate_env any)
  3178. {
  3179. declare app_env any;
  3180. if (graph = '')
  3181. signal ('22023', 'Empty string is not a valid graph IRI in DB.DBA.RDF_LOAD_RDFA_WITH_IRI_TRANSLATION ()');
  3182. else if (graph is null)
  3183. {
  3184. graph := base;
  3185. if ((graph is null) or (graph = ''))
  3186. signal ('22023', 'DB.DBA.RDF_LOAD_RDFA_WITH_IRI_TRANSLATION () requires a valid IRI as a base argument if graph is not specified');
  3187. }
  3188. if (1 <> sys_stat ('cl_run_local_only'))
  3189. return DB.DBA.RDF_LOAD_RDFA_WITH_IRI_TRANSLATION_CL (strg, base, graph, xml_parse_mode, iri_xlate_cbk, iri_xlate_env);
  3190. app_env := vector (
  3191. null,
  3192. null,
  3193. __max (length (strg) / 100, 100000),
  3194. null,
  3195. iri_xlate_cbk,
  3196. iri_xlate_env );
  3197. rdf_load_rdfxml (strg, bit_or (2, bit_shift (xml_parse_mode, 8)),
  3198. graph,
  3199. vector (
  3200. 'DB.DBA.TTLP_EV_NEW_GRAPH',
  3201. 'DB.DBA.TTLP_EV_NEW_BLANK',
  3202. 'DB.DBA.TTLP_EV_GET_IID',
  3203. 'DB.DBA.TTLP_EV_TRIPLE_XLAT',
  3204. 'DB.DBA.TTLP_EV_TRIPLE_L_XLAT',
  3205. 'DB.DBA.TTLP_EV_COMMIT',
  3206. 'DB.DBA.TTLP_EV_REPORT_DEFAULT' ),
  3207. app_env,
  3208. base );
  3209. if (__rdf_graph_is_in_enabled_repl (iri_to_id (graph)))
  3210. repl_text ('__rdf_repl', '__rdf_repl_flush_queue ()');
  3211. return graph;
  3212. }
  3213. ;
  3214. create procedure DB.DBA.RDF_RDFA_TO_DICT (in strg varchar, in base varchar, in graph varchar := null)
  3215. {
  3216. declare res any;
  3217. res := dict_new (length (strg) / 100);
  3218. rdf_load_rdfxml (strg, 2,
  3219. graph,
  3220. vector (
  3221. 'DB.DBA.RDF_TTL2HASH_EXEC_NEW_GRAPH',
  3222. 'DB.DBA.RDF_TTL2HASH_EXEC_NEW_BLANK',
  3223. 'DB.DBA.RDF_TTL2HASH_EXEC_GET_IID',
  3224. 'DB.DBA.RDF_TTL2HASH_EXEC_TRIPLE',
  3225. 'DB.DBA.RDF_TTL2HASH_EXEC_TRIPLE_L',
  3226. '',
  3227. 'DB.DBA.TTLP_EV_REPORT_DEFAULT' ),
  3228. res,
  3229. base );
  3230. return res;
  3231. }
  3232. ;
  3233. create procedure DB.DBA.RDF_LOAD_XHTML_MICRODATA (in strg varchar, in base varchar, in graph varchar := null,
  3234. in xml_parse_mode integer := 1, in log_enable int := null, in transactional int := 0 )
  3235. {
  3236. return DB.DBA.RDF_LOAD_RDFXML_IMPL (strg, base, graph, bit_or (4, bit_shift (xml_parse_mode, 8)), log_enable, transactional);
  3237. }
  3238. ;
  3239. -----
  3240. -- Fast rewriting from serialization to serialization without storing
  3241. --!AWK PUBLIC
  3242. create procedure DB.DBA.RDF_XML_IRI_TO_TTL (inout obj any, inout ses any)
  3243. {
  3244. declare res varchar;
  3245. if (isiri_id (obj))
  3246. {
  3247. if (obj >= min_bnode_iri_id ())
  3248. {
  3249. if (obj >= #ib0)
  3250. http (sprintf ('_:bb%d ', iri_id_num (obj) - iri_id_num (#ib0)), ses);
  3251. else
  3252. http (sprintf ('_:b%d ', iri_id_num (obj)), ses);
  3253. }
  3254. else
  3255. {
  3256. res := coalesce (id_to_iri (obj), sprintf ('_:bad_iid_%d', iri_id_num (obj)));
  3257. -- res := coalesce ((select RU_QNAME from DB.DBA.RDF_URL where RU_IID = obj), sprintf ('_:bad_iid_%d', iri_id_num (obj)));
  3258. http ('<', ses);
  3259. http_escape (res, 12, ses, 1, 1);
  3260. http ('> ', ses);
  3261. }
  3262. }
  3263. else if (__tag of varchar = __tag (obj))
  3264. {
  3265. if ("LEFT" (obj, 9) = 'nodeID://')
  3266. {
  3267. http ('_:', ses);
  3268. http (subseq (obj, 9), ses);
  3269. http (' ', ses);
  3270. }
  3271. else
  3272. {
  3273. http ('<', ses);
  3274. http_escape (obj, 12, ses, 1, 1);
  3275. http ('> ', ses);
  3276. }
  3277. }
  3278. else
  3279. {
  3280. http ('<', ses);
  3281. http_escape (cast (obj as varchar), 12, ses, 1, 1);
  3282. http ('> ', ses);
  3283. }
  3284. }
  3285. ;
  3286. --!AWK PUBLIC
  3287. create procedure DB.DBA.RDF_XML_OBJ_TO_TTL (
  3288. inout o_val any, inout o_type varchar, inout o_lang varchar,
  3289. inout ses any)
  3290. {
  3291. declare res varchar;
  3292. if (isiri_id (o_val))
  3293. {
  3294. if (o_val >= min_bnode_iri_id ())
  3295. {
  3296. if (o_val >= #ib0)
  3297. http (sprintf ('_:bb%d ', iri_id_num (o_val) - iri_id_num (#ib0)), ses);
  3298. else
  3299. http (sprintf ('_:b%d ', iri_id_num (o_val)), ses);
  3300. }
  3301. else
  3302. {
  3303. res := coalesce (id_to_iri (o_val), sprintf ('_:bad_iid_%d', iri_id_num (o_val)));
  3304. http ('<', ses);
  3305. http_escape (res, 12, ses, 1, 1);
  3306. http ('> ', ses);
  3307. }
  3308. return;
  3309. }
  3310. http ('"', ses);
  3311. if (__tag of XML = o_val)
  3312. http_escape (serialize_to_UTF8_xml (o_val), 11, ses, 1, 1);
  3313. else
  3314. http_escape (o_val, 11, ses, 1, 1);
  3315. if (isstring (o_type))
  3316. {
  3317. http ('"^^<', ses);
  3318. http_escape (o_type, 12, ses, 1, 1);
  3319. http ('> ', ses);
  3320. }
  3321. else if (isstring (o_lang))
  3322. {
  3323. http ('"@', ses);
  3324. http (o_lang, ses);
  3325. http (' ', ses);
  3326. }
  3327. else
  3328. http ('" ', ses);
  3329. }
  3330. ;
  3331. --!AWK PUBLIC
  3332. create procedure DB.DBA.RDF_CONVERT_RDFXML_TO_TTL_EV_NEW_BLANK (inout g_iid IRI_ID, inout app_env any, inout res IRI_ID)
  3333. {
  3334. ; -- empty procedure
  3335. }
  3336. ;
  3337. --!AWK PUBLIC
  3338. create procedure DB.DBA.RDF_CONVERT_RDFXML_TO_TTL_EV_TRIPLE (
  3339. inout g_iid IRI_ID, inout s_uri varchar, inout p_uri varchar,
  3340. inout o_uri varchar,
  3341. inout app_env any )
  3342. {
  3343. DB.DBA.RDF_XML_IRI_TO_TTL (s_uri, app_env);
  3344. DB.DBA.RDF_XML_IRI_TO_TTL (p_uri, app_env);
  3345. DB.DBA.RDF_XML_IRI_TO_TTL (o_uri, app_env);
  3346. http ('.\n', app_env);
  3347. }
  3348. ;
  3349. --!AWK PUBLIC
  3350. create procedure DB.DBA.RDF_CONVERT_RDFXML_TO_TTL_EV_TRIPLE_L (
  3351. inout g_iid IRI_ID, inout s_uri varchar, inout p_uri varchar,
  3352. inout o_val any, inout o_type varchar, inout o_lang varchar,
  3353. inout app_env any )
  3354. {
  3355. DB.DBA.RDF_XML_IRI_TO_TTL (s_uri, app_env);
  3356. DB.DBA.RDF_XML_IRI_TO_TTL (p_uri, app_env);
  3357. DB.DBA.RDF_XML_OBJ_TO_TTL (o_val, o_type, o_lang, app_env);
  3358. http ('.\n', app_env);
  3359. }
  3360. ;
  3361. --!AWK PUBLIC
  3362. create procedure DB.DBA.RDF_CONVERT_RDFXML_TO_TTL (in strg varchar, in base varchar, inout ttl_ses any)
  3363. {
  3364. rdf_load_rdfxml (strg, 0,
  3365. 'http://example.com',
  3366. vector (
  3367. '',
  3368. 'DB.DBA.RDF_CONVERT_RDFXML_TO_TTL_EV_NEW_BLANK',
  3369. 'DB.DBA.TTLP_EV_GET_IID',
  3370. 'DB.DBA.RDF_CONVERT_RDFXML_TO_TTL_EV_TRIPLE',
  3371. 'DB.DBA.RDF_CONVERT_RDFXML_TO_TTL_EV_TRIPLE_L',
  3372. '',
  3373. 'DB.DBA.TTLP_EV_REPORT_DEFAULT' ),
  3374. ttl_ses,
  3375. base );
  3376. }
  3377. ;
  3378. --!AWK PUBLIC
  3379. create procedure DB.DBA.RDF_CONVERT_RDFXML_FILE_TO_TTL_FILE (in rdfxml_source_filename varchar, in base varchar, in ttl_target_filename varchar)
  3380. {
  3381. declare in_ses, out_ses any;
  3382. in_ses := file_to_string_output (rdfxml_source_filename);
  3383. out_ses := string_output ();
  3384. DB.DBA.RDF_CONVERT_RDFXML_TO_TTL (in_ses, base, out_ses);
  3385. string_to_file (ttl_target_filename, out_ses, -2);
  3386. }
  3387. ;
  3388. -----
  3389. -- Export into external serializations
  3390. create procedure DB.DBA.RDF_LONG_TO_TTL (inout obj any, inout ses any)
  3391. {
  3392. declare res varchar;
  3393. if (obj is null)
  3394. signal ('RDFXX', 'DB.DBA.RDF_LONG_TO_TTL(): object is NULL');
  3395. if (isiri_id (obj))
  3396. {
  3397. if (obj >= min_bnode_iri_id ())
  3398. {
  3399. if (obj >= #ib0)
  3400. http (sprintf ('_:bb%d ', iri_id_num (obj) - iri_id_num (#ib0)), ses);
  3401. else
  3402. http (sprintf ('_:b%d ', iri_id_num (obj)), ses);
  3403. }
  3404. else
  3405. {
  3406. res := coalesce (id_to_iri (obj), sprintf ('_:bad_iid_%d', iri_id_num (obj)));
  3407. -- res := coalesce ((select RU_QNAME from DB.DBA.RDF_URL where RU_IID = obj), sprintf ('_:bad_iid_%d', iri_id_num (obj)));
  3408. http ('<', ses);
  3409. http_escape (res, 12, ses, 1, 1);
  3410. http ('> ', ses);
  3411. }
  3412. }
  3413. else if (__tag of rdf_box = __tag (obj))
  3414. {
  3415. http ('"', ses);
  3416. if (rdf_box_data_tag (obj) in (__tag of varchar, __tag of long varchar, __tag of nvarchar, __tag of long nvarchar, 185))
  3417. http_escape (__rdf_sqlval_of_obj (obj, 1), 11, ses, 1, 1);
  3418. else if (__tag of datetime = rdf_box_data_tag (obj))
  3419. __rdf_long_to_ttl (obj, ses);
  3420. else if (__tag of XML = rdf_box_data_tag (obj))
  3421. http_escape (serialize_to_UTF8_xml (__rdf_sqlval_of_obj (obj, 1)), 11, ses, 1, 1);
  3422. else if (__tag of varbinary = rdf_box_data_tag (obj))
  3423. {
  3424. http ('"', ses);
  3425. http_escape (__rdf_sqlval_of_obj (obj, 1), 11, ses, 0, 0);
  3426. http ('" ', ses);
  3427. }
  3428. else
  3429. http_escape (cast (__rdf_sqlval_of_obj (obj, 1) as varchar), 11, ses, 1, 1);
  3430. if (257 <> rdf_box_type (obj))
  3431. {
  3432. res := coalesce ((select RDT_QNAME from DB.DBA.RDF_DATATYPE where RDT_TWOBYTE = rdf_box_type (obj)));
  3433. if (res is null)
  3434. signal ('RDFXX', sprintf ('Bad rdf box type (%d), box "%s"', rdf_box_type (obj), cast (rdf_box_data (obj) as varchar)));
  3435. http ('"^^<', ses);
  3436. http_escape (res, 12, ses, 1, 1);
  3437. http ('> ', ses);
  3438. }
  3439. else if (257 <> rdf_box_lang (obj))
  3440. {
  3441. res := coalesce ((select lower (RL_ID) from DB.DBA.RDF_LANGUAGE where RL_TWOBYTE = rdf_box_lang (obj)));
  3442. http ('"@', ses); http (res, ses); http (' ', ses);
  3443. }
  3444. else
  3445. http ('" ', ses);
  3446. }
  3447. else if (__tag of varchar = __tag (obj))
  3448. {
  3449. if (1 = __box_flags (obj))
  3450. {
  3451. http ('<', ses);
  3452. http_escape (obj, 12, ses, 1, 1);
  3453. http ('> ', ses);
  3454. }
  3455. else
  3456. {
  3457. http ('"', ses);
  3458. http_escape (obj, 11, ses, 1, 1);
  3459. http ('" ', ses);
  3460. }
  3461. }
  3462. else if (__tag (obj) in (__tag of long varchar, __tag of nvarchar, __tag of long nvarchar, 185))
  3463. {
  3464. http ('"', ses);
  3465. http_escape (obj, 11, ses, 1, 1);
  3466. http ('" ', ses);
  3467. }
  3468. else if (__tag of datetime = rdf_box_data_tag (obj))
  3469. {
  3470. http ('"', ses);
  3471. __rdf_long_to_ttl (obj, ses);
  3472. http ('"^^<', ses);
  3473. http_escape (cast (__xsd_type (obj) as varchar), 12, ses, 1, 1);
  3474. http ('> ', ses);
  3475. }
  3476. else if (__tag of varbinary = __tag (obj))
  3477. {
  3478. http ('"', ses);
  3479. http_escape (obj, 11, ses, 0, 0);
  3480. http ('" ', ses);
  3481. }
  3482. else
  3483. {
  3484. http ('"', ses);
  3485. http_escape (__rdf_strsqlval (obj), 11, ses, 1, 1);
  3486. http ('"^^<', ses);
  3487. http_escape (cast (__xsd_type (obj) as varchar), 12, ses, 1, 1);
  3488. http ('> ', ses);
  3489. }
  3490. }
  3491. ;
  3492. create procedure DB.DBA.RDF_TRIPLES_TO_VERBOSE_TTL (inout triples any, inout ses any)
  3493. {
  3494. declare tcount, tctr integer;
  3495. declare prev_s, prev_p IRI_ID;
  3496. declare res varchar;
  3497. declare string_subjs_found, string_preds_found integer;
  3498. string_subjs_found := 0;
  3499. string_preds_found := 0;
  3500. tcount := length (triples);
  3501. -- dbg_obj_princ ('DB.DBA.RDF_TRIPLES_TO_VERBOSE_TTL:'); for (tctr := 0; tctr < tcount; tctr := tctr + 1) -- dbg_obj_princ (triples[tctr]);
  3502. if (0 = tcount)
  3503. {
  3504. http ('# Empty TURTLE\n', ses);
  3505. return;
  3506. }
  3507. for (tctr := 0; tctr < tcount; tctr := tctr + 1)
  3508. {
  3509. declare subj,pred any;
  3510. subj := triples[tctr][0];
  3511. pred := triples[tctr][1];
  3512. if (not (isiri_id (subj)))
  3513. {
  3514. if (isstring (subj) and (1 = __box_flags (subj)))
  3515. string_subjs_found := 1;
  3516. else
  3517. {
  3518. if (subj is null)
  3519. signal ('RDFXX', 'DB.DBA.TRIPLES_TO_TTL(): subject is NULL');
  3520. signal ('RDFXX', 'DB.DBA.TRIPLES_TO_TTL(): subject is literal');
  3521. }
  3522. }
  3523. if (not isiri_id (pred))
  3524. {
  3525. if (isstring (pred) and (1 = __box_flags (pred)))
  3526. string_preds_found := 1;
  3527. else
  3528. {
  3529. if (pred is null)
  3530. signal ('RDFXX', 'DB.DBA.TRIPLES_TO_TTL(): predicate is NULL');
  3531. signal ('RDFXX', 'DB.DBA.TRIPLES_TO_TTL(): predicate is literal');
  3532. }
  3533. }
  3534. if (pred >= min_bnode_iri_id ())
  3535. signal ('RDFXX', 'DB.DBA.TRIPLES_TO_TTL(): blank node as predicate');
  3536. }
  3537. if (not string_preds_found)
  3538. rowvector_digit_sort (triples, 1, 1);
  3539. if (not string_subjs_found)
  3540. rowvector_digit_sort (triples, 0, 1);
  3541. DB.DBA.RDF_TRIPLES_BATCH_COMPLETE (triples);
  3542. prev_s := null;
  3543. prev_p := null;
  3544. for (tctr := 0; tctr < tcount; tctr := tctr + 1)
  3545. {
  3546. declare subj,pred,obj any;
  3547. subj := triples[tctr][0];
  3548. pred := triples[tctr][1];
  3549. obj := triples[tctr][2];
  3550. if (prev_s = subj)
  3551. {
  3552. if (prev_p = pred)
  3553. {
  3554. http (',\n\t\t', ses);
  3555. goto print_o;
  3556. }
  3557. http (';\n\t', ses);
  3558. goto print_p;
  3559. }
  3560. if (prev_s is not null)
  3561. http ('.\n', ses);
  3562. if (isstring (subj))
  3563. {
  3564. if (subj like 'nodeID://%')
  3565. {
  3566. http ('_:', ses);
  3567. http_escape (subseq (subj, 9), 12, ses, 1, 1);
  3568. http (' ', ses);
  3569. }
  3570. else
  3571. {
  3572. http ('<', ses);
  3573. http_escape (subj, 12, ses, 1, 1);
  3574. http ('> ', ses);
  3575. }
  3576. }
  3577. else if (subj >= min_bnode_iri_id ())
  3578. {
  3579. if (subj >= #ib0)
  3580. http (sprintf ('_:bb%d ', iri_id_num (subj) - iri_id_num (#ib0)), ses);
  3581. else
  3582. http (sprintf ('_:b%d ', iri_id_num (subj)), ses);
  3583. }
  3584. else
  3585. {
  3586. res := id_to_iri (subj);
  3587. http ('<', ses);
  3588. http_escape (res, 12, ses, 1, 1);
  3589. http ('> ', ses);
  3590. }
  3591. prev_s := subj;
  3592. prev_p := null;
  3593. print_p:
  3594. if (isstring (pred))
  3595. {
  3596. if (pred like 'nodeID://%')
  3597. {
  3598. http ('_:', ses);
  3599. http_escape (subseq (pred, 9), 12, ses, 1, 1);
  3600. http (' ', ses);
  3601. }
  3602. else
  3603. {
  3604. http ('<', ses);
  3605. http_escape (pred, 12, ses, 1, 1);
  3606. http ('> ', ses);
  3607. }
  3608. }
  3609. else
  3610. {
  3611. res := id_to_iri (pred);
  3612. http ('<', ses);
  3613. http_escape (res, 12, ses, 1, 1);
  3614. http ('> ', ses);
  3615. }
  3616. prev_p := pred;
  3617. print_o:
  3618. DB.DBA.RDF_LONG_TO_TTL (obj, ses);
  3619. }
  3620. http ('.\n', ses);
  3621. }
  3622. ;
  3623. create function DB.DBA.RDF_TRIPLES_TO_TTL_ENV (in tcount integer, in env_flags integer, in col_metas any, inout ses any)
  3624. {
  3625. return vector (dict_new (__min (tcount, 16000)), 0, '', '', '', 0, 0, env_flags, col_metas, ses);
  3626. }
  3627. ;
  3628. create procedure DB.DBA.RDF_TRIPLES_TO_TTL (inout triples any, inout ses any)
  3629. {
  3630. declare env any;
  3631. declare tcount, tctr integer;
  3632. tcount := length (triples);
  3633. -- dbg_obj_princ ('DB.DBA.RDF_TRIPLES_TO_TTL:'); for (tctr := 0; tctr < tcount; tctr := tctr + 1) -- dbg_obj_princ (triples[tctr]);
  3634. if (0 = tcount)
  3635. {
  3636. http ('# Empty TURTLE\n', ses);
  3637. return;
  3638. }
  3639. env := DB.DBA.RDF_TRIPLES_TO_TTL_ENV (tcount, 0, 0, ses);
  3640. { whenever sqlstate '*' goto end_pred_sort;
  3641. rowvector_subj_sort (triples, 1, 1);
  3642. end_pred_sort: ;
  3643. }
  3644. { whenever sqlstate '*' goto end_subj_sort;
  3645. rowvector_subj_sort (triples, 0, 1);
  3646. end_subj_sort: ;
  3647. }
  3648. DB.DBA.RDF_TRIPLES_BATCH_COMPLETE (triples);
  3649. for (tctr := 0; tctr < tcount; tctr := tctr + 1)
  3650. {
  3651. http_ttl_triple (env, triples[tctr][0], triples[tctr][1], triples[tctr][2], ses);
  3652. }
  3653. http (' .', ses);
  3654. }
  3655. ;
  3656. create procedure DB.DBA.RDF_TRIPLES_TO_TRIG (inout triples any, inout ses any)
  3657. {
  3658. declare env any;
  3659. declare tcount, tctr, first_dflt_g_idx integer;
  3660. declare prev_g_iri varchar;
  3661. declare first_g_idx integer;
  3662. tcount := length (triples);
  3663. if (0 = tcount)
  3664. {
  3665. http ('# Empty TriG\n', ses);
  3666. return;
  3667. }
  3668. env := DB.DBA.RDF_TRIPLES_TO_TTL_ENV (tcount, 0, 0, ses);
  3669. { whenever sqlstate '*' goto end_pred_sort;
  3670. rowvector_subj_sort (triples, 1, 1);
  3671. end_pred_sort: ;
  3672. }
  3673. { whenever sqlstate '*' goto end_subj_sort;
  3674. rowvector_subj_sort (triples, 0, 1);
  3675. end_subj_sort: ;
  3676. }
  3677. rowvector_graph_sort (triples, 3, 1);
  3678. -- dbg_obj_princ ('DB.DBA.RDF_TRIPLES_TO_TRIG after sort:'); for (tctr := 0; tctr < tcount; tctr := tctr + 1) -- dbg_obj_princ (triples[tctr]);
  3679. DB.DBA.RDF_TRIPLES_BATCH_COMPLETE (triples);
  3680. for (tctr := 0; (tctr < tcount) and aref_or_default (triples, tctr, 3, null) is null; tctr := tctr + 1)
  3681. {
  3682. http_ttl_prefixes (env, triples[tctr][0], triples[tctr][1], triples[tctr][2], ses);
  3683. }
  3684. first_g_idx := tctr;
  3685. for (tctr := first_g_idx; tctr < tcount; tctr := tctr + 1)
  3686. {
  3687. http_ttl_prefixes (env, triples[tctr][0], triples[tctr][1], triples[tctr][2], ses);
  3688. }
  3689. if (0 < first_g_idx)
  3690. {
  3691. http ('{\n', ses);
  3692. for (tctr := 0; tctr < first_g_idx; tctr := tctr + 1)
  3693. {
  3694. http_ttl_triple (env, triples[tctr][0], triples[tctr][1], triples[tctr][2], ses);
  3695. }
  3696. http (' .\n}\n', ses);
  3697. }
  3698. prev_g_iri := '';
  3699. for (tctr := first_g_idx; tctr < tcount; tctr := tctr + 1)
  3700. {
  3701. declare g_iri varchar;
  3702. g_iri := id_to_iri_nosignal (triples[tctr][3]);
  3703. if (g_iri is not null)
  3704. {
  3705. if (g_iri <> prev_g_iri)
  3706. {
  3707. if (prev_g_iri <> '')
  3708. http (' .\n}\n', ses);
  3709. env[1] := 0;
  3710. http ('<', ses);
  3711. http_escape (g_iri, 12, ses, 1, 1);
  3712. http ('> = {\n', ses);
  3713. prev_g_iri := g_iri;
  3714. }
  3715. http_ttl_triple (env, triples[tctr][0], triples[tctr][1], triples[tctr][2], ses);
  3716. }
  3717. }
  3718. if (prev_g_iri <> '')
  3719. http (' .\n}\n', ses);
  3720. }
  3721. ;
  3722. create procedure DB.DBA.RDF_TRIPLES_TO_NT (inout triples any, inout ses any)
  3723. {
  3724. declare env any;
  3725. declare tcount, tctr integer;
  3726. tcount := length (triples);
  3727. -- dbg_obj_princ ('DB.DBA.RDF_TRIPLES_TO_TTL:'); for (tctr := 0; tctr < tcount; tctr := tctr + 1) -- dbg_obj_princ (triples[tctr]);
  3728. if (0 = tcount)
  3729. {
  3730. http ('# Empty NT\n', ses);
  3731. return;
  3732. }
  3733. env := vector (0, 0, 0);
  3734. DB.DBA.RDF_TRIPLES_BATCH_COMPLETE (triples);
  3735. for (tctr := 0; tctr < tcount; tctr := tctr + 1)
  3736. {
  3737. http_nt_triple (env, triples[tctr][0], triples[tctr][1], triples[tctr][2], ses);
  3738. }
  3739. }
  3740. ;
  3741. create procedure DB.DBA.RDF_GRAPH_TO_TTL (in graph_iri varchar, inout ses any)
  3742. {
  3743. declare tcount integer;
  3744. declare res varchar;
  3745. declare prev_s, prev_p IRI_ID;
  3746. -- dbg_obj_princ ('DB.DBA.RDF_GRAPH_TO_TTL (', graph_iri, ', ...)');
  3747. tcount := 0;
  3748. prev_s := null;
  3749. prev_p := null;
  3750. for (select S as subj, P as pred, O as obj from DB.DBA.RDF_QUAD where G = iri_to_id (graph_iri)) do
  3751. {
  3752. if (prev_s = subj)
  3753. {
  3754. if (prev_p = pred)
  3755. {
  3756. http (',\n\t\t', ses);
  3757. goto print_o;
  3758. }
  3759. http (';\n\t', ses);
  3760. goto print_p;
  3761. }
  3762. if (prev_s is not null)
  3763. http ('.\n', ses);
  3764. if (subj >= min_bnode_iri_id ())
  3765. {
  3766. if (subj >= #ib0)
  3767. http (sprintf ('_:bb%d ', iri_id_num (subj) - iri_id_num (#ib0)), ses);
  3768. else
  3769. http (sprintf ('_:b%d ', iri_id_num (subj)), ses);
  3770. }
  3771. else
  3772. {
  3773. res := id_to_iri (subj);
  3774. http ('<', ses);
  3775. http_escape (res, 12, ses, 1, 1);
  3776. http ('> ', ses);
  3777. }
  3778. prev_s := subj;
  3779. prev_p := null;
  3780. print_p:
  3781. if (pred >= min_bnode_iri_id ())
  3782. signal ('RDFXX', 'DB.DBA.RDF_GRAPH_TO_TTL(): blank node as predicate');
  3783. else
  3784. {
  3785. res := id_to_iri (pred);
  3786. http ('<', ses);
  3787. http_escape (res, 12, ses, 1, 1);
  3788. http ('> ', ses);
  3789. }
  3790. prev_p := pred;
  3791. print_o:
  3792. DB.DBA.RDF_LONG_TO_TTL (obj, ses);
  3793. tcount := tcount + 1;
  3794. }
  3795. if (0 = tcount)
  3796. http ('# Empty TURTLE\n', ses);
  3797. else
  3798. http ('.\n', ses);
  3799. }
  3800. ;
  3801. --create procedure DB.DBA.TEST_SPARQL_TTL (in query varchar, in dflt_graph varchar)
  3802. --{
  3803. -- declare ses, rset, triples any;
  3804. -- declare txt varchar;
  3805. -- ses := string_output ();
  3806. -- rset := DB.DBA.SPARQL_EVAL_TO_ARRAY (query, dflt_graph, 1);
  3807. -- triples := dict_list_keys (rset[0][0], 1);
  3808. -- DB.DBA.RDF_TRIPLES_TO_TTL (triples, ses);
  3809. -- txt := string_output_string (ses);
  3810. -- dump_large_text (txt);
  3811. --}
  3812. --;
  3813. create procedure DB.DBA.RDF_TRIPLES_TO_RDF_XML_TEXT (inout triples any, in print_top_level integer, inout ses any)
  3814. {
  3815. declare ns_dict, env any;
  3816. declare tcount, tctr integer;
  3817. tcount := length (triples);
  3818. DB.DBA.RDF_TRIPLES_BATCH_COMPLETE (triples);
  3819. { whenever sqlstate '*' goto end_pred_sort;
  3820. rowvector_subj_sort (triples, 1, 1);
  3821. end_pred_sort: ;
  3822. }
  3823. ns_dict := dict_new (case (print_top_level) when 0 then 10 else __min (tcount, 16000) end);
  3824. dict_put (ns_dict, 'http://www.w3.org/1999/02/22-rdf-syntax-ns#', 'rdf');
  3825. dict_put (ns_dict, 'http://www.w3.org/2000/01/rdf-schema#', 'rdfs');
  3826. env := vector (ns_dict, 0, 0, '', '', 0, 0, 0, 0, 0);
  3827. if (print_top_level)
  3828. {
  3829. http ('<?xml version="1.0" encoding="utf-8" ?>\n<rdf:RDF\n\txmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"\n\txmlns:rdfs="http://www.w3.org/2000/01/rdf-schema#"', ses);
  3830. for (tctr := 0; tctr < tcount; tctr := tctr + 1)
  3831. {
  3832. http_rdfxml_p_ns (env, triples[tctr][1], ses);
  3833. }
  3834. http (' >', ses);
  3835. }
  3836. { whenever sqlstate '*' goto end_subj_sort;
  3837. rowvector_subj_sort (triples, 0, 1);
  3838. end_subj_sort: ;
  3839. }
  3840. for (tctr := 0; tctr < tcount; tctr := tctr + 1)
  3841. {
  3842. http_rdfxml_triple (env, triples[tctr][0], triples[tctr][1], triples[tctr][2], ses);
  3843. }
  3844. if (isstring (env[2]))
  3845. http ('\n </rdf:Description>', ses);
  3846. if (print_top_level)
  3847. {
  3848. http ('\n</rdf:RDF>', ses);
  3849. }
  3850. }
  3851. ;
  3852. --create procedure DB.DBA.TEST_SPARQL_RDF_XML_TEXT (in query varchar, in dflt_graph varchar)
  3853. --{
  3854. -- declare ses, rset, triples any;
  3855. -- declare txt varchar;
  3856. -- ses := string_output ();
  3857. -- rset := DB.DBA.SPARQL_EVAL_TO_ARRAY (query, dflt_graph, 1);
  3858. -- triples := dict_list_keys (rset[0][0], 1);
  3859. -- DB.DBA.RDF_TRIPLES_TO_RDF_XML_TEXT (triples, 1, ses);
  3860. -- txt := string_output_string (ses);
  3861. -- dump_large_text (txt);
  3862. --}
  3863. --;
  3864. create procedure DB.DBA.RDF_TRIPLES_TO_TALIS_JSON (inout triples any, inout ses any)
  3865. {
  3866. declare env any;
  3867. declare tcount, tctr, status integer;
  3868. tcount := length (triples);
  3869. -- dbg_obj_princ ('DB.DBA.RDF_TRIPLES_TO_TALIS_JSON:'); for (tctr := 0; tctr < tcount; tctr := tctr + 1) -- dbg_obj_princ (triples[tctr]);
  3870. if (0 = tcount)
  3871. {
  3872. http ('{ }\n', ses);
  3873. return;
  3874. }
  3875. env := vector (0, 0, 0, null);
  3876. -- No error handlers here because failed sorting by predicate or subject would result in poorly structured output.
  3877. rowvector_subj_sort (triples, 1, 1);
  3878. rowvector_subj_sort (triples, 0, 1);
  3879. DB.DBA.RDF_TRIPLES_BATCH_COMPLETE (triples);
  3880. http ('{\n ', ses);
  3881. status := 0;
  3882. for (tctr := 0; tctr < tcount; tctr := tctr + 1)
  3883. {
  3884. if (http_talis_json_triple (env, triples[tctr][0], triples[tctr][1], triples[tctr][2], ses))
  3885. status := 1;
  3886. }
  3887. if (status)
  3888. http (' ] }\n', ses);
  3889. http ('}\n', ses);
  3890. }
  3891. ;
  3892. create procedure DB.DBA.RDF_TRIPLES_TO_JSON_LD (inout triples any, inout ses any)
  3893. {
  3894. declare env any;
  3895. declare tcount, tctr, status integer;
  3896. tcount := length (triples);
  3897. -- dbg_obj_princ ('DB.DBA.RDF_TRIPLES_TO_JSON_LD:'); for (tctr := 0; tctr < tcount; tctr := tctr + 1) -- dbg_obj_princ (triples[tctr]);
  3898. if (0 = tcount)
  3899. {
  3900. http ('{ }\n', ses);
  3901. return;
  3902. }
  3903. env := vector (0, 0, 0, null);
  3904. -- No error handlers here because failed sorting by predicate or subject would result in poorly structured output.
  3905. rowvector_subj_sort (triples, 1, 1);
  3906. rowvector_subj_sort (triples, 0, 1);
  3907. DB.DBA.RDF_TRIPLES_BATCH_COMPLETE (triples);
  3908. http ('{ "@graph": [\n ', ses);
  3909. status := 0;
  3910. for (tctr := 0; tctr < tcount; tctr := tctr + 1)
  3911. {
  3912. if (http_ld_json_triple (env, triples[tctr][0], triples[tctr][1], triples[tctr][2], ses))
  3913. status := 1;
  3914. }
  3915. if (status)
  3916. http (' ] }\n', ses);
  3917. http ('] }\n', ses);
  3918. }
  3919. ;
  3920. create procedure DB.DBA.RDF_TRIPLES_TO_JSON (inout triples any, inout ses any)
  3921. {
  3922. declare tcount, tctr, env integer;
  3923. tcount := length (triples);
  3924. http ('\n{ "head": { "link": [], "vars": [ "s", "p", "o" ] },\n "results": { "distinct": false, "ordered": true, "bindings": [', ses);
  3925. tcount := length (triples);
  3926. env := vector (0, 0, vector ('s', 'p', 'o'), null);
  3927. DB.DBA.RDF_TRIPLES_BATCH_COMPLETE (triples);
  3928. for (tctr := 0; tctr < tcount; tctr := tctr + 1)
  3929. {
  3930. declare triple any;
  3931. if (tctr > 0)
  3932. http(',', ses);
  3933. triple := aref_set_0 (triples, tctr);
  3934. sparql_rset_json_write_row (ses, env, triple);
  3935. aset_zap_arg (triples, tctr, triple);
  3936. }
  3937. http (' ] } }', ses);
  3938. }
  3939. ;
  3940. create procedure DB.DBA.RDF_TRIPLES_TO_CSV (inout triples any, inout ses any)
  3941. {
  3942. declare env any;
  3943. declare tcount, tctr, status integer;
  3944. http ('"subject","predicate","object"\n', ses);
  3945. tcount := length (triples);
  3946. -- dbg_obj_princ ('DB.DBA.RDF_TRIPLES_TO_CSV:'); for (tctr := 0; tctr < tcount; tctr := tctr + 1) -- dbg_obj_princ (triples[tctr]);
  3947. { whenever sqlstate '*' goto p_done; rowvector_subj_sort (triples, 1, 1); p_done: ; }
  3948. { whenever sqlstate '*' goto s_done; rowvector_subj_sort (triples, 0, 1); s_done: ; }
  3949. DB.DBA.RDF_TRIPLES_BATCH_COMPLETE (triples);
  3950. for (tctr := 0; tctr < tcount; tctr := tctr + 1)
  3951. {
  3952. DB.DBA.SPARQL_RESULTS_CSV_WRITE_VALUE (ses, triples[tctr][0]);
  3953. http (',', ses);
  3954. DB.DBA.SPARQL_RESULTS_CSV_WRITE_VALUE (ses, triples[tctr][1]);
  3955. http (',', ses);
  3956. DB.DBA.SPARQL_RESULTS_CSV_WRITE_VALUE (ses, triples[tctr][2]);
  3957. http ('\n', ses);
  3958. }
  3959. }
  3960. ;
  3961. create procedure DB.DBA.RDF_TRIPLES_TO_TSV (inout triples any, inout ses any)
  3962. {
  3963. declare env any;
  3964. declare tcount, tctr, status integer;
  3965. http ('"subject","predicate","object"\n', ses);
  3966. tcount := length (triples);
  3967. -- dbg_obj_princ ('DB.DBA.RDF_TRIPLES_TO_TSV:'); for (tctr := 0; tctr < tcount; tctr := tctr + 1) -- dbg_obj_princ (triples[tctr]);
  3968. { whenever sqlstate '*' goto p_done; rowvector_subj_sort (triples, 1, 1); p_done: ; }
  3969. { whenever sqlstate '*' goto s_done; rowvector_subj_sort (triples, 0, 1); s_done: ; }
  3970. DB.DBA.RDF_TRIPLES_BATCH_COMPLETE (triples);
  3971. for (tctr := 0; tctr < tcount; tctr := tctr + 1)
  3972. {
  3973. DB.DBA.SPARQL_RESULTS_CSV_WRITE_VALUE (ses, triples[tctr][0]);
  3974. http ('\t', ses);
  3975. DB.DBA.SPARQL_RESULTS_CSV_WRITE_VALUE (ses, triples[tctr][1]);
  3976. http ('\t', ses);
  3977. DB.DBA.SPARQL_RESULTS_CSV_WRITE_VALUE (ses, triples[tctr][2]);
  3978. http ('\n', ses);
  3979. }
  3980. }
  3981. ;
  3982. create procedure DB.DBA.RDF_TRIPLES_TO_RDFA_XHTML (inout triples any, inout ses any)
  3983. {
  3984. declare env, prev_subj, subj_text, pred_text, nsdict, nslist any;
  3985. declare ctr, len, tcount, tctr, status integer;
  3986. tcount := length (triples);
  3987. -- dbg_obj_princ ('DB.DBA.RDF_TRIPLES_TO_RDFA_XHTML:'); for (tctr := 0; tctr < tcount; tctr := tctr + 1) -- dbg_obj_princ (triples[tctr]);
  3988. http ('<?xml version="1.0" encoding="UTF-8"?>\n
  3989. <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML+RDFa 1.0//EN" "http://www.w3.org/MarkUp/DTD/xhtml-rdfa-1.dtd">\n', ses);
  3990. if (0 = tcount)
  3991. {
  3992. http ('<html xmlns="http://www.w3.org/1999/xhtml">
  3993. <head><title>Empty RDFa+XHTML document</title></head><body>
  3994. <p>This document is empty and basically useless. It is generated by a web service that can make some statements in XHTML+RDFa format.
  3995. This time the service made zero such statements, sorry.</p></body></html>', ses);
  3996. return;
  3997. }
  3998. nsdict := dict_new (10 + cast (sqrt(tcount) as integer));
  3999. dict_put (nsdict, 'http://www.w3.org/1999/02/22-rdf-syntax-ns#', 'rdf');
  4000. dict_put (nsdict, 'http://www.w3.org/2001/XMLSchema#', 'xsdh');
  4001. DB.DBA.RDF_TRIPLES_BATCH_COMPLETE (triples);
  4002. for (tctr := 0; (tctr < tcount) and (1000 > dict_size (nsdict)); tctr := tctr + 1)
  4003. {
  4004. sparql_iri_split_rdfa_qname (triples[tctr][0], nsdict, 1);
  4005. sparql_iri_split_rdfa_qname (triples[tctr][1], nsdict, 1);
  4006. sparql_iri_split_rdfa_qname (triples[tctr][2], nsdict, 1);
  4007. }
  4008. http ('<html xmlns="http://www.w3.org/1999/xhtml"', ses);
  4009. nslist := dict_to_vector (nsdict, 0);
  4010. len := length (nslist);
  4011. for (ctr := len - 2; ctr >= 0; ctr := ctr-2)
  4012. {
  4013. http (sprintf ('\n xmlns:%s="', nslist[ctr+1]), ses);
  4014. http_escape (nslist[ctr], 3, ses, 1, 1);
  4015. http ('"', ses);
  4016. }
  4017. http ('>\n<head><title>RDFa+XHTML document</title></head><body>\n', ses);
  4018. http (sprintf ('<p>This HTML document contains %d embedded RDF statements represented using (X)HTML+RDFa notation.</p>',
  4019. tcount), ses);
  4020. http ('<p>The embedded RDF content will be recognized by any processor of (X)HTML+RDFa.</p>', ses);
  4021. http ('\n<table border="1">\n<thead><tr><th>Namespace Prefix</th><th>Namespace URI</th></tr></thead><tbody>', ses);
  4022. for (ctr := len - 2; ctr >= 0; ctr := ctr-2)
  4023. {
  4024. http (sprintf ('\n<tr><td>xmlns:%s</td><td>', nslist[ctr+1]), ses);
  4025. http_escape (nslist[ctr], 3, ses, 1, 1);
  4026. http ('</td></tr>', ses);
  4027. }
  4028. http ('\n</tbody></table>', ses);
  4029. http ('\n<table border="1">\n<thead><tr><th>Subject</th><th>Predicate</th><th>Object</th></tr></thead>', ses);
  4030. env := vector (0, 0, 0, null);
  4031. rowvector_subj_sort (triples, 1, 1);
  4032. rowvector_subj_sort (triples, 0, 1);
  4033. prev_subj := null;
  4034. for (tctr := 0; tctr < tcount; tctr := tctr + 1)
  4035. {
  4036. declare subj, pred, obj, split, obj_iri_split any;
  4037. declare pred_tagname varchar;
  4038. declare res varchar;
  4039. subj := triples[tctr][0];
  4040. pred := triples[tctr][1];
  4041. obj := triples[tctr][2];
  4042. -- dbg_obj_princ ('DB.DBA.RDF_TRIPLES_TO_RDFA_XHTML: subj:', subj, __tag(subj), __box_flags (subj));
  4043. -- dbg_obj_princ ('DB.DBA.RDF_TRIPLES_TO_RDFA_XHTML: pred:', pred, __tag(pred), __box_flags (pred));
  4044. -- dbg_obj_princ ('DB.DBA.RDF_TRIPLES_TO_RDFA_XHTML: obj:', obj, __tag(obj), __box_flags (obj));
  4045. if (prev_subj is null or (subj <> prev_subj))
  4046. {
  4047. if (prev_subj is not null)
  4048. http ('\n</tbody>', ses);
  4049. http ('\n<tbody about="[', ses);
  4050. split := sparql_iri_split_rdfa_qname (subj, nsdict, 2);
  4051. -- dbg_obj_princ ('Split of ', subj, ' is ', split);
  4052. if ('' = split[1])
  4053. {
  4054. subj_text := split[2];
  4055. http_escape (subj_text, 3, ses, 1, 1);
  4056. http (']">', ses);
  4057. }
  4058. else if (isstring (split[0]))
  4059. {
  4060. subj_text := concat (split[0], ':', split[2]);
  4061. http_escape (subj_text, 3, ses, 1, 1);
  4062. http (']">', ses);
  4063. }
  4064. else
  4065. {
  4066. subj_text := id_to_iri (subj);
  4067. http_escape (concat ('s:', split[2]), 3, ses, 1, 1);
  4068. http (']" xmlns:s="', ses);
  4069. http_escape (split[1], 3, ses, 1, 1);
  4070. http ('">', ses);
  4071. }
  4072. subj_text := sprintf ('\n<tr><td>%V</td><td>', subj_text);
  4073. prev_subj := subj;
  4074. }
  4075. http (subj_text, ses);
  4076. split := sparql_iri_split_rdfa_qname (pred, nsdict, 2);
  4077. if ('' = split[1])
  4078. {
  4079. http_value (split[2], 0, ses);
  4080. }
  4081. else if (isstring (split[0]))
  4082. {
  4083. http_value (concat (split[0], ':', split[2]), 0, ses);
  4084. }
  4085. else
  4086. {
  4087. http_value (id_to_iri (pred), 0, ses);
  4088. }
  4089. obj_iri_split := sparql_iri_split_rdfa_qname (obj, nsdict, 2);
  4090. http (case (isvector (obj_iri_split)) when 0 then '</td><td property="' else '</td><td rel="' end, ses);
  4091. if ('' = split[1])
  4092. {
  4093. pred_text := split[2];
  4094. http_escape (pred_text, 3, ses, 1, 1);
  4095. http ('"', ses);
  4096. }
  4097. else if (isstring (split[0]))
  4098. {
  4099. pred_text := concat (split[0], ':', split[2]);
  4100. http_escape (pred_text, 3, ses, 1, 1);
  4101. http ('"', ses);
  4102. }
  4103. else
  4104. {
  4105. pred_text := id_to_iri (pred);
  4106. http_escape (concat ('p:', split[2]), 3, ses, 1, 1);
  4107. http ('" xmlns:p="', ses);
  4108. http_escape (split[1], 3, ses, 1, 1);
  4109. http ('"', ses);
  4110. }
  4111. if (obj is null)
  4112. signal ('RDFXX', 'DB.DBA.TRIPLES_TO_RDFA_XHTML: object is NULL');
  4113. if (isvector (obj_iri_split))
  4114. {
  4115. http (' resource="', ses);
  4116. if (isstring (obj_iri_split[0]))
  4117. {
  4118. http ('[', ses);
  4119. http_escape (concat (obj_iri_split[0], ':', obj_iri_split[2]), 3, ses, 1, 1);
  4120. http (']" >', ses);
  4121. http_value (concat (obj_iri_split[0], ':', obj_iri_split[2]), 0, ses);
  4122. http ('</td></tr>', ses);
  4123. }
  4124. else
  4125. {
  4126. http_escape (concat (obj_iri_split[1], ':', obj_iri_split[2]), 3, ses, 1, 1);
  4127. http ('" >', ses);
  4128. http_value (concat (obj_iri_split[1], ':', obj_iri_split[2]), 0, ses);
  4129. http ('</td></tr>', ses);
  4130. }
  4131. }
  4132. else
  4133. {
  4134. declare sqlval any;
  4135. declare dt, lang, strval any;
  4136. dt := 0; lang := 0;
  4137. if (__tag of rdf_box = __tag (obj))
  4138. {
  4139. if (257 <> rdf_box_type (obj))
  4140. dt := coalesce ((select __bft (RDT_QNAME, 1) from DB.DBA.RDF_DATATYPE where RDT_TWOBYTE = rdf_box_type (obj)));
  4141. else if (257 <> rdf_box_lang (obj))
  4142. lang := coalesce ((select lower (RL_ID) from DB.DBA.RDF_LANGUAGE where RL_TWOBYTE = rdf_box_lang (obj)));
  4143. sqlval := __rdf_sqlval_of_obj (obj, 1);
  4144. if (__tag of datetime = __tag (sqlval))
  4145. {
  4146. if (257 = rdf_box_type (obj))
  4147. dt := __xsd_type (sqlval);
  4148. }
  4149. }
  4150. else if (__tag (obj) not in (__tag of varchar, __tag of varbinary))
  4151. {
  4152. sqlval := obj;
  4153. dt := __xsd_type (sqlval);
  4154. }
  4155. else
  4156. sqlval := obj;
  4157. if (not (isinteger (dt)))
  4158. {
  4159. http (' datatype="', ses);
  4160. split := sparql_iri_split_rdfa_qname (dt, nsdict, 2);
  4161. if ('' = split[1])
  4162. {
  4163. http_escape (split[2], 3, ses, 1, 1);
  4164. http ('"', ses);
  4165. }
  4166. else if (isstring (split[0]))
  4167. {
  4168. http_escape (concat (split[0], ':', split[2]), 3, ses, 1, 1);
  4169. http ('"', ses);
  4170. }
  4171. else
  4172. {
  4173. http_escape (concat ('dt:', split[2]), 3, ses, 1, 1);
  4174. http ('" xmlns:dt="', ses);
  4175. http_escape (split[1], 3, ses, 1, 1);
  4176. http ('"', ses);
  4177. }
  4178. }
  4179. if (isstring (lang))
  4180. {
  4181. http (' xml:lang="', ses);
  4182. http_escape (lang, 3, ses, 1, 1);
  4183. http ('"', ses);
  4184. }
  4185. http ('>', ses);
  4186. if (__tag of datetime = __tag(sqlval))
  4187. __rdf_long_to_ttl (sqlval, ses);
  4188. else if (__tag (sqlval) in (__tag of varbinary, __tag of XML))
  4189. http_value (sqlval, 0, ses);
  4190. else if (__tag of varchar = __tag (sqlval))
  4191. http_value (charset_recode (sqlval, 'UTF-8', '_WIDE_'), 0, ses);
  4192. else
  4193. {
  4194. sqlval := __rdf_strsqlval (obj);
  4195. if (__tag of varchar = __tag (sqlval))
  4196. sqlval := charset_recode (sqlval, 'UTF-8', '_WIDE_');
  4197. http_value (sqlval, 0, ses);
  4198. }
  4199. http ('</td></tr>', ses);
  4200. }
  4201. }
  4202. if (prev_subj is not null)
  4203. http ('\n</tbody>', ses);
  4204. http ('\n</table></body></html>\n', ses);
  4205. }
  4206. ;
  4207. create function DB.DBA.RDF_ENDPOINT_DESCRIBE_LINK_FMT (in ul_or_tr varchar)
  4208. {
  4209. declare lpath varchar;
  4210. lpath := virtuoso_ini_item_value ('URIQA','DefaultHost');
  4211. if (lpath is null)
  4212. lpath := '/sparql';
  4213. else
  4214. lpath := 'http://' || lpath || '/sparql';
  4215. whenever sqlstate 'HT013' goto no_http_context;
  4216. lpath := http_path ();
  4217. no_http_context:
  4218. return ' <a href=" ' || lpath || '?query=describe+%%3C%U%%3E&amp;format=text%%2Fx-html%%2B' || ul_or_tr || '">describe</a> ';
  4219. }
  4220. ;
  4221. create function DB.DBA.RDF_PIVOT_DESCRIBE_LINK (in iri varchar)
  4222. {
  4223. return sprintf ('; <a href="/describe/?url=%U&sid=1&amp;urilookup=1">facets</a> ', iri);
  4224. }
  4225. ;
  4226. create procedure DB.DBA.RDF_TRIPLES_TO_HTML_UL (inout triples any, inout ses any)
  4227. {
  4228. declare env, prev_subj, prev_pred any array;
  4229. declare can_pivot, ctr, len, tcount, tctr, status, obj_needs_br integer;
  4230. declare endpoint_fmt, subj_iri, pred_iri varchar;
  4231. tcount := length (triples);
  4232. -- dbg_obj_princ ('DB.DBA.RDF_TRIPLES_TO_HTML_UL:'); for (tctr := 0; tctr < tcount; tctr := tctr + 1) -- dbg_obj_princ (triples[tctr]);
  4233. http ('<?xml version="1.0" encoding="UTF-8"?>\n<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML+RDFa 1.0//EN" "http://www.w3.org/MarkUp/DTD/xhtml-rdfa-1.dtd">\n', ses);
  4234. if (0 = tcount)
  4235. {
  4236. http ('<html xmlns="http://www.w3.org/1999/xhtml">
  4237. <head><title>Empty HTML RDFa and Microdata document</title>
  4238. <meta http-equiv="Content-Type" content="text/html;charset=utf-8" />
  4239. </head><body>
  4240. <p>This document is empty and basically useless. It is generated by a web service that can make some statements in HTML Microdata format.
  4241. This time the service made zero such statements, sorry.</p></body></html>', ses);
  4242. return;
  4243. }
  4244. endpoint_fmt := DB.DBA.RDF_ENDPOINT_DESCRIBE_LINK_FMT ('ul');
  4245. can_pivot := case (isnull (DB.DBA.VAD_CHECK_VERSION ('PivotViewer'))) when 0 then 1 else 0 end;
  4246. DB.DBA.RDF_TRIPLES_BATCH_COMPLETE (triples);
  4247. http ('<html xmlns="http://www.w3.org/1999/xhtml"', ses);
  4248. http ('>\n<head><title>HTML RDFa and Microdata document</title>
  4249. <meta http-equiv="Content-Type" content="text/html;charset=utf-8" />
  4250. </head>\n<body>\n<ul>\n', ses);
  4251. env := vector (0, 0, 0, null);
  4252. rowvector_subj_sort (triples, 1, 1);
  4253. rowvector_subj_sort (triples, 0, 1);
  4254. prev_subj := prev_pred := null;
  4255. obj_needs_br := 0;
  4256. for (tctr := 0; tctr < tcount; tctr := tctr + 1)
  4257. {
  4258. declare subj, pred, obj, split, obj_iri_split any array;
  4259. declare pred_tagname varchar;
  4260. declare res varchar;
  4261. subj := triples[tctr][0];
  4262. pred := triples[tctr][1];
  4263. obj := triples[tctr][2];
  4264. -- dbg_obj_princ ('DB.DBA.RDF_TRIPLES_TO_HTML_UL: subj:', subj, __tag(subj), __box_flags (subj));
  4265. -- dbg_obj_princ ('DB.DBA.RDF_TRIPLES_TO_HTML_UL: pred:', pred, __tag(pred), __box_flags (pred));
  4266. -- dbg_obj_princ ('DB.DBA.RDF_TRIPLES_TO_HTML_UL: obj:', obj, __tag(obj), __box_flags (obj));
  4267. if (prev_subj is null or (subj <> prev_subj))
  4268. {
  4269. if (prev_subj is not null)
  4270. http ('\n </ul></li>\n </ul></li>', ses);
  4271. subj_iri := id_to_iri (subj);
  4272. http ('\n <li about="', ses);
  4273. http_escape (subj_iri, 3, ses, 1, 1);
  4274. http ('" itemscope="" itemid="', ses);
  4275. http_escape (subj_iri, 3, ses, 1, 1);
  4276. http ('"><a href="', ses);
  4277. http_escape (subj_iri, 3, ses, 1, 1);
  4278. http ('">', ses);
  4279. http_escape (subj_iri, 1, ses, 1, 1);
  4280. http ('</a> (', ses);
  4281. http (sprintf (endpoint_fmt, subj_iri), ses);
  4282. if (can_pivot)
  4283. http (DB.DBA.RDF_PIVOT_DESCRIBE_LINK (subj_iri), ses);
  4284. http (')\n <ul>', ses);
  4285. prev_subj := subj;
  4286. prev_pred := null;
  4287. }
  4288. if (prev_pred is null or (pred <> prev_pred))
  4289. {
  4290. if (prev_pred is not null)
  4291. http ('\n </ul></li>', ses);
  4292. pred_iri := id_to_iri (pred);
  4293. http ('\n <li><a href="', ses);
  4294. http_escape (pred_iri, 3, ses, 1, 1);
  4295. http ('">', ses);
  4296. http_escape (pred_iri, 1, ses, 1, 1);
  4297. http ('</a> (', ses);
  4298. http (sprintf (endpoint_fmt, pred_iri), ses);
  4299. if (can_pivot)
  4300. http (DB.DBA.RDF_PIVOT_DESCRIBE_LINK (pred_iri), ses);
  4301. http (')\n <ul>', ses);
  4302. prev_pred := pred;
  4303. obj_needs_br := 0;
  4304. }
  4305. if (obj is null)
  4306. signal ('RDFXX', 'DB.DBA.TRIPLES_TO_HTML_UL: object is NULL');
  4307. if (obj_needs_br)
  4308. http ('\n', ses);
  4309. else
  4310. obj_needs_br := 1;
  4311. if (isiri_id (obj))
  4312. {
  4313. declare obj_iri varchar;
  4314. obj_iri := id_to_iri (obj);
  4315. http ('\n <li><a rel="', ses);
  4316. http_escape (pred_iri, 3, ses, 1, 1);
  4317. http ('" resource="', ses);
  4318. http_escape (obj_iri, 3, ses, 1, 1);
  4319. http ('" itemprop="', ses);
  4320. http_escape (pred_iri, 3, ses, 1, 1);
  4321. http ('" href="', ses);
  4322. http_escape (obj_iri, 3, ses, 1, 1);
  4323. http ('">', ses);
  4324. http_escape (obj_iri, 1, ses, 1, 1);
  4325. http ('</a> (', ses);
  4326. http (sprintf (endpoint_fmt, obj_iri), ses);
  4327. if (can_pivot)
  4328. http (DB.DBA.RDF_PIVOT_DESCRIBE_LINK (obj_iri), ses);
  4329. http (')</li>', ses);
  4330. }
  4331. else
  4332. {
  4333. declare sqlval any;
  4334. declare dt, lang, strval any;
  4335. http ('\n <li property="', ses);
  4336. http_escape (pred_iri, 3, ses, 1, 1);
  4337. http ('" itemprop="', ses);
  4338. http_escape (pred_iri, 3, ses, 1, 1);
  4339. dt := 0; lang := 0;
  4340. if (__tag of rdf_box = __tag (obj))
  4341. {
  4342. if (257 <> rdf_box_lang (obj))
  4343. lang := coalesce ((select lower (RL_ID) from DB.DBA.RDF_LANGUAGE where RL_TWOBYTE = rdf_box_lang (obj)));
  4344. else if (257 <> rdf_box_type (obj))
  4345. dt := coalesce ((select __bft (RDT_QNAME, 1) from DB.DBA.RDF_DATATYPE where RDT_TWOBYTE = rdf_box_type (obj)));
  4346. sqlval := __rdf_sqlval_of_obj (obj, 1);
  4347. if (__tag of datetime = __tag (sqlval))
  4348. {
  4349. if (257 = rdf_box_type (obj))
  4350. dt := __xsd_type (sqlval);
  4351. }
  4352. }
  4353. else if (__tag (obj) not in (__tag of varchar, __tag of varbinary))
  4354. {
  4355. sqlval := obj;
  4356. dt := __xsd_type (sqlval);
  4357. }
  4358. else
  4359. sqlval := obj;
  4360. if (not (isinteger (dt)))
  4361. {
  4362. http ('" datatype="', ses);
  4363. http_escape (dt, 3, ses, 1, 1);
  4364. }
  4365. if (isstring (lang))
  4366. {
  4367. http ('" xml:lang="', ses);
  4368. http_escape (lang, 3, ses, 1, 1);
  4369. }
  4370. http ('">', ses);
  4371. if (__tag of datetime = __tag(sqlval))
  4372. __rdf_long_to_ttl (sqlval, ses);
  4373. else if (__tag (sqlval) in (__tag of varbinary, __tag of XML))
  4374. http_value (sqlval, 0, ses);
  4375. else if (__tag of varchar = __tag (sqlval))
  4376. http_value (charset_recode (sqlval, 'UTF-8', '_WIDE_'), 0, ses);
  4377. else
  4378. {
  4379. sqlval := __rdf_strsqlval (obj);
  4380. if (__tag of varchar = __tag (sqlval))
  4381. sqlval := charset_recode (sqlval, 'UTF-8', '_WIDE_');
  4382. http_value (sqlval, 0, ses);
  4383. }
  4384. http ('</li>', ses);
  4385. }
  4386. }
  4387. if (prev_subj is not null)
  4388. http ('\n </ul></li></ul></li></ul>', ses);
  4389. http ('\n</body></html>\n', ses);
  4390. }
  4391. ;
  4392. create procedure DB.DBA.RDF_TRIPLES_TO_HTML_TR (inout triples any, inout ses any)
  4393. {
  4394. declare env, prev_subj, prev_pred any;
  4395. declare can_pivot, ctr, len, tcount, tctr, status integer;
  4396. declare endpoint_fmt, subj_iri, pred_iri, subj_recod, pred_recod, subj_trtd, pred_tdtd varchar;
  4397. tcount := length (triples);
  4398. -- dbg_obj_princ ('DB.DBA.RDF_TRIPLES_TO_HTML_TR:'); for (tctr := 0; tctr < tcount; tctr := tctr + 1) -- dbg_obj_princ (triples[tctr]);
  4399. -- http ('<?xml version="1.0" encoding="UTF-8"?>\n<!DOCTYPE html>\n', ses);
  4400. if (0 = tcount)
  4401. {
  4402. http ('<html xmlns="http://www.w3.org/1999/xhtml">
  4403. <head><title>Empty HTML RDFa and Microdata document</title></head><body>
  4404. <p>This document is empty and basically useless. It is generated by a web service that can make some statements in HTML Microdata format.
  4405. This time the service made zero such statements, sorry.</p></body></html>', ses);
  4406. return;
  4407. }
  4408. endpoint_fmt := DB.DBA.RDF_ENDPOINT_DESCRIBE_LINK_FMT ('tr');
  4409. can_pivot := case (isnull (DB.DBA.VAD_CHECK_VERSION ('PivotViewer'))) when 0 then 1 else 0 end;
  4410. DB.DBA.RDF_TRIPLES_BATCH_COMPLETE (triples);
  4411. http ('<html xmlns="http://www.w3.org/1999/xhtml"', ses);
  4412. http ('>\n<head><title>HTML RDFa and Microdata document</title>
  4413. <meta http-equiv="Content-Type" content="text/html;charset=utf-8" />
  4414. </head>\n<body>\n<table>\n', ses);
  4415. env := vector (0, 0, 0, null);
  4416. rowvector_subj_sort (triples, 1, 1);
  4417. rowvector_subj_sort (triples, 0, 1);
  4418. prev_subj := prev_pred := null;
  4419. for (tctr := 0; tctr < tcount; tctr := tctr + 1)
  4420. {
  4421. declare subj, pred, obj, split, obj_iri_split any;
  4422. declare pred_tagname varchar;
  4423. declare res varchar;
  4424. subj := triples[tctr][0];
  4425. pred := triples[tctr][1];
  4426. obj := triples[tctr][2];
  4427. -- dbg_obj_princ ('DB.DBA.RDF_TRIPLES_TO_HTML_TR: subj:', subj, __tag(subj), __box_flags (subj));
  4428. -- dbg_obj_princ ('DB.DBA.RDF_TRIPLES_TO_HTML_TR: pred:', pred, __tag(pred), __box_flags (pred));
  4429. -- dbg_obj_princ ('DB.DBA.RDF_TRIPLES_TO_HTML_TR: obj:', obj, __tag(obj), __box_flags (obj));
  4430. if (prev_subj is null or (subj <> prev_subj))
  4431. {
  4432. declare trtd_ses any;
  4433. subj_iri := id_to_iri (subj);
  4434. --subj_recod := replace (subj_iri, '"', '%22');
  4435. --subj_trtd := sprintf ('\n<tr itemscope="itemscope" about="%s" itemid="%s">\n <td><a href="%s">%V</a> (' || endpoint_fmt || '%s)</td>',
  4436. -- subj_recod, subj_recod, subj_recod, subj_iri, subj_iri,
  4437. -- case when (can_pivot) then DB.DBA.RDF_PIVOT_DESCRIBE_LINK (id_to_iri (subj)) else '' end );
  4438. trtd_ses := string_output ();
  4439. http ('\n<tr itemscope="itemscope" about="', trtd_ses);
  4440. http_escape (subj_iri, 3, trtd_ses, 1, 1);
  4441. http ('" itemid="', trtd_ses);
  4442. http_escape (subj_iri, 3, trtd_ses, 1, 1);
  4443. http ('">\n <td><a href="', trtd_ses);
  4444. http_escape (subj_iri, 3, trtd_ses, 1, 1);
  4445. http (sprintf ('">%V</a> (' || endpoint_fmt || '%s)</td>', subj_iri, subj_iri,
  4446. case when (can_pivot) then DB.DBA.RDF_PIVOT_DESCRIBE_LINK (id_to_iri (subj)) else '' end ),
  4447. trtd_ses );
  4448. subj_trtd := string_output_string (trtd_ses);
  4449. prev_subj := subj;
  4450. }
  4451. if (prev_pred is null or (pred <> prev_pred))
  4452. {
  4453. declare tdtd_ses any;
  4454. pred_iri := id_to_iri (pred);
  4455. --pred_recod := replace (pred_iri, '"', '%22');
  4456. --pred_tdtd := sprintf ('\n <td><a href="%s">%s</a> (' || endpoint_fmt || '%s)\n </td><td',
  4457. -- pred_recod, pred_recod, pred_iri,
  4458. -- case when (can_pivot) then DB.DBA.RDF_PIVOT_DESCRIBE_LINK (id_to_iri (pred)) else '' end );
  4459. tdtd_ses := string_output ();
  4460. http ('\n <td><a href="', tdtd_ses);
  4461. http_escape (pred_iri, 3, tdtd_ses, 1, 1);
  4462. http ('">', tdtd_ses);
  4463. http_escape (pred_iri, 1, tdtd_ses, 1, 1);
  4464. http (sprintf ('</a> (' || endpoint_fmt || '%s)\n </td><td', pred_iri,
  4465. case when (can_pivot) then DB.DBA.RDF_PIVOT_DESCRIBE_LINK (id_to_iri (pred)) else '' end ),
  4466. tdtd_ses );
  4467. pred_tdtd := string_output_string (tdtd_ses);
  4468. prev_pred := pred;
  4469. }
  4470. if (obj is null)
  4471. signal ('RDFXX', 'DB.DBA.TRIPLES_TO_HTML_TR: object is NULL');
  4472. http (subj_trtd, ses);
  4473. http (pred_tdtd, ses);
  4474. if (isiri_id (obj))
  4475. {
  4476. declare obj_iri varchar;
  4477. obj_iri := id_to_iri (obj);
  4478. http ('><a rel="', ses);
  4479. http_escape (pred_iri, 3, ses, 1, 1);
  4480. http ('" resource="', ses);
  4481. http_escape (obj_iri, 3, ses, 1, 1);
  4482. http ('" itemprop="', ses);
  4483. http_escape (pred_iri, 3, ses, 1, 1);
  4484. http ('" href="', ses);
  4485. http_escape (obj_iri, 3, ses, 1, 1);
  4486. http (sprintf ('">%V</a> (' || endpoint_fmt, obj_iri, obj_iri), ses);
  4487. if (can_pivot)
  4488. http (DB.DBA.RDF_PIVOT_DESCRIBE_LINK (obj_iri), ses);
  4489. http (')</td></tr>', ses);
  4490. }
  4491. else
  4492. {
  4493. declare sqlval any;
  4494. declare dt, lang, strval any;
  4495. http (' property="', ses);
  4496. http_escape (pred_iri, 3, ses, 1, 1);
  4497. http ('" itemprop="', ses);
  4498. http_escape (pred_iri, 3, ses, 1, 1);
  4499. dt := 0; lang := 0;
  4500. if (__tag of rdf_box = __tag (obj))
  4501. {
  4502. if (257 <> rdf_box_lang (obj))
  4503. lang := coalesce ((select lower (RL_ID) from DB.DBA.RDF_LANGUAGE where RL_TWOBYTE = rdf_box_lang (obj)));
  4504. else if (257 <> rdf_box_type (obj))
  4505. dt := coalesce ((select __bft (RDT_QNAME, 1) from DB.DBA.RDF_DATATYPE where RDT_TWOBYTE = rdf_box_type (obj)));
  4506. sqlval := __rdf_sqlval_of_obj (obj, 1);
  4507. if (__tag of datetime = __tag (sqlval))
  4508. {
  4509. if (257 = rdf_box_type (obj))
  4510. dt := __xsd_type (sqlval);
  4511. }
  4512. }
  4513. else if (__tag (obj) not in (__tag of varchar, __tag of varbinary))
  4514. {
  4515. sqlval := obj;
  4516. dt := __xsd_type (sqlval);
  4517. }
  4518. else
  4519. sqlval := obj;
  4520. if (not (isinteger (dt)))
  4521. {
  4522. http ('" datatype="', ses);
  4523. http_escape (dt, 3, ses, 1, 1);
  4524. }
  4525. if (isstring (lang))
  4526. {
  4527. http ('" xml:lang="', ses);
  4528. http_escape (lang, 3, ses, 1, 1);
  4529. }
  4530. http ('">', ses);
  4531. if (__tag of datetime = __tag(sqlval))
  4532. __rdf_long_to_ttl (sqlval, ses);
  4533. else if (__tag (sqlval) in (__tag of varbinary, __tag of XML))
  4534. http_value (sqlval, 0, ses);
  4535. else if (__tag of varchar = __tag (sqlval))
  4536. http_value (charset_recode (sqlval, 'UTF-8', '_WIDE_'), 0, ses);
  4537. else
  4538. {
  4539. sqlval := __rdf_strsqlval (obj);
  4540. if (__tag of varchar = __tag (sqlval))
  4541. sqlval := charset_recode (sqlval, 'UTF-8', '_WIDE_');
  4542. http_value (sqlval, 0, ses);
  4543. }
  4544. http ('</td></tr>', ses);
  4545. }
  4546. }
  4547. http ('\n</table></body></html>\n', ses);
  4548. }
  4549. ;
  4550. create procedure DB.DBA.RDF_TRIPLES_TO_HTML_MICRODATA (inout triples any, inout ses any)
  4551. {
  4552. declare env, prev_subj, prev_pred, nsdict, nslist any;
  4553. declare ctr, len, tcount, tctr, status, obj_needs_br integer;
  4554. tcount := length (triples);
  4555. -- dbg_obj_princ ('DB.DBA.RDF_TRIPLES_TO_HTML_MICRODATA:'); for (tctr := 0; tctr < tcount; tctr := tctr + 1) -- dbg_obj_princ (triples[tctr]);
  4556. -- http ('<?xml version="1.0" encoding="UTF-8"?>\n<!DOCTYPE html>\n', ses);
  4557. if (0 = tcount)
  4558. {
  4559. http ('<html xmlns="http://www.w3.org/1999/xhtml">
  4560. <head><title>Empty HTML Microdata document</title></head><body>
  4561. <p>This document is empty and basically useless. It is generated by a web service that can make some statements in HTML Microdata format.
  4562. This time the service made zero such statements, sorry.</p></body></html>', ses);
  4563. return;
  4564. }
  4565. nsdict := dict_new (10 + cast (sqrt(tcount) as integer));
  4566. dict_put (nsdict, 'http://www.w3.org/1999/02/22-rdf-syntax-ns#', 'rdf');
  4567. dict_put (nsdict, 'http://www.w3.org/2001/XMLSchema#', 'xsdh');
  4568. DB.DBA.RDF_TRIPLES_BATCH_COMPLETE (triples);
  4569. for (tctr := 0; (tctr < tcount) and (1000 > dict_size (nsdict)); tctr := tctr + 1)
  4570. {
  4571. sparql_iri_split_rdfa_qname (triples[tctr][0], nsdict, 1);
  4572. sparql_iri_split_rdfa_qname (triples[tctr][1], nsdict, 1);
  4573. sparql_iri_split_rdfa_qname (triples[tctr][2], nsdict, 1);
  4574. }
  4575. http ('<html xmlns="http://www.w3.org/1999/xhtml"', ses);
  4576. http ('>\n<head><title>HTML Microdata document</title></head><body>\n', ses);
  4577. http (sprintf ('<p>This HTML5 document contains %d embedded RDF statements represented using HTML+Microdata notation.</p>',
  4578. tcount), ses);
  4579. http ('<p>The embedded RDF content will be recognized by any processor of HTML5 Microdata.</p>', ses);
  4580. http ('\n<table><tr><th>Prefix</th><th>Namespace IRI</th></tr>', ses);
  4581. nslist := dict_to_vector (nsdict, 0);
  4582. len := length (nslist);
  4583. for (ctr := len - 2; ctr >= 0; ctr := ctr-2)
  4584. {
  4585. http (sprintf ('\n<tr><td>%V</td><td>%V</td></tr>', nslist[ctr+1], nslist[ctr]), ses);
  4586. }
  4587. http ('</table>', ses);
  4588. env := vector (0, 0, 0, null);
  4589. rowvector_subj_sort (triples, 1, 1);
  4590. rowvector_subj_sort (triples, 0, 1);
  4591. prev_subj := prev_pred := null;
  4592. obj_needs_br := 0;
  4593. for (tctr := 0; tctr < tcount; tctr := tctr + 1)
  4594. {
  4595. declare subj, pred, obj, split, obj_iri_split any;
  4596. declare pred_tagname varchar;
  4597. declare res varchar;
  4598. subj := triples[tctr][0];
  4599. pred := triples[tctr][1];
  4600. obj := triples[tctr][2];
  4601. if (isstring (subj))
  4602. subj := iri_to_id (subj);
  4603. if (isstring (pred))
  4604. pred := iri_to_id (pred);
  4605. if (isstring (obj) and __box_flags (obj) = 1)
  4606. obj := iri_to_id (obj);
  4607. -- dbg_obj_princ ('DB.DBA.RDF_TRIPLES_TO_HTML_MICRODATA: subj:', subj, __tag(subj), __box_flags (subj));
  4608. -- dbg_obj_princ ('DB.DBA.RDF_TRIPLES_TO_HTML_MICRODATA: pred:', pred, __tag(pred), __box_flags (pred));
  4609. -- dbg_obj_princ ('DB.DBA.RDF_TRIPLES_TO_HTML_MICRODATA: obj:', obj, __tag(obj), __box_flags (obj));
  4610. if (prev_subj is null or (subj <> prev_subj))
  4611. {
  4612. if (prev_subj is not null)
  4613. http ('\n</dd></dl>', ses);
  4614. http (sprintf ('\n<dl itemscope itemid="%s">', replace (id_to_iri (subj), '"', '%22')), ses);
  4615. split := sparql_iri_split_rdfa_qname (subj, nsdict, 2);
  4616. -- dbg_obj_princ ('Split of ', subj, ' is ', split);
  4617. if ('' = split[1])
  4618. http (sprintf ('\n<dt>Subject Item</dt><dd>%V</dd>', split[2]), ses);
  4619. else if (isstring (split[0]))
  4620. http (sprintf ('\n<dt>Subject Item</dt><dd>%V:%V</dd>', split[0], split[2]), ses);
  4621. else
  4622. http (sprintf ('\n<dt>Subject Item</dt><dd>%V%V</dd>', split[1], split[2]), ses);
  4623. prev_subj := subj;
  4624. prev_pred := null;
  4625. }
  4626. if (prev_pred is null or (pred <> prev_pred))
  4627. {
  4628. if (prev_pred is not null)
  4629. http ('\n</dd>', ses);
  4630. split := sparql_iri_split_rdfa_qname (pred, nsdict, 2);
  4631. -- dbg_obj_princ ('Split of ', pred, ' is ', split);
  4632. if ('' = split[1])
  4633. http (sprintf ('\n<dt>%V</dt><dd>', split[2]), ses);
  4634. else if (isstring (split[0]))
  4635. http (sprintf ('\n<dt>%V:%V</dt><dd>', split[0], split[2]), ses);
  4636. else
  4637. http (sprintf ('\n<dt>%V%V</dt><dd>', split[1], split[2]), ses);
  4638. prev_pred := pred;
  4639. obj_needs_br := 0;
  4640. }
  4641. if (obj is null)
  4642. signal ('RDFXX', 'DB.DBA.TRIPLES_TO_HTML_MICRODATA: object is NULL');
  4643. if (obj_needs_br)
  4644. http ('\n', ses);
  4645. else
  4646. obj_needs_br := 1;
  4647. obj_iri_split := sparql_iri_split_rdfa_qname (obj, nsdict, 2);
  4648. if (isvector (obj_iri_split))
  4649. {
  4650. http (sprintf ('\n<a itemprop="%s" href="%s">', replace (id_to_iri (pred), '"', '%22'), replace (id_to_iri (obj), '"', '%22')), ses);
  4651. if ('' = obj_iri_split[1])
  4652. http (sprintf ('%V</a>', obj_iri_split[2]), ses);
  4653. else if (isstring (obj_iri_split[0]))
  4654. http (sprintf ('%V:%V</a>', obj_iri_split[0], obj_iri_split[2]), ses);
  4655. else
  4656. http (sprintf ('%V%V</a>', obj_iri_split[1], obj_iri_split[2]), ses);
  4657. }
  4658. else
  4659. {
  4660. declare sqlval any;
  4661. declare dt, lang, strval any;
  4662. http (sprintf ('\n<span itemprop="%s"', replace (id_to_iri (pred), '"', '%22')), ses);
  4663. dt := 0; lang := 0;
  4664. if (__tag of rdf_box = __tag (obj))
  4665. {
  4666. if (257 <> rdf_box_lang (obj))
  4667. lang := coalesce ((select lower (RL_ID) from DB.DBA.RDF_LANGUAGE where RL_TWOBYTE = rdf_box_lang (obj)));
  4668. --DT else if (257 <> rdf_box_type (obj))
  4669. --DT dt := coalesce ((select __bft (RDT_QNAME, 1) from DB.DBA.RDF_DATATYPE where RDT_TWOBYTE = rdf_box_type (obj)));
  4670. sqlval := __rdf_sqlval_of_obj (obj, 1);
  4671. --DT if (__tag of datetime = __tag (sqlval))
  4672. --DT {
  4673. --DT if (257 = rdf_box_type (obj))
  4674. --DT dt := __xsd_type (sqlval);
  4675. --DT }
  4676. }
  4677. else if (__tag (obj) not in (__tag of varchar, __tag of varbinary))
  4678. {
  4679. sqlval := obj;
  4680. --DT dt := __xsd_type (sqlval);
  4681. }
  4682. else
  4683. sqlval := obj;
  4684. --DT if (not (isinteger (dt)))
  4685. --DT {
  4686. --DT http (' datatype="', ses);
  4687. --DT split := sparql_iri_split_rdfa_qname (dt, nsdict, 2);
  4688. --DT if ('' = split[1])
  4689. --DT {
  4690. --DT http_escape (split[2], 3, ses, 1, 1);
  4691. --DT http ('"', ses);
  4692. --DT }
  4693. --DT else if (isstring (split[0]))
  4694. --DT {
  4695. --DT http_escape (concat (split[0], ':', split[2]), 3, ses, 1, 1);
  4696. --DT http ('"', ses);
  4697. --DT }
  4698. --DT else
  4699. --DT {
  4700. --DT http_escape (concat ('dt:', split[2]), 3, ses, 1, 1);
  4701. --DT http ('" xmlns:dt="', ses);
  4702. --DT http_escape (split[1], 3, ses, 1, 1);
  4703. --DT http ('"', ses);
  4704. --DT }
  4705. --DT }
  4706. if (isstring (lang))
  4707. {
  4708. http (' xml:lang="', ses);
  4709. http_escape (lang, 3, ses, 1, 1);
  4710. http ('"', ses);
  4711. }
  4712. http ('>', ses);
  4713. if (__tag of datetime = __tag(sqlval))
  4714. __rdf_long_to_ttl (sqlval, ses);
  4715. else if (__tag (sqlval) in (__tag of varbinary, __tag of XML))
  4716. http_value (sqlval, 0, ses);
  4717. else if (__tag of varchar = __tag (sqlval))
  4718. http_value (charset_recode (sqlval, 'UTF-8', '_WIDE_'), 0, ses);
  4719. else
  4720. {
  4721. sqlval := __rdf_strsqlval (obj);
  4722. if (__tag of varchar = __tag (sqlval))
  4723. sqlval := charset_recode (sqlval, 'UTF-8', '_WIDE_');
  4724. http_value (sqlval, 0, ses);
  4725. }
  4726. http ('</span>', ses);
  4727. }
  4728. }
  4729. if (prev_subj is not null)
  4730. http ('\n</dd></dl>', ses);
  4731. http ('\n</body></html>\n', ses);
  4732. }
  4733. ;
  4734. create procedure DB.DBA.RDF_TRIPLES_TO_HTML_NICE_MICRODATA (inout triples any, inout ses any)
  4735. {
  4736. declare env, prev_subj, prev_pred, nsdict, nslist any;
  4737. declare subj_text, s_itemid, p_itemprop, nice_host, describe_path, about_path varchar;
  4738. declare ctr, len, tcount, tctr, status, obj_needs_br integer;
  4739. tcount := length (triples);
  4740. -- dbg_obj_princ ('DB.DBA.RDF_TRIPLES_TO_HTML_NICE_MICRODATA:'); for (tctr := 0; tctr < tcount; tctr := tctr + 1) -- dbg_obj_princ (triples[tctr]);
  4741. -- http ('<?xml version="1.0" encoding="UTF-8"?>\n<!DOCTYPE html>\n', ses);
  4742. if (0 = tcount)
  4743. {
  4744. http ('<html xmlns="http://www.w3.org/1999/xhtml">
  4745. <head><title>Empty HTML Microdata document</title></head><body>
  4746. <p>This document is empty and basically useless. It is generated by a web service that can make some statements in HTML Microdata format.
  4747. This time the service made zero such statements, sorry.</p></body></html>', ses);
  4748. return;
  4749. }
  4750. nice_host := registry_get ('URIQADefaultHost');
  4751. describe_path := about_path := null;
  4752. if (isstring (nice_host))
  4753. {
  4754. if (exists (select 1 from VAD.DBA.VAD_REGISTRY where R_KEY like '/VAD/fct/%/resources/dav/%'))
  4755. describe_path := 'http://' || nice_host || '/describe/?url=';
  4756. if (exists (select 1 from VAD.DBA.VAD_REGISTRY where R_KEY like '/VAD/cartridges/%/resources/dav/%'))
  4757. about_path := 'http://' || nice_host || '/about/html/';
  4758. }
  4759. nsdict := dict_new (10 + cast (sqrt(tcount) as integer));
  4760. dict_put (nsdict, 'http://www.w3.org/1999/02/22-rdf-syntax-ns#', 'rdf');
  4761. dict_put (nsdict, 'http://www.w3.org/2001/XMLSchema#', 'xsdh');
  4762. DB.DBA.RDF_TRIPLES_BATCH_COMPLETE (triples);
  4763. for (tctr := 0; (tctr < tcount) and (1000 > dict_size (nsdict)); tctr := tctr + 1)
  4764. {
  4765. sparql_iri_split_rdfa_qname (triples[tctr][0], nsdict, 1);
  4766. sparql_iri_split_rdfa_qname (triples[tctr][1], nsdict, 1);
  4767. sparql_iri_split_rdfa_qname (triples[tctr][2], nsdict, 1);
  4768. }
  4769. http ('<html xmlns="http://www.w3.org/1999/xhtml"', ses);
  4770. http ('>\n<head><title>HTML Based Entity Description (with embedded Microdata)</title></head><body>\n', ses);
  4771. http (sprintf ('<p>This HTML5 document contains %d embedded RDF statements represented using HTML+Microdata notation.</p>',
  4772. tcount), ses);
  4773. http ('<p>The embedded RDF content will be recognized by any processor of HTML5 Microdata.</p>', ses);
  4774. -- http ('\n<table><tr><th>Prefix</th><th>Namespace IRI</th></tr>', ses);
  4775. -- nslist := dict_to_vector (nsdict, 0);
  4776. -- len := length (nslist);
  4777. -- for (ctr := len - 2; ctr >= 0; ctr := ctr-2)
  4778. -- {
  4779. -- http (sprintf ('\n<tr><td>%V</td><td>%V</td></tr>', nslist[ctr+1], nslist[ctr]), ses);
  4780. -- }
  4781. -- http ('</table>', ses);
  4782. env := vector (0, 0, 0, null);
  4783. rowvector_subj_sort (triples, 1, 1);
  4784. rowvector_subj_sort (triples, 0, 1);
  4785. prev_subj := prev_pred := null;
  4786. obj_needs_br := 0;
  4787. http ('\n<table border=1><tr><th>Subject</th><th>Predicate</th><th>Object</th></tr>', ses);
  4788. for (tctr := 0; tctr < tcount; tctr := tctr + 1)
  4789. {
  4790. declare subj, pred, obj, split, o_split any;
  4791. declare pred_tagname varchar;
  4792. declare res varchar;
  4793. subj := triples[tctr][0];
  4794. pred := triples[tctr][1];
  4795. obj := triples[tctr][2];
  4796. if (isstring (subj))
  4797. subj := iri_to_id (subj);
  4798. if (isstring (pred))
  4799. pred := iri_to_id (pred);
  4800. if (isstring (obj) and __box_flags (obj) = 1)
  4801. obj := iri_to_id (obj);
  4802. -- dbg_obj_princ ('DB.DBA.RDF_TRIPLES_TO_HTML_NICE_MICRODATA: subj:', subj, __tag(subj), __box_flags (subj));
  4803. -- dbg_obj_princ ('DB.DBA.RDF_TRIPLES_TO_HTML_NICE_MICRODATA: pred:', pred, __tag(pred), __box_flags (pred));
  4804. -- dbg_obj_princ ('DB.DBA.RDF_TRIPLES_TO_HTML_NICE_MICRODATA: obj:', obj, __tag(obj), __box_flags (obj));
  4805. if (prev_subj is null or (subj <> prev_subj))
  4806. {
  4807. if (prev_subj is not null)
  4808. http ('\n</td></tr>', ses);
  4809. split := sparql_iri_split_rdfa_qname (subj, nsdict, 2);
  4810. s_itemid := replace (id_to_iri (subj), '"', '%22');
  4811. -- dbg_obj_princ ('Split of ', subj, ' is ', split);
  4812. if (about_path is null)
  4813. {
  4814. if ('' = split[1]) subj_text := sprintf ('\n<td><a href="%s">%V</a></td>' , s_itemid, split[2]);
  4815. else if (isstring (split[0])) subj_text := sprintf ('\n<td><a href="%s">%V:%V</a></td>' , s_itemid, split[0], split[2]);
  4816. else subj_text := sprintf ('\n<td><a href="%s">%V%V</a></td>' , s_itemid, split[1], split[2]);
  4817. }
  4818. else
  4819. {
  4820. if ('' = split[1]) subj_text := sprintf ('\n<td><a href="%s">%V</a> (<a href="%s%s">/about</a>)</td>' , s_itemid, split[2] , about_path, s_itemid);
  4821. else if (isstring (split[0])) subj_text := sprintf ('\n<td><a href="%s">%V:%V</a> (<a href="%s%s">/about</a>)</td>' , s_itemid, split[0], split[2] , about_path, s_itemid);
  4822. else subj_text := sprintf ('\n<td><a href="%s">%V%V</a> (<a href="%s%s">/about</a>)</td>' , s_itemid, split[1], split[2] , about_path, s_itemid);
  4823. }
  4824. prev_subj := subj;
  4825. prev_pred := null;
  4826. }
  4827. if (prev_pred is null or (pred <> prev_pred))
  4828. {
  4829. if (prev_pred is not null)
  4830. http ('\n</td></tr>', ses);
  4831. http ('\n<tr>', ses);
  4832. http (subj_text, ses);
  4833. split := sparql_iri_split_rdfa_qname (pred, nsdict, 2);
  4834. p_itemprop := replace (id_to_iri (pred), '"', '%22');
  4835. -- dbg_obj_princ ('Split of ', pred, ' is ', split);
  4836. if ('' = split[1]) http (sprintf ('\n<td><a href="%s">%V</a>' , p_itemprop, split[2]) , ses);
  4837. else if (isstring (split[0])) http (sprintf ('\n<td><a href="%s">%V:%V</a>' , p_itemprop, split[0], split[2]) , ses);
  4838. else http (sprintf ('\n<td><a href="%s">%V%V</a>' , p_itemprop, split[1], split[2]) , ses);
  4839. if (describe_path is not null)
  4840. http (sprintf (' (<a href="%s%U">/describe</a>)</td>' , describe_path, id_to_iri (pred)), ses);
  4841. http (sprintf ('</td>\n<td itemscope itemid="%s">', s_itemid), ses);
  4842. prev_pred := pred;
  4843. obj_needs_br := 0;
  4844. }
  4845. if (obj is null)
  4846. signal ('RDFXX', 'DB.DBA.TRIPLES_TO_HTML_NICE_MICRODATA: object is NULL');
  4847. if (obj_needs_br)
  4848. http (' ,', ses);
  4849. else
  4850. obj_needs_br := 1;
  4851. o_split := sparql_iri_split_rdfa_qname (obj, nsdict, 2);
  4852. if (isvector (o_split))
  4853. {
  4854. declare o_href varchar;
  4855. o_href := replace (id_to_iri (obj), '"', '%22');
  4856. if ('' = o_split[1]) http (sprintf ('\n<a itemprop="%V" href="%s">%V</a>' , p_itemprop, o_href, o_split[2]) , ses);
  4857. else if (isstring (o_split[0])) http (sprintf ('\n<a itemprop="%V" href="%s">%V:%V</a>' , p_itemprop, o_href, o_split[0], o_split[2]) , ses);
  4858. else http (sprintf ('\n<a itemprop="%V" href="%s">%V%V</a>' , p_itemprop, o_href, o_split[1], o_split[2]) , ses);
  4859. if (about_path is not null)
  4860. http (sprintf ('\n(<a href="%s%s">/about</a>)', about_path, o_href), ses);
  4861. }
  4862. else
  4863. {
  4864. declare sqlval any;
  4865. declare dt, lang, strval any;
  4866. http (sprintf ('\n<span itemprop="%s"', replace (id_to_iri (pred), '"', '%22')), ses);
  4867. dt := 0; lang := 0;
  4868. if (__tag of rdf_box = __tag (obj))
  4869. {
  4870. if (257 <> rdf_box_lang (obj))
  4871. lang := coalesce ((select lower (RL_ID) from DB.DBA.RDF_LANGUAGE where RL_TWOBYTE = rdf_box_lang (obj)));
  4872. --DT else if (257 <> rdf_box_type (obj))
  4873. --DT dt := coalesce ((select __bft (RDT_QNAME, 1) from DB.DBA.RDF_DATATYPE where RDT_TWOBYTE = rdf_box_type (obj)));
  4874. sqlval := __rdf_sqlval_of_obj (obj, 1);
  4875. --DT if (__tag of datetime = __tag (sqlval))
  4876. --DT {
  4877. --DT if (257 = rdf_box_type (obj))
  4878. --DT dt := __xsd_type (sqlval);
  4879. --DT }
  4880. }
  4881. else if (__tag (obj) not in (__tag of varchar, __tag of varbinary))
  4882. {
  4883. sqlval := obj;
  4884. --DT dt := __xsd_type (sqlval);
  4885. }
  4886. else
  4887. sqlval := obj;
  4888. --DT if (not (isinteger (dt)))
  4889. --DT {
  4890. --DT http (' datatype="', ses);
  4891. --DT split := sparql_iri_split_rdfa_qname (dt, nsdict, 2);
  4892. --DT if ('' = split[1])
  4893. --DT {
  4894. --DT http_escape (split[2], 3, ses, 1, 1);
  4895. --DT http ('"', ses);
  4896. --DT }
  4897. --DT else if (isstring (split[0]))
  4898. --DT {
  4899. --DT http_escape (concat (split[0], ':', split[2]), 3, ses, 1, 1);
  4900. --DT http ('"', ses);
  4901. --DT }
  4902. --DT else
  4903. --DT {
  4904. --DT http_escape (concat ('dt:', split[2]), 3, ses, 1, 1);
  4905. --DT http ('" xmlns:dt="', ses);
  4906. --DT http_escape (split[1], 3, ses, 1, 1);
  4907. --DT http ('"', ses);
  4908. --DT }
  4909. --DT }
  4910. if (isstring (lang))
  4911. {
  4912. http (' xml:lang="', ses);
  4913. http_escape (lang, 3, ses, 1, 1);
  4914. http ('"', ses);
  4915. }
  4916. http ('>', ses);
  4917. if (__tag of datetime = __tag(sqlval))
  4918. __rdf_long_to_ttl (sqlval, ses);
  4919. else if (__tag (sqlval) in (__tag of varbinary, __tag of XML))
  4920. http_value (sqlval, 0, ses);
  4921. else if (__tag of varchar = __tag (sqlval))
  4922. http_value (charset_recode (sqlval, 'UTF-8', '_WIDE_'), 0, ses);
  4923. else
  4924. {
  4925. sqlval := __rdf_strsqlval (obj);
  4926. if (__tag of varchar = __tag (sqlval))
  4927. sqlval := charset_recode (sqlval, 'UTF-8', '_WIDE_');
  4928. http_value (sqlval, 0, ses);
  4929. }
  4930. http ('</span>', ses);
  4931. }
  4932. }
  4933. if (prev_subj is not null)
  4934. http ('\n</td></tr></table>', ses);
  4935. http ('\n</body></html>\n', ses);
  4936. }
  4937. ;
  4938. create procedure DB.DBA.RDF_TRIPLES_TO_JSON_MICRODATA (inout triples any, inout ses any)
  4939. {
  4940. declare env, prev_subj, prev_pred any;
  4941. declare ctr, len, tcount, tctr, status, obj_needs_comma integer;
  4942. tcount := length (triples);
  4943. -- dbg_obj_princ ('DB.DBA.RDF_TRIPLES_TO_JSON_MICRODATA:'); for (tctr := 0; tctr < tcount; tctr := tctr + 1) -- dbg_obj_princ (triples[tctr]);
  4944. http ('{ "items" : [', ses);
  4945. env := vector (0, 0, 0, null);
  4946. rowvector_subj_sort (triples, 1, 1);
  4947. rowvector_subj_sort (triples, 0, 1);
  4948. DB.DBA.RDF_TRIPLES_BATCH_COMPLETE (triples);
  4949. prev_subj := prev_pred := null;
  4950. obj_needs_comma := 0;
  4951. for (tctr := 0; tctr < tcount; tctr := tctr + 1)
  4952. {
  4953. declare subj, pred, obj, split, obj_iri_split any;
  4954. declare pred_tagname varchar;
  4955. declare res varchar;
  4956. subj := triples[tctr][0];
  4957. pred := triples[tctr][1];
  4958. obj := triples[tctr][2];
  4959. -- dbg_obj_princ ('DB.DBA.RDF_TRIPLES_TO_JSON_MICRODATA: subj:', subj, __tag(subj), __box_flags (subj));
  4960. -- dbg_obj_princ ('DB.DBA.RDF_TRIPLES_TO_JSON_MICRODATA: pred:', pred, __tag(pred), __box_flags (pred));
  4961. -- dbg_obj_princ ('DB.DBA.RDF_TRIPLES_TO_JSON_MICRODATA: obj:', obj, __tag(obj), __box_flags (obj));
  4962. if (prev_subj is null or (subj <> prev_subj))
  4963. {
  4964. declare subj_iri varchar;
  4965. if (prev_subj is not null)
  4966. http (' ] } },\n', ses);
  4967. if (isstring (subj))
  4968. subj_iri := subj;
  4969. else
  4970. subj_iri := id_to_iri (subj);
  4971. if (starts_with (subj_iri, 'nodeID://'))
  4972. subj_iri := '_:' || subseq (subj_iri, 9);
  4973. http ('\n { "id" : "', ses); http_escape (subj_iri, 14, ses, 1, 1); http ('"\n "properties" : {', ses);
  4974. prev_subj := subj;
  4975. prev_pred := null;
  4976. }
  4977. if (prev_pred is null or (pred <> prev_pred))
  4978. {
  4979. if (prev_pred is not null)
  4980. http (' ] ,', ses);
  4981. http ('\n "', ses); http_escape (case when isstring (pred) then pred else id_to_iri (pred) end, 14, ses, 1, 1); http ('" : [ ', ses);
  4982. prev_pred := pred;
  4983. obj_needs_comma := 0;
  4984. }
  4985. if (obj is null)
  4986. signal ('RDFXX', 'DB.DBA.TRIPLES_TO_JSON_MICRODATA: object is NULL');
  4987. if (obj_needs_comma)
  4988. http (',\n ', ses);
  4989. else
  4990. obj_needs_comma := 1;
  4991. if (isiri_id (obj))
  4992. {
  4993. declare obj_iri varchar;
  4994. obj_iri := id_to_iri (obj);
  4995. if (starts_with (obj_iri, 'nodeID://'))
  4996. obj_iri := '_:' || subseq (obj_iri, 9);
  4997. http ('{ "id" : "', ses); http_escape (obj_iri, 14, ses, 1, 1); http ('" }', ses);
  4998. }
  4999. else
  5000. {
  5001. declare sqlval any;
  5002. declare dt, lang, strval any;
  5003. dt := 0; lang := 0;
  5004. if (__tag of rdf_box = __tag (obj))
  5005. {
  5006. if (257 <> rdf_box_lang (obj))
  5007. lang := coalesce ((select lower (RL_ID) from DB.DBA.RDF_LANGUAGE where RL_TWOBYTE = rdf_box_lang (obj)));
  5008. --DT else if (257 <> rdf_box_type (obj))
  5009. --DT dt := coalesce ((select __bft (RDT_QNAME, 1) from DB.DBA.RDF_DATATYPE where RDT_TWOBYTE = rdf_box_type (obj)));
  5010. sqlval := __rdf_sqlval_of_obj (obj, 1);
  5011. --DT if (__tag of datetime = __tag (sqlval))
  5012. --DT {
  5013. --DT if (257 = rdf_box_type (obj))
  5014. --DT dt := __xsd_type (sqlval);
  5015. --DT }
  5016. }
  5017. else if (__tag (obj) not in (__tag of varchar, __tag of varbinary))
  5018. {
  5019. sqlval := obj;
  5020. --DT dt := __xsd_type (sqlval);
  5021. }
  5022. else
  5023. sqlval := obj;
  5024. --DT if (not (isinteger (dt)))
  5025. --DT {
  5026. --DT http (' datatype="', ses);
  5027. --DT split := sparql_iri_split_rdfa_qname (dt, nsdict, 2);
  5028. --DT if ('' = split[1])
  5029. --DT {
  5030. --DT http_escape (split[2], 3, ses, 1, 1);
  5031. --DT http ('"', ses);
  5032. --DT }
  5033. --DT else if (isstring (split[0]))
  5034. --DT {
  5035. --DT http_escape (concat (split[0], ':', split[2]), 3, ses, 1, 1);
  5036. --DT http ('"', ses);
  5037. --DT }
  5038. --DT else
  5039. --DT {
  5040. --DT http_escape (concat ('dt:', split[2]), 3, ses, 1, 1);
  5041. --DT http ('" xmlns:dt="', ses);
  5042. --DT http_escape (split[1], 3, ses, 1, 1);
  5043. --DT http ('"', ses);
  5044. --DT }
  5045. --DT }
  5046. --DT if (isstring (lang))
  5047. --DT {
  5048. --DT http (' xml:lang="', ses);
  5049. --DT http_escape (lang, 3, ses, 1, 1);
  5050. --DT http ('"', ses);
  5051. --DT }
  5052. --DT http ('>', ses);
  5053. if (__tag (sqlval) in (__tag of integer, __tag of real, __tag of double precision, __tag of decimal))
  5054. http_value (sqlval, 0, ses);
  5055. else if (__tag (sqlval) in (__tag of varbinary, __tag of XML))
  5056. {
  5057. declare tmpses any;
  5058. tmpses := string_output();
  5059. http_value (sqlval, 0, tmpses);
  5060. http ('"', ses); http_escape (string_output_string (tmpses), 14, ses, 1, 1); http ('"', ses);
  5061. }
  5062. else if (__tag of varchar = __tag (sqlval))
  5063. {
  5064. http ('"', ses); http_escape (sqlval, 14, ses, 1, 1); http ('"', ses);
  5065. }
  5066. else
  5067. {
  5068. sqlval := __rdf_strsqlval (obj);
  5069. http ('"', ses); http_escape (sqlval, 14, ses, 1, 1); http ('"', ses);
  5070. }
  5071. }
  5072. }
  5073. if (prev_subj is not null)
  5074. http ('] } }', ses);
  5075. http (' }\n', ses);
  5076. }
  5077. ;
  5078. -- /* OData ATOM format */
  5079. create function DB.DBA.RDF_FORMAT_TRIPLE_DICT_AS_ATOM_XML (inout triples_dict any) returns long varchar
  5080. {
  5081. declare triples, ses any;
  5082. ses := string_output ();
  5083. if (214 <> __tag (triples_dict))
  5084. {
  5085. triples := vector ();
  5086. }
  5087. else
  5088. triples := dict_list_keys (triples_dict, 1);
  5089. DB.DBA.RDF_TRIPLES_TO_ATOM_XML_TEXT (triples, 1, ses);
  5090. return ses;
  5091. }
  5092. ;
  5093. create procedure DB.DBA.ODATA_EDM_TYPE (in obj any)
  5094. {
  5095. if (__tag of int = __tag (obj))
  5096. return 'Int32';
  5097. else if (__tag of smallint = __tag (obj))
  5098. return 'Int16';
  5099. else if (__tag of bigint = __tag (obj))
  5100. return 'Int64';
  5101. else if (__tag of numeric = __tag (obj))
  5102. return 'Decimal';
  5103. else if (__tag of double precision = __tag (obj))
  5104. return 'Double';
  5105. else if (__tag of real = __tag (obj))
  5106. return 'Double';
  5107. else if (__tag of datetime = __tag (obj))
  5108. return 'DateTime';
  5109. else if (__tag of date = __tag (obj))
  5110. return 'Date';
  5111. else if (__tag of time = __tag (obj))
  5112. return 'Time';
  5113. else if (__tag of varbinary = __tag (obj))
  5114. return 'Binary';
  5115. return null;
  5116. }
  5117. ;
  5118. create function DB.DBA.RDF_FORMAT_TRIPLE_DICT_AS_ODATA_JSON (inout triples_dict any) returns long varchar
  5119. {
  5120. declare triples, ses any;
  5121. ses := string_output ();
  5122. if (214 <> __tag (triples_dict))
  5123. {
  5124. triples := vector ();
  5125. }
  5126. else
  5127. triples := dict_list_keys (triples_dict, 1);
  5128. DB.DBA.RDF_TRIPLES_TO_ODATA_JSON (triples, ses);
  5129. return ses;
  5130. }
  5131. ;
  5132. create procedure DB.DBA.RDF_TRIPLES_TO_ODATA_JSON (inout triples any, inout ses any)
  5133. {
  5134. declare tcount, tctr, ns_ctr integer;
  5135. declare dict, entries any;
  5136. declare subj, pred, obj any;
  5137. declare entry_dict, ns_dict, ns_arr any;
  5138. declare pred_tagname varchar;
  5139. declare p_ns_uri, p_ns_pref varchar;
  5140. dict := dict_new ();
  5141. ns_dict := dict_new ();
  5142. ns_ctr := 0;
  5143. tcount := length (triples);
  5144. DB.DBA.RDF_TRIPLES_BATCH_COMPLETE (triples);
  5145. http ('{ "d" : { \n "results": [ \n', ses);
  5146. for (tctr := 0; tctr < tcount; tctr := tctr + 1)
  5147. {
  5148. subj := triples[tctr][0];
  5149. pred := triples[tctr][1];
  5150. obj := triples[tctr][2];
  5151. entry_dict := dict_get (dict, subj);
  5152. if (entry_dict is null)
  5153. {
  5154. entry_dict := dict_new ();
  5155. dict_put (dict, subj, entry_dict);
  5156. }
  5157. dict_put (entry_dict, vector (pred, obj), 1);
  5158. }
  5159. entries := dict_list_keys (dict, 0);
  5160. tcount := length (entries);
  5161. for (tctr := 0; tctr < tcount; tctr := tctr + 1)
  5162. {
  5163. declare meta any;
  5164. declare has_meta, mcount int;
  5165. declare title, content varchar;
  5166. has_meta := 0; title := null; content := null;
  5167. subj := entries[tctr];
  5168. entry_dict := dict_get (dict, subj);
  5169. meta := dict_list_keys (entry_dict, 1);
  5170. if (isiri_id (subj)) subj := id_to_iri (subj);
  5171. http (' { ', ses);
  5172. http (sprintf ('"__metadata": { "uri": "%s" }, \n', subj), ses);
  5173. for (declare i, l int, i := 0, l := length (meta); i < l; i := i + 1)
  5174. {
  5175. pred := meta[i][0];
  5176. obj := meta[i][1];
  5177. if (isiri_id (pred)) pred := id_to_iri (pred);
  5178. if (isiri_id (obj) or (isstring (obj) and __box_flags (obj) = 1))
  5179. {
  5180. -- links
  5181. if (isiri_id (obj)) obj := id_to_iri (obj);
  5182. http (sprintf (' "%s": { "__deferred": { "uri": "%s" } }', pred, obj), ses);
  5183. }
  5184. else
  5185. {
  5186. -- data
  5187. declare tmp any;
  5188. http (sprintf (' "%s": ', pred), ses);
  5189. if (__tag of rdf_box = __tag (obj))
  5190. {
  5191. tmp := __rdf_strsqlval (obj);
  5192. if (__tag of varchar = __tag (tmp))
  5193. tmp := charset_recode (tmp, 'UTF-8', '_WIDE_');
  5194. }
  5195. else
  5196. {
  5197. tmp := obj;
  5198. }
  5199. http ('"', ses);
  5200. http_value (tmp, 0, ses);
  5201. http ('"', ses);
  5202. }
  5203. if (i < l - 1)
  5204. http (', \n', ses);
  5205. }
  5206. http ('\n } ', ses);
  5207. if (tctr < tcount - 1)
  5208. http (', ', ses);
  5209. }
  5210. http (sprintf ('\n ], "__count": "%d"\n } }', tcount), ses);
  5211. }
  5212. ;
  5213. create procedure DB.DBA.RDF_TRIPLES_TO_ATOM_XML_TEXT (inout triples any, in print_top_level integer, inout ses any)
  5214. {
  5215. declare tcount, tctr, ns_ctr integer;
  5216. declare dict, entries any;
  5217. declare subj, pred, obj any;
  5218. declare entry_dict, ns_dict, ns_arr any;
  5219. declare pred_tagname varchar;
  5220. declare p_ns_uri, p_ns_pref, lang, range varchar;
  5221. declare pct integer;
  5222. declare twobyte integer;
  5223. dict := dict_new ();
  5224. ns_dict := dict_new ();
  5225. ns_ctr := 0; pct := 0;
  5226. tcount := length (triples);
  5227. DB.DBA.RDF_TRIPLES_BATCH_COMPLETE (triples);
  5228. if (print_top_level)
  5229. {
  5230. http ('<?xml version="1.0" encoding="utf-8" ?>\n<feed \n\t xmlns="http://www.w3.org/2005/Atom" \n'||
  5231. '\t xmlns:d="http://schemas.microsoft.com/ado/2007/08/dataservices" \n'||
  5232. '\t xmlns:m="http://schemas.microsoft.com/ado/2007/08/dataservices/metadata" \n', ses);
  5233. }
  5234. for (tctr := 0; tctr < tcount; tctr := tctr + 1)
  5235. {
  5236. subj := triples[tctr][0];
  5237. pred := triples[tctr][1];
  5238. obj := triples[tctr][2];
  5239. entry_dict := dict_get (dict, subj);
  5240. if (entry_dict is null)
  5241. {
  5242. entry_dict := dict_new ();
  5243. dict_put (dict, subj, entry_dict);
  5244. }
  5245. dict_put (entry_dict, vector (pred, obj), 1);
  5246. if (isiri_id (obj) or (isstring (obj) and __box_flags (obj) = 1))
  5247. goto next;
  5248. if (isiri_id (pred)) pred := id_to_iri (pred);
  5249. p_ns_uri := iri_split (pred, pred_tagname);
  5250. if (length (p_ns_uri) > 0 and dict_get (ns_dict, p_ns_uri) is null)
  5251. {
  5252. p_ns_pref := __xml_get_ns_prefix (p_ns_uri, 3);
  5253. if (p_ns_pref is null)
  5254. {
  5255. p_ns_pref := sprintf ('ns%dpred', ns_ctr);
  5256. ns_ctr := ns_ctr + 1;
  5257. }
  5258. dict_put (ns_dict, p_ns_uri, p_ns_pref);
  5259. }
  5260. next:;
  5261. }
  5262. ns_arr := dict_to_vector (ns_dict, 0);
  5263. for (declare i int, i := 0; i < length (ns_arr); i := i + 2)
  5264. {
  5265. http (sprintf ('\t xmlns:%s="%s"\n', ns_arr[i+1], ns_arr[i]), ses);
  5266. }
  5267. http ('>\n', ses);
  5268. if (is_http_ctx ())
  5269. {
  5270. declare q, u, h, id varchar;
  5271. declare lines any;
  5272. q := http_request_get ('QUERY_STRING');
  5273. if (length (q))
  5274. q := '?' || q;
  5275. else
  5276. q := '';
  5277. u := http_request_get ('REQUEST_URI');
  5278. h := WS.WS.PARSE_URI (http_requested_url () || q);
  5279. h [2] := u; h [4] := '';
  5280. id := WS.WS.VFS_URI_COMPOSE (h);
  5281. http (sprintf ('\t<id>%V</id>\n', id), ses);
  5282. lines := http_request_header ();
  5283. range := http_request_header_full (lines, 'Accept-Language', 'en');
  5284. }
  5285. else
  5286. {
  5287. http ('\t<id/>\n', ses);
  5288. range := 'en, */*;0.1';
  5289. }
  5290. http (sprintf ('\t<updated>%s</updated>\n', date_iso8601 (dt_set_tz (now (), 0))), ses);
  5291. http ('\t<author><name /></author>\n', ses);
  5292. http (sprintf ('\t<title type="text">OData Service and Descriptor Document</title>\n'), ses);
  5293. entries := dict_list_keys (dict, 0);
  5294. tcount := length (entries);
  5295. for (tctr := 0; tctr < tcount; tctr := tctr + 1)
  5296. {
  5297. declare meta any;
  5298. declare has_meta int;
  5299. declare title, content varchar;
  5300. pct := 0;
  5301. has_meta := 0; title := null; content := null;
  5302. subj := entries[tctr];
  5303. entry_dict := dict_get (dict, subj);
  5304. meta := dict_list_keys (entry_dict, 1);
  5305. http ('\t<entry>\n', ses);
  5306. if (isiri_id (subj)) subj := id_to_iri (subj);
  5307. http (sprintf ('\t\t<id>%s</id>\n', subj), ses);
  5308. --http (sprintf ('\t\t<link rel="self" href="%s"/>\n', subj), ses);
  5309. for (declare i, l int, i := 0, l := length (meta); i < l; i := i + 1)
  5310. {
  5311. pred := meta[i][0];
  5312. obj := meta[i][1];
  5313. if (isiri_id (obj) or (isstring (obj) and __box_flags (obj) = 1))
  5314. {
  5315. if (isiri_id (obj)) obj := id_to_iri (obj);
  5316. if (isiri_id (pred)) pred := id_to_iri (pred);
  5317. --p_ns_uri := iri_split (pred, pred_tagname);
  5318. --if (length (p_ns_uri) > 0)
  5319. --{
  5320. -- p_ns_pref := dict_get (ns_dict, p_ns_uri);
  5321. -- pred_tagname := p_ns_pref || ':' || pred_tagname;
  5322. --}
  5323. http (sprintf ('\t\t<link rel="%s" href="%s"/>\n', pred, obj), ses);
  5324. }
  5325. else
  5326. {
  5327. if (title is null and
  5328. (
  5329. pred = iri_to_id ('http://purl.org/dc/terms/title') or
  5330. pred = iri_to_id ('http://www.w3.org/2000/01/rdf-schema#label'))
  5331. )
  5332. {
  5333. declare rc int;
  5334. lang := 'en';
  5335. if (__tag of rdf_box = __tag (obj))
  5336. {
  5337. twobyte := rdf_box_lang (obj);
  5338. if (twobyte <> 257)
  5339. {
  5340. lang := coalesce ((select lower (RL_ID) from DB.DBA.RDF_LANGUAGE where RL_TWOBYTE = twobyte), lang);
  5341. }
  5342. }
  5343. rc := langmatches_pct_http (lang, range);
  5344. if (pct < rc)
  5345. {
  5346. title := __rdf_strsqlval (obj);
  5347. pct := rc;
  5348. }
  5349. }
  5350. has_meta := 1;
  5351. }
  5352. }
  5353. if (title is not null)
  5354. http (sprintf ('\t\t<title>%s</title>\n', title), ses);
  5355. http (sprintf ('\t\t<updated>%s</updated>\n', date_iso8601 (dt_set_tz (now (), 0))), ses);
  5356. http ('\t\t<author><name /></author>\n', ses);
  5357. if (has_meta)
  5358. http ('\t\t<content type="application/xml">\n\t\t\t<m:properties>\n', ses);
  5359. for (declare i, l int, i := 0, l := length (meta); i < l; i := i + 1)
  5360. {
  5361. pred := meta[i][0];
  5362. obj := meta[i][1];
  5363. if (isiri_id (pred)) pred := id_to_iri (pred);
  5364. if (not (isiri_id (obj) or (isstring (obj) and __box_flags (obj) = 1)))
  5365. {
  5366. p_ns_uri := iri_split (pred, pred_tagname);
  5367. if (length (p_ns_uri) = 0)
  5368. {
  5369. http ('<', ses); http (pred_tagname, ses);
  5370. }
  5371. else
  5372. {
  5373. p_ns_pref := dict_get (ns_dict, p_ns_uri);
  5374. pred_tagname := p_ns_pref || ':' || pred_tagname;
  5375. http ('\t\t\t\t<', ses); http (pred_tagname, ses);
  5376. if (__tag of rdf_box = __tag (obj))
  5377. {
  5378. declare tmp any;
  5379. tmp := __rdf_strsqlval (obj);
  5380. twobyte := rdf_box_lang (obj);
  5381. if (twobyte <> 257)
  5382. {
  5383. lang := coalesce ((select lower (RL_ID) from DB.DBA.RDF_LANGUAGE where RL_TWOBYTE = twobyte), lang);
  5384. http (sprintf (' xml:lang="%s"', lang), ses);
  5385. }
  5386. http ('>', ses);
  5387. if (__tag of varchar = __tag (tmp))
  5388. tmp := charset_recode (tmp, 'UTF-8', '_WIDE_');
  5389. http_value (tmp, 0, ses);
  5390. }
  5391. else
  5392. {
  5393. declare tp varchar;
  5394. tp := ODATA_EDM_TYPE (obj);
  5395. if (tp is not null)
  5396. http (sprintf (' m:type="Edm.%s"', tp), ses);
  5397. http ('>', ses);
  5398. if (__tag of varbinary = __tag (obj))
  5399. obj := encode_base64 (cast (obj as varchar));
  5400. http_value (obj, 0, ses);
  5401. }
  5402. http ('</', ses); http (pred_tagname, ses); http ('>\n', ses);
  5403. }
  5404. }
  5405. }
  5406. if (has_meta)
  5407. http ('\t\t\t</m:properties>\n\t\t</content>\n', ses);
  5408. http ('\t</entry>\n', ses);
  5409. }
  5410. if (print_top_level)
  5411. {
  5412. http ('</feed>', ses);
  5413. }
  5414. }
  5415. ;
  5416. -----
  5417. -- Export into external serializations for 'define output:format "..."'
  5418. create procedure DB.DBA.RDF_FORMAT_RESULT_SET_AS_TTL_INIT (inout _env any)
  5419. {
  5420. _env := string_output();
  5421. http ('@prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> .
  5422. @prefix rs: <http://www.w3.org/2005/sparql-results#> .
  5423. @prefix xsd: <http://www.w3.org/2001/XMLSchema#> .
  5424. [ rdf:type rs:results ;', _env);
  5425. }
  5426. ;
  5427. create procedure DB.DBA.RDF_FORMAT_RESULT_SET_AS_TTL_ACC (inout _env any, inout colvalues any, inout colnames any)
  5428. {
  5429. declare col_ctr, col_count integer;
  5430. declare blank_ids any;
  5431. if (185 <> __tag(_env))
  5432. DB.DBA.RDF_FORMAT_RESULT_SET_AS_TTL_INIT (_env);
  5433. http ('\n rs:result [', _env);
  5434. col_count := length (colnames);
  5435. for (col_ctr := 0; col_ctr < col_count; col_ctr := col_ctr + 1)
  5436. {
  5437. declare _name varchar;
  5438. declare _val any;
  5439. _name := colnames[col_ctr];
  5440. _val := colvalues[col_ctr];
  5441. if (_val is null)
  5442. goto end_of_binding;
  5443. http ('\n rs:binding [ rs:name "', _env);
  5444. http_value (colnames[col_ctr], 0, _env);
  5445. http ('" ; rs:value ', _env);
  5446. if (isiri_id (_val))
  5447. {
  5448. if (_val >= min_bnode_iri_id ())
  5449. {
  5450. http (sprintf ('_:nodeID%d ] ;', iri_id_num (_val)), _env);
  5451. }
  5452. else
  5453. {
  5454. declare res varchar;
  5455. res := id_to_iri (_val);
  5456. -- res := coalesce ((select RU_QNAME from DB.DBA.RDF_URL where RU_IID = _val));
  5457. if (res is null)
  5458. res := sprintf ('<bad://%d>', iri_id_num (_val));
  5459. http (sprintf ('<%V> ] ;', res), _env);
  5460. }
  5461. }
  5462. else
  5463. {
  5464. DB.DBA.RDF_LONG_TO_TTL (_val, _env);
  5465. http (sprintf (' ] ;'), _env);
  5466. }
  5467. end_of_binding: ;
  5468. }
  5469. http ('\n ] ;', _env);
  5470. }
  5471. ;
  5472. create function DB.DBA.RDF_FORMAT_RESULT_SET_AS_TTL_FIN (inout _env any) returns long varchar
  5473. {
  5474. if (185 <> __tag(_env))
  5475. DB.DBA.RDF_FORMAT_RESULT_SET_AS_TTL_INIT (_env);
  5476. http ('\n ] .', _env);
  5477. return string_output_string (_env);
  5478. }
  5479. ;
  5480. create aggregate DB.DBA.RDF_FORMAT_RESULT_SET_AS_TTL (in colvalues any, in colnames any) returns long varchar
  5481. from DB.DBA.RDF_FORMAT_RESULT_SET_AS_TTL_INIT, DB.DBA.RDF_FORMAT_RESULT_SET_AS_TTL_ACC, DB.DBA.RDF_FORMAT_RESULT_SET_AS_TTL_FIN
  5482. order
  5483. ;
  5484. create procedure DB.DBA.RDF_FORMAT_RESULT_SET_AS_NT_INIT (inout _env any)
  5485. {
  5486. _env := vector (0, 0, string_output());
  5487. http ('@prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> .
  5488. @prefix rs: <http://www.w3.org/2005/sparql-results#> .
  5489. @prefix xsd: <http://www.w3.org/2001/XMLSchema#> .
  5490. _:_ <http://www.w3.org/1999/02/22-rdf-syntax-ns#type> <http://www.w3.org/2005/sparql-results#results> .\n', _env[2]);
  5491. }
  5492. ;
  5493. create procedure DB.DBA.RDF_FORMAT_RESULT_SET_AS_NT_ACC (inout _env any, inout colvalues any, inout colnames any)
  5494. {
  5495. declare col_ctr, col_count integer;
  5496. declare rowid varchar;
  5497. declare blank_ids any;
  5498. if (__tag of vector <> __tag(_env))
  5499. DB.DBA.RDF_FORMAT_RESULT_SET_AS_NT_INIT (_env);
  5500. if (isinteger (_env[1]))
  5501. {
  5502. declare col_buf any;
  5503. col_count := length (colnames);
  5504. if (185 <> __tag(_env))
  5505. DB.DBA.RDF_FORMAT_RESULT_SET_AS_NT_INIT (_env);
  5506. col_buf := make_array (col_count * 7, 'any');
  5507. for (col_ctr := 0; col_ctr < col_count; col_ctr := col_ctr + 1)
  5508. col_buf [col_ctr * 7] := colnames[col_ctr];
  5509. _env[1] := col_buf;
  5510. }
  5511. sparql_rset_nt_write_row (0, _env, colvalues);
  5512. }
  5513. ;
  5514. create function DB.DBA.RDF_FORMAT_RESULT_SET_AS_NT_FIN (inout _env any) returns long varchar
  5515. {
  5516. if (__tag of vector <> __tag(_env))
  5517. DB.DBA.RDF_FORMAT_RESULT_SET_AS_NT_INIT (_env);
  5518. return string_output_string (_env[2]);
  5519. }
  5520. ;
  5521. create aggregate DB.DBA.RDF_FORMAT_RESULT_SET_AS_NT (in colvalues any, in colnames any) returns long varchar
  5522. from DB.DBA.RDF_FORMAT_RESULT_SET_AS_NT_INIT, DB.DBA.RDF_FORMAT_RESULT_SET_AS_NT_ACC, DB.DBA.RDF_FORMAT_RESULT_SET_AS_NT_FIN
  5523. order
  5524. ;
  5525. create procedure DB.DBA.RDF_FORMAT_RESULT_SET_AS_RDF_XML_INIT (inout _env any)
  5526. {
  5527. _env := string_output();
  5528. http ('<rdf:RDF
  5529. xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
  5530. xmlns:rs="http://www.w3.org/2005/sparql-results#"
  5531. xmlns:xsd="http://www.w3.org/2001/XMLSchema#" >
  5532. <rs:results rdf:nodeID="rset">', _env);
  5533. }
  5534. ;
  5535. create procedure DB.DBA.RDF_FORMAT_RESULT_SET_AS_RDF_XML_ACC (inout _env any, inout colvalues any, inout colnames any)
  5536. {
  5537. -- dbg_obj_princ ('DB.DBA.RDF_FORMAT_RESULT_SET_AS_RDF_XML_ACC (..., ', colvalues, colnames, ')');
  5538. declare sol_id varchar;
  5539. declare col_ctr, col_count integer;
  5540. declare blank_ids any;
  5541. if (185 <> __tag(_env))
  5542. DB.DBA.RDF_FORMAT_RESULT_SET_AS_RDF_XML_INIT (_env);
  5543. sol_id := cast (length (_env) as varchar);
  5544. http ('\n <rs:result rdf:nodeID="sol' || sol_id || '">', _env);
  5545. col_count := length (colnames);
  5546. for (col_ctr := 0; col_ctr < col_count; col_ctr := col_ctr + 1)
  5547. {
  5548. declare _name varchar;
  5549. declare _val any;
  5550. _name := colnames[col_ctr];
  5551. _val := colvalues[col_ctr];
  5552. if (_val is null)
  5553. goto end_of_binding;
  5554. http ('\n <rs:binding rdf:nodeID="sol' || sol_id || '-' || cast (col_ctr as varchar) || '" rs:name="', _env);
  5555. http_value (colnames[col_ctr], 0, _env);
  5556. http ('"><rs:value', _env);
  5557. if (isiri_id (_val))
  5558. {
  5559. if (_val >= min_bnode_iri_id ())
  5560. {
  5561. http (sprintf (' rdf:nodeID="b%d"/></rs:binding>', iri_id_num (_val)), _env);
  5562. }
  5563. else
  5564. {
  5565. declare res varchar;
  5566. res := id_to_iri (_val);
  5567. -- res := coalesce ((select RU_QNAME from DB.DBA.RDF_URL where RU_IID = _val));
  5568. if (res is null)
  5569. res := sprintf ('bad://%d', iri_id_num (_val));
  5570. http (sprintf (' rdf:resource="%V"/></rs:binding>', res), _env);
  5571. }
  5572. }
  5573. else
  5574. {
  5575. declare lang, dt varchar;
  5576. lang := DB.DBA.RDF_LANGUAGE_OF_LONG (_val, null);
  5577. dt := DB.DBA.RDF_DATATYPE_IRI_OF_LONG (_val, null);
  5578. if (lang is not null)
  5579. {
  5580. if (dt is not null)
  5581. http (sprintf (' xml:lang="%V" rdf:datatype="%V">',
  5582. cast (lang as varchar), cast (dt as varchar)), _env);
  5583. else
  5584. http (sprintf (' xml:lang="%V">',
  5585. cast (lang as varchar)), _env);
  5586. }
  5587. else
  5588. {
  5589. if (dt is not null)
  5590. http (sprintf (' rdf:datatype="%V">',
  5591. cast (dt as varchar)), _env);
  5592. else
  5593. http (sprintf ('>'), _env);
  5594. }
  5595. http_value (__rdf_strsqlval (_val), 0, _env);
  5596. http ('</rs:value></rs:binding>', _env);
  5597. }
  5598. end_of_binding: ;
  5599. }
  5600. http ('\n </rs:result>', _env);
  5601. }
  5602. ;
  5603. create function DB.DBA.RDF_FORMAT_RESULT_SET_AS_RDF_XML_FIN (inout _env any) returns long varchar
  5604. {
  5605. if (185 <> __tag(_env))
  5606. DB.DBA.RDF_FORMAT_RESULT_SET_AS_RDF_XML_INIT (_env);
  5607. http ('\n </rs:results>\n</rdf:RDF>', _env);
  5608. return string_output_string (_env);
  5609. }
  5610. ;
  5611. create aggregate DB.DBA.RDF_FORMAT_RESULT_SET_AS_RDF_XML (in colvalues any, in colnames any) returns long varchar
  5612. from DB.DBA.RDF_FORMAT_RESULT_SET_AS_RDF_XML_INIT, DB.DBA.RDF_FORMAT_RESULT_SET_AS_RDF_XML_ACC, DB.DBA.RDF_FORMAT_RESULT_SET_AS_RDF_XML_FIN
  5613. order
  5614. ;
  5615. create procedure DB.DBA.RDF_FORMAT_RESULT_SET_AS_JSON_INIT (inout _env any)
  5616. {
  5617. _env := 0;
  5618. }
  5619. ;
  5620. create procedure DB.DBA.RDF_FORMAT_RESULT_SET_AS_JSON_ACC (inout _env any, inout colvalues any, inout colnames any)
  5621. {
  5622. declare sol_id varchar;
  5623. declare col_ctr, col_count, need_comma integer;
  5624. declare blank_ids any;
  5625. col_count := length (colnames);
  5626. if (185 <> __tag(_env))
  5627. {
  5628. _env := string_output ();
  5629. http ('\n{ "head": { "link": [], "vars": [', _env);
  5630. for (col_ctr := 0; col_ctr < col_count; col_ctr := col_ctr + 1)
  5631. {
  5632. if (col_ctr > 0)
  5633. http(', "', _env);
  5634. else
  5635. http('"', _env);
  5636. http_escape (colnames[col_ctr], 11, _env, 0, 1);
  5637. http('"', _env);
  5638. }
  5639. http ('] },\n "results": { "distinct": false, "ordered": true, "bindings": [\n {', _env);
  5640. }
  5641. else
  5642. http(',\n {', _env);
  5643. need_comma := 0;
  5644. for (col_ctr := 0; col_ctr < col_count; col_ctr := col_ctr + 1)
  5645. {
  5646. declare val any;
  5647. val := colvalues[col_ctr];
  5648. if (val is null)
  5649. goto end_of_val_print; -- see below
  5650. if (need_comma)
  5651. http('\t,', _env);
  5652. else
  5653. need_comma := 1;
  5654. DB.DBA.SPARQL_RESULTS_JSON_WRITE_BINDING (_env, colnames[col_ctr], val);
  5655. end_of_val_print: ;
  5656. }
  5657. http('}', _env);
  5658. }
  5659. ;
  5660. create function DB.DBA.RDF_FORMAT_RESULT_SET_AS_JSON_FIN (inout _env any) returns long varchar
  5661. {
  5662. if (185 <> __tag(_env))
  5663. {
  5664. _env := string_output ();
  5665. http ('\n{ "head": { "link": [], "vars": [] },\n "results": { "distinct": false, "ordered": true, "bindings": [', _env);
  5666. }
  5667. http (' ] } }', _env);
  5668. return string_output_string (_env);
  5669. }
  5670. ;
  5671. create aggregate DB.DBA.RDF_FORMAT_RESULT_SET_AS_JSON (in colvalues any, in colnames any) returns long varchar
  5672. from DB.DBA.RDF_FORMAT_RESULT_SET_AS_JSON_INIT, DB.DBA.RDF_FORMAT_RESULT_SET_AS_JSON_ACC, DB.DBA.RDF_FORMAT_RESULT_SET_AS_JSON_FIN
  5673. order
  5674. ;
  5675. create procedure DB.DBA.RDF_FORMAT_RESULT_SET_AS_CSV_INIT (inout _env any)
  5676. {
  5677. _env := 0;
  5678. }
  5679. ;
  5680. create procedure DB.DBA.SPARQL_RESULTS_CSV_WRITE_VALUE (inout _env any, in val any)
  5681. {
  5682. declare t integer;
  5683. t := __tag (val);
  5684. if (t = __tag of rdf_box)
  5685. {
  5686. val := rdf_box_data (val);
  5687. t := __tag (val);
  5688. }
  5689. if (t in (__tag of integer, __tag of numeric, __tag of double precision, __tag of float, __tag of date, __tag of time, __tag of datetime))
  5690. {
  5691. http_value (val, 0, _env);
  5692. return;
  5693. }
  5694. if (t = __tag of IRI_ID)
  5695. val := id_to_iri (val);
  5696. http ('"', _env);
  5697. http (replace (cast (val as varchar), '"', '""'), _env);
  5698. http ('"', _env);
  5699. }
  5700. ;
  5701. create procedure DB.DBA.RDF_FORMAT_RESULT_SET_AS_CSV_ACC (inout _env any, inout colvalues any, inout colnames any)
  5702. {
  5703. declare sol_id varchar;
  5704. declare col_ctr, col_count integer;
  5705. declare blank_ids any;
  5706. col_count := length (colnames);
  5707. if (185 <> __tag(_env))
  5708. {
  5709. _env := string_output ();
  5710. for (col_ctr := 0; col_ctr < col_count; col_ctr := col_ctr + 1)
  5711. {
  5712. if (col_ctr > 0)
  5713. http(',', _env);
  5714. DB.DBA.SPARQL_RESULTS_CSV_WRITE_VALUE (_env, colnames[col_ctr]);
  5715. }
  5716. http ('\n', _env);
  5717. }
  5718. for (col_ctr := 0; col_ctr < col_count; col_ctr := col_ctr + 1)
  5719. {
  5720. declare val any;
  5721. val := colvalues[col_ctr];
  5722. if (col_ctr > 0)
  5723. http(',', _env);
  5724. if (val is not null)
  5725. DB.DBA.SPARQL_RESULTS_CSV_WRITE_VALUE (_env, val);
  5726. }
  5727. http('\n', _env);
  5728. }
  5729. ;
  5730. create function DB.DBA.RDF_FORMAT_RESULT_SET_AS_CSV_FIN (inout _env any) returns long varchar
  5731. {
  5732. if (185 <> __tag(_env))
  5733. return '';
  5734. return string_output_string (_env);
  5735. }
  5736. ;
  5737. create aggregate DB.DBA.RDF_FORMAT_RESULT_SET_AS_CSV (in colvalues any, in colnames any) returns long varchar
  5738. from DB.DBA.RDF_FORMAT_RESULT_SET_AS_CSV_INIT, DB.DBA.RDF_FORMAT_RESULT_SET_AS_CSV_ACC, DB.DBA.RDF_FORMAT_RESULT_SET_AS_CSV_FIN
  5739. order
  5740. ;
  5741. create procedure DB.DBA.RDF_FORMAT_RESULT_SET_AS_TSV_ACC (inout _env any, inout colvalues any, inout colnames any)
  5742. {
  5743. declare sol_id varchar;
  5744. declare col_ctr, col_count integer;
  5745. declare blank_ids any;
  5746. col_count := length (colnames);
  5747. if (185 <> __tag(_env))
  5748. {
  5749. _env := string_output ();
  5750. for (col_ctr := 0; col_ctr < col_count; col_ctr := col_ctr + 1)
  5751. {
  5752. if (col_ctr > 0)
  5753. http('\t', _env);
  5754. DB.DBA.SPARQL_RESULTS_CSV_WRITE_VALUE (_env, colnames[col_ctr]);
  5755. }
  5756. http ('\n', _env);
  5757. }
  5758. for (col_ctr := 0; col_ctr < col_count; col_ctr := col_ctr + 1)
  5759. {
  5760. declare val any;
  5761. val := colvalues[col_ctr];
  5762. if (col_ctr > 0)
  5763. http('\t', _env);
  5764. if (val is not null)
  5765. DB.DBA.SPARQL_RESULTS_CSV_WRITE_VALUE (_env, val);
  5766. }
  5767. http('\n', _env);
  5768. }
  5769. ;
  5770. create aggregate DB.DBA.RDF_FORMAT_RESULT_SET_AS_TSV (in colvalues any, in colnames any) returns long varchar
  5771. from DB.DBA.RDF_FORMAT_RESULT_SET_AS_CSV_INIT, DB.DBA.RDF_FORMAT_RESULT_SET_AS_TSV_ACC, DB.DBA.RDF_FORMAT_RESULT_SET_AS_CSV_FIN
  5772. order
  5773. ;
  5774. create procedure DB.DBA.RDF_FORMAT_RESULT_SET_AS_CXML_INIT (inout _env any)
  5775. {
  5776. _env := 0;
  5777. }
  5778. ;
  5779. create procedure DB.DBA.RDF_FORMAT_RESULT_SET_AS_CXML_ACC (inout _env any, inout colvalues any, inout colnames any)
  5780. {
  5781. declare agg, colvalues_copy any;
  5782. colvalues_copy := colvalues;
  5783. if (isinteger (_env))
  5784. {
  5785. vectorbld_init (agg);
  5786. _env := vector (0, colnames);
  5787. }
  5788. else
  5789. {
  5790. agg := aref_set_0 (_env, 0);
  5791. }
  5792. vectorbld_acc (agg, colvalues_copy);
  5793. aset_zap_arg (_env, 0, agg);
  5794. }
  5795. ;
  5796. create function DB.DBA.RDF_FORMAT_RESULT_SET_AS_CXML_FIN (inout _env any) returns long varchar
  5797. {
  5798. declare ses, metas, rset any;
  5799. declare accept varchar;
  5800. declare add_http_headers integer;
  5801. ses := string_output ();
  5802. if (isinteger (_env))
  5803. {
  5804. metas := vector (vector (vector ('s')), 1);
  5805. rset := vector ();
  5806. DB.DBA.SPARQL_RESULTS_CXML_WRITE (ses, metas, rset, accept, add_http_headers);
  5807. }
  5808. else
  5809. {
  5810. declare cols any;
  5811. declare colctr, colcount integer;
  5812. rset := aref_set_0 (_env, 0);
  5813. vectorbld_final (rset);
  5814. cols := aref_set_0 (_env, 1);
  5815. colcount := length (cols);
  5816. for (colctr := 0; colctr < colcount; colctr := colctr + 1) cols[colctr] := vector (cols[colctr]);
  5817. metas := vector (cols, vector ());
  5818. DB.DBA.SPARQL_RESULTS_CXML_WRITE (ses, metas, rset, accept, add_http_headers);
  5819. }
  5820. return string_output_string (ses);
  5821. }
  5822. ;
  5823. create aggregate DB.DBA.RDF_FORMAT_RESULT_SET_AS_CXML (in colvalues any, in colnames any) returns long varchar
  5824. from DB.DBA.RDF_FORMAT_RESULT_SET_AS_CXML_INIT, DB.DBA.RDF_FORMAT_RESULT_SET_AS_CXML_ACC, DB.DBA.RDF_FORMAT_RESULT_SET_AS_CXML_FIN
  5825. order
  5826. ;
  5827. create procedure DB.DBA.RDF_FORMAT_RESULT_SET_AS_BINDINGS_INIT (inout _env any)
  5828. {
  5829. _env := vector (0, 0, string_output());
  5830. }
  5831. ;
  5832. create procedure DB.DBA.RDF_FORMAT_RESULT_SET_AS_BINDINGS_ACC (inout _env any, inout colvalues any, inout colnames any)
  5833. {
  5834. declare col_ctr, col_count integer;
  5835. declare ses any;
  5836. declare rowid varchar;
  5837. declare blank_ids any;
  5838. if (__tag of vector <> __tag(_env))
  5839. DB.DBA.RDF_FORMAT_RESULT_SET_AS_BINDINGS_INIT (_env);
  5840. if (isinteger (_env[1]))
  5841. {
  5842. if (185 <> __tag(_env))
  5843. DB.DBA.RDF_FORMAT_RESULT_SET_AS_BINDINGS_INIT (_env);
  5844. _env[1] := colnames;
  5845. ses := aref_set_0 (_env, 2);
  5846. http ('BINDINGS', ses);
  5847. foreach (varchar colname in colnames) do { http (' ?' || colname, ses); }
  5848. http (' {', ses);
  5849. }
  5850. else
  5851. ses := aref_set_0 (_env, 2);
  5852. http ('\n (', ses);
  5853. foreach (any val in colvalues) do
  5854. {
  5855. if (val is null)
  5856. http ('\tUNDEF', ses);
  5857. else
  5858. {
  5859. http ('\t', ses);
  5860. http_nt_object (val, ses);
  5861. }
  5862. }
  5863. http ('\t)', ses);
  5864. aset_zap_arg (_env, 2, ses);
  5865. }
  5866. ;
  5867. create function DB.DBA.RDF_FORMAT_RESULT_SET_AS_BINDINGS_FIN (inout _env any) returns long varchar
  5868. {
  5869. declare ses any;
  5870. if (__tag of vector <> __tag(_env))
  5871. DB.DBA.RDF_FORMAT_RESULT_SET_AS_BINDINGS_INIT (_env);
  5872. if (isinteger (_env[1]))
  5873. return 'BINDINGS ?EmptyResultSetStub { }';
  5874. ses := aref_set_0 (_env, 2);
  5875. if (not isinteger (_env[1]))
  5876. http ('\n}', ses);
  5877. return string_output_string (ses);
  5878. }
  5879. ;
  5880. create aggregate DB.DBA.RDF_FORMAT_RESULT_SET_AS_BINDINGS (in colvalues any, in colnames any) returns long varchar
  5881. from DB.DBA.RDF_FORMAT_RESULT_SET_AS_BINDINGS_INIT, DB.DBA.RDF_FORMAT_RESULT_SET_AS_BINDINGS_ACC, DB.DBA.RDF_FORMAT_RESULT_SET_AS_BINDINGS_FIN
  5882. order
  5883. ;
  5884. create function DB.DBA.RDF_FORMAT_TRIPLE_DICT_AS_TTL (inout triples_dict any) returns long varchar
  5885. {
  5886. declare triples, ses any;
  5887. ses := string_output ();
  5888. if (214 <> __tag (triples_dict))
  5889. {
  5890. triples := vector ();
  5891. }
  5892. else
  5893. triples := dict_list_keys (triples_dict, 1);
  5894. DB.DBA.RDF_TRIPLES_TO_TTL (triples, ses);
  5895. return ses;
  5896. }
  5897. ;
  5898. create function DB.DBA.RDF_FORMAT_TRIPLE_DICT_AS_NICE_TTL (inout triples_dict any) returns long varchar
  5899. {
  5900. declare triples, ses any;
  5901. if (2666 < dict_size (triples_dict)) -- The "nice" algorithm is too slow to be applied to large outputs. There's also a limit for 8000 namespace prefixes.
  5902. return DB.DBA.RDF_FORMAT_TRIPLE_DICT_AS_TTL (triples_dict);
  5903. ses := string_output ();
  5904. if (214 <> __tag (triples_dict))
  5905. triples := vector ();
  5906. else
  5907. triples := dict_list_keys (triples_dict, 1);
  5908. DB.DBA.RDF_TRIPLES_TO_NICE_TTL (triples, ses);
  5909. return ses;
  5910. }
  5911. ;
  5912. create procedure DB.DBA.RDF_TRIPLES_TO_NICE_TTL (inout triples any, inout ses any)
  5913. {
  5914. declare tcount integer;
  5915. tcount := length (triples);
  5916. if (0 = tcount)
  5917. {
  5918. http ('# Empty Turtle\n', ses);
  5919. return;
  5920. }
  5921. if (2666 < tcount) -- The "nice" algorithm is too slow to be applied to large outputs. There's also a limit for 8000 namespace prefixes.
  5922. {
  5923. DB.DBA.RDF_TRIPLES_TO_TTL (triples, ses);
  5924. return;
  5925. }
  5926. DB.DBA.RDF_TRIPLES_TO_NICE_TTL_IMPL (triples, 0, ses);
  5927. }
  5928. ;
  5929. create procedure DB.DBA.RDF_TRIPLES_TO_NICE_TTL_IMPL (inout triples any, in env_flags integer, inout ses any)
  5930. {
  5931. declare env, printed_triples_mask any;
  5932. declare rdf_first_iid, rdf_rest_iid, rdf_nil_iid IRI_ID;
  5933. declare bnode_usage_dict any;
  5934. -- Keys of bnode_usage_dict are IRI_IDs of all blank nodes of the \c triples,
  5935. -- values are vectors of five items
  5936. -- #0: NULL if key bnode is not used as object OR IRI_ID of single subject such that the key bnode is object OR an empty string UNAME if the key bnode is used as object many times or makes a loop made of anonymous bnodes.
  5937. -- #1: NULL if key bnode does not have rdf:first property OR an integer index of that rdf:first triple in \c triples OR an empty string UNAME if the key bnode has many values of rdf:first or non-list predicates.
  5938. -- #2: NULL if key bnode does not have rdf:rest property OR an integer index of that rdf:rest triple in \c triples OR an empty string UNAME if the key bnode has many values of rdf:rest or non-list predicates.
  5939. -- #3: NULL if not in the list or not yet checked OR an integer that indicates the length of proper tail of the list OR an empty string UNAME if the list is ended up with cycle or something weird.
  5940. -- #4: Index of first triple where the bnode appears as a subject, NULL if there are no such.
  5941. declare tail_to_head_dict any;
  5942. -- Keys of tail_to_head_dict are last bnodes of lists, values are first bnodes of (valid parts of) lists OR empty string UNAME for last bnodes that were later proven to be inappropriate.
  5943. declare all_bnodes any;
  5944. declare tcount, tctr, bnode_ctr integer;
  5945. declare tail_bnode, head_bnode IRI_ID;
  5946. declare prefixes_are_printed integer;
  5947. declare prev_s, prev_p varchar;
  5948. tcount := length (triples);
  5949. rowvector_obj_sort (triples, 2, 1);
  5950. rowvector_subj_sort (triples, 1, 1);
  5951. rowvector_subj_sort (triples, 0, 1);
  5952. env := DB.DBA.RDF_TRIPLES_TO_TTL_ENV (tcount, env_flags, 0, ses);
  5953. rdf_first_iid := iri_to_id ('http://www.w3.org/1999/02/22-rdf-syntax-ns#first');
  5954. rdf_rest_iid := iri_to_id ('http://www.w3.org/1999/02/22-rdf-syntax-ns#rest');
  5955. rdf_nil_iid := iri_to_id ('http://www.w3.org/1999/02/22-rdf-syntax-ns#nil');
  5956. printed_triples_mask := space (tcount);
  5957. -- First of all we gather info into bnode_usage_dict, except items #3 of values
  5958. bnode_usage_dict := dict_new (13 + (tcount / 100));
  5959. tail_to_head_dict := dict_new (13 + (tcount / 1000));
  5960. for (tctr := 0; tctr < tcount; tctr := tctr + 1)
  5961. {
  5962. declare s_iid, o_iid IRI_ID;
  5963. -- dbg_obj_princ ('Gathering ', tctr, '/', tcount, triples[tctr][0], triples[tctr][1], triples[tctr][2]);
  5964. if (triples[tctr][0] is null or triples[tctr][1] is null or triples[tctr][2] is null)
  5965. {
  5966. printed_triples_mask[tctr] := ascii ('N');
  5967. goto triple_skipped;
  5968. }
  5969. s_iid := iri_to_id_nosignal (triples[tctr][0]);
  5970. o_iid := iri_to_id_nosignal (triples[tctr][2]);
  5971. if (is_bnode_iri_id (s_iid))
  5972. {
  5973. declare p_iid IRI_ID;
  5974. declare u any;
  5975. p_iid := iri_to_id_nosignal (triples[tctr][1]);
  5976. u := dict_get (bnode_usage_dict, s_iid, null);
  5977. if (u is null)
  5978. u := vector (null, null, null, null, tctr);
  5979. else if (u[4] is null)
  5980. u[4] := tctr;
  5981. if (rdf_first_iid = p_iid)
  5982. {
  5983. if (u[1] is null)
  5984. {
  5985. u[1] := tctr;
  5986. goto s_iid_done;
  5987. }
  5988. else
  5989. goto bad_for_list;
  5990. }
  5991. else if (rdf_rest_iid = p_iid)
  5992. {
  5993. if (u[2] is not null)
  5994. goto bad_for_list;
  5995. else if (rdf_nil_iid = o_iid)
  5996. {
  5997. dict_put (tail_to_head_dict, s_iid, s_iid);
  5998. u[2] := tctr;
  5999. goto s_iid_done;
  6000. }
  6001. else if (is_bnode_iri_id (o_iid))
  6002. {
  6003. u[2] := tctr;
  6004. goto s_iid_done;
  6005. }
  6006. else
  6007. goto bad_for_list;
  6008. }
  6009. bad_for_list:
  6010. u[1] := UNAME'';
  6011. u[2] := UNAME'';
  6012. if (dict_get (tail_to_head_dict, s_iid, null) is not null)
  6013. dict_put (tail_to_head_dict, s_iid, UNAME'');
  6014. s_iid_done:
  6015. dict_put (bnode_usage_dict, s_iid, u);
  6016. }
  6017. if (is_bnode_iri_id (o_iid))
  6018. {
  6019. declare u any;
  6020. u := dict_get (bnode_usage_dict, o_iid, null);
  6021. if (u is null)
  6022. dict_put (bnode_usage_dict, o_iid, vector (s_iid, null, null, null, null));
  6023. else
  6024. {
  6025. if (u[0] is null)
  6026. u[0] := s_iid;
  6027. else
  6028. u[0] := UNAME'';
  6029. dict_put (bnode_usage_dict, o_iid, u);
  6030. }
  6031. }
  6032. triple_skipped: ;
  6033. }
  6034. -- Now it's possible to check for loops of anonymous cycles
  6035. all_bnodes := dict_list_keys (bnode_usage_dict, 0);
  6036. gvector_sort (all_bnodes, 1, 0, 1);
  6037. foreach (IRI_ID bn_iid in all_bnodes) do
  6038. {
  6039. declare top_bn_iid IRI_ID;
  6040. top_bn_iid := bn_iid;
  6041. while (is_bnode_iri_id (top_bn_iid))
  6042. {
  6043. declare u any;
  6044. u := dict_get (bnode_usage_dict, top_bn_iid, null);
  6045. if (u[0] = bn_iid)
  6046. {
  6047. u := dict_get (bnode_usage_dict, bn_iid, null);
  6048. u[0] := UNAME'';
  6049. dict_put (bnode_usage_dict, bn_iid, u);
  6050. goto bn_iid_done;
  6051. }
  6052. top_bn_iid := u[0];
  6053. }
  6054. bn_iid_done: ;
  6055. }
  6056. -- Now it is possible to check list nodes
  6057. dict_iter_rewind (tail_to_head_dict);
  6058. while (dict_iter_next (tail_to_head_dict, tail_bnode, head_bnode))
  6059. {
  6060. declare last_good_head_bnode IRI_ID;
  6061. declare len_ctr integer;
  6062. len_ctr := 0;
  6063. last_good_head_bnode := head_bnode;
  6064. -- dbg_obj_princ ('Loop from ', tail_bnode, ' to ', head_bnode);
  6065. while (is_bnode_iri_id (head_bnode))
  6066. {
  6067. declare u any;
  6068. u := dict_get (bnode_usage_dict, head_bnode, null);
  6069. -- dbg_obj_princ (head_bnode, ' has ', u);
  6070. if (isinteger (u[1]) and isinteger (u[2]) and u[3] is null and (u[0] is null or isiri_id (u[0])))
  6071. {
  6072. -- dbg_obj_princ ('Reached ', last_good_head_bnode);
  6073. last_good_head_bnode := head_bnode;
  6074. u[3] := len_ctr;
  6075. len_ctr := len_ctr + 1;
  6076. dict_put (bnode_usage_dict, head_bnode, u);
  6077. head_bnode := u[0];
  6078. }
  6079. else
  6080. {
  6081. u[3] := UNAME'';
  6082. dict_put (bnode_usage_dict, head_bnode, u);
  6083. head_bnode := null;
  6084. }
  6085. }
  6086. }
  6087. DB.DBA.RDF_TRIPLES_BATCH_COMPLETE (triples);
  6088. -- Start the actual serialization
  6089. prefixes_are_printed := 0;
  6090. for (tctr := 0; tctr < tcount; tctr := tctr + 1)
  6091. prefixes_are_printed := prefixes_are_printed + http_ttl_prefixes (env, triples[tctr][0], triples[tctr][1], triples[tctr][2], ses);
  6092. if (prefixes_are_printed)
  6093. http ('\n', ses);
  6094. prev_s := '';
  6095. prev_p := '';
  6096. -- dbg_obj_princ ('printed_triples_mask="', printed_triples_mask, '"');
  6097. for (tctr := 0; tctr < tcount; tctr := tctr + 1)
  6098. {
  6099. declare s_iid, o_iid IRI_ID;
  6100. declare s, p, o any;
  6101. if (ascii (' ') <> printed_triples_mask[tctr])
  6102. goto done_triple;
  6103. -- dbg_obj_princ ('Printing ', tctr, '/', tcount, triples[tctr][0], triples[tctr][1], triples[tctr][2]);
  6104. s := triples[tctr][0];
  6105. p := triples[tctr][1];
  6106. o := triples[tctr][2];
  6107. s_iid := iri_to_id_nosignal (s);
  6108. o_iid := iri_to_id_nosignal (o);
  6109. if (is_bnode_iri_id (s_iid))
  6110. {
  6111. declare u any;
  6112. u := dict_get (bnode_usage_dict, s_iid, null);
  6113. if (isiri_id (u[0]))
  6114. goto done_triple;
  6115. }
  6116. if (s <> prev_s)
  6117. {
  6118. if (prev_s <> '')
  6119. http (' .\n', ses);
  6120. http_ttl_value (env, s, 0, ses);
  6121. http ('\n\t', ses);
  6122. prev_s := s;
  6123. prev_p := '';
  6124. }
  6125. if (p <> prev_p)
  6126. {
  6127. if (prev_p <> '')
  6128. http (' ;\n\t', ses);
  6129. http_ttl_value (env, p, 1, ses);
  6130. http ('\t', ses);
  6131. prev_p := p;
  6132. }
  6133. else
  6134. http (' , ', ses);
  6135. printed_triples_mask[tctr] := ascii ('p');
  6136. if (is_bnode_iri_id (o_iid))
  6137. DB.DBA.RDF_TRIPLE_OBJ_BNODE_TO_NICE_TTL (triples, printed_triples_mask, o_iid, env, bnode_usage_dict, 2, ses);
  6138. else
  6139. http_ttl_value (env, o, 2, ses);
  6140. -- dbg_obj_princ ('printed_triples_mask="', printed_triples_mask, '"');
  6141. done_triple: ;
  6142. }
  6143. done_data:
  6144. if (prev_s is not null)
  6145. http (' .\n', ses);
  6146. else
  6147. http ('# Empty Turtle (no valid data to print)\n', ses);
  6148. }
  6149. ;
  6150. create procedure DB.DBA.RDF_TRIPLE_OBJ_BNODE_TO_NICE_TTL (inout triples any, inout printed_triples_mask any, in s_bnode_iid IRI_ID, inout env any, inout bnode_usage_dict any, in depth integer, inout ses any)
  6151. {
  6152. declare u, subj, prev_p any;
  6153. declare tctr, tcount integer;
  6154. u := dict_get (bnode_usage_dict, s_bnode_iid, null);
  6155. if (u[0] is not null and not isiri_id (u[0]))
  6156. {
  6157. -- dbg_obj_princ ('Printing plain bnode ', s_bnode_iid, ' u=', u);
  6158. http_ttl_value (env, s_bnode_iid, 2, ses);
  6159. return;
  6160. }
  6161. if (isinteger (u[3]))
  6162. {
  6163. -- dbg_obj_princ ('Printing list from ', s_bnode_iid, ' u=', u);
  6164. http ('(', ses);
  6165. while (is_bnode_iri_id (s_bnode_iid))
  6166. {
  6167. declare itm any;
  6168. declare itm_iid IRI_ID;
  6169. itm := triples[u[1]][2];
  6170. itm_iid := iri_to_id_nosignal (itm);
  6171. if (ascii (' ') <> printed_triples_mask[u[1]]) signal ('OBLOM', 'Corrupted CAR in list');
  6172. if (ascii (' ') <> printed_triples_mask[u[2]]) signal ('OBLOM', 'Corrupted CDR in list');
  6173. printed_triples_mask[u[1]] := ascii ('A');
  6174. http (' ', ses);
  6175. if (is_bnode_iri_id (itm_iid))
  6176. DB.DBA.RDF_TRIPLE_OBJ_BNODE_TO_NICE_TTL (triples, printed_triples_mask, itm_iid, env, bnode_usage_dict, depth + 1, ses);
  6177. else
  6178. http_ttl_value (env, itm, 2, ses);
  6179. printed_triples_mask[u[2]] := ascii ('D');
  6180. s_bnode_iid := iri_to_id_nosignal (triples[u[2]][2]);
  6181. u := dict_get (bnode_usage_dict, s_bnode_iid, null);
  6182. -- dbg_obj_princ ('next node ', s_bnode_iid, ' u=', u);
  6183. }
  6184. http (' )', ses);
  6185. return;
  6186. }
  6187. tctr := u[4];
  6188. if (tctr is null)
  6189. {
  6190. -- dbg_obj_princ ('Printing empty bnode ', s_bnode_iid, ' u=', u);
  6191. http ('[ ]', ses);
  6192. return;
  6193. }
  6194. tcount := length (triples);
  6195. subj := triples[tctr][0];
  6196. prev_p := '';
  6197. http ('[\t', ses);
  6198. -- dbg_obj_princ ('Printing bnode triples for ', s_bnode_iid, ' starting from ', tctr, '/', tcount, ' u=', u);
  6199. while (1=1)
  6200. {
  6201. declare o_iid IRI_ID;
  6202. declare p, o any;
  6203. if (ascii (' ') <> printed_triples_mask[tctr])
  6204. goto done_triple;
  6205. p := triples[tctr][1];
  6206. o := triples[tctr][2];
  6207. o_iid := iri_to_id_nosignal (o);
  6208. if (p <> prev_p)
  6209. {
  6210. if (prev_p <> '')
  6211. http (' ;\n' || repeat ('\t', depth+2), ses);
  6212. http_ttl_value (env, p, 2, ses);
  6213. http ('\t', ses);
  6214. prev_p := p;
  6215. }
  6216. else
  6217. http (' , ', ses);
  6218. printed_triples_mask[tctr] := ascii ('[');
  6219. if (is_bnode_iri_id (o_iid))
  6220. DB.DBA.RDF_TRIPLE_OBJ_BNODE_TO_NICE_TTL (triples, printed_triples_mask, o_iid, env, bnode_usage_dict, depth + 2, ses);
  6221. else
  6222. http_ttl_value (env, o, 2, ses);
  6223. done_triple:
  6224. tctr := tctr + 1;
  6225. if (not ((tctr < tcount) and (triples[tctr][0] = subj)))
  6226. {
  6227. http (' ]', ses);
  6228. return;
  6229. }
  6230. }
  6231. }
  6232. ;
  6233. create function DB.DBA.RDF_FORMAT_TRIPLE_DICT_AS_TRIG (inout triples_dict any) returns long varchar
  6234. {
  6235. declare triples, ses any;
  6236. ses := string_output ();
  6237. if (214 <> __tag (triples_dict))
  6238. {
  6239. triples := vector ();
  6240. }
  6241. else
  6242. triples := dict_list_keys (triples_dict, 1);
  6243. DB.DBA.RDF_TRIPLES_TO_TRIG (triples, ses);
  6244. return ses;
  6245. }
  6246. ;
  6247. create function DB.DBA.RDF_FORMAT_TRIPLE_DICT_AS_NT (inout triples_dict any) returns long varchar
  6248. {
  6249. declare triples, ses any;
  6250. ses := string_output ();
  6251. if (214 <> __tag (triples_dict))
  6252. {
  6253. triples := vector ();
  6254. }
  6255. else
  6256. triples := dict_list_keys (triples_dict, 1);
  6257. DB.DBA.RDF_TRIPLES_TO_NT (triples, ses);
  6258. return ses;
  6259. }
  6260. ;
  6261. create function DB.DBA.RDF_FORMAT_TRIPLE_DICT_AS_RDF_XML (inout triples_dict any) returns long varchar
  6262. {
  6263. declare triples, ses any;
  6264. ses := string_output ();
  6265. if (214 <> __tag (triples_dict))
  6266. {
  6267. triples := vector ();
  6268. }
  6269. else
  6270. triples := dict_list_keys (triples_dict, 1);
  6271. DB.DBA.RDF_TRIPLES_TO_RDF_XML_TEXT (triples, 1, ses);
  6272. return ses;
  6273. }
  6274. ;
  6275. create function DB.DBA.RDF_FORMAT_TRIPLE_DICT_AS_TALIS_JSON (inout triples_dict any) returns long varchar
  6276. {
  6277. declare triples, ses any;
  6278. ses := string_output ();
  6279. if (214 <> __tag (triples_dict))
  6280. {
  6281. triples := vector ();
  6282. }
  6283. else
  6284. triples := dict_list_keys (triples_dict, 1);
  6285. DB.DBA.RDF_TRIPLES_TO_TALIS_JSON (triples, ses);
  6286. return ses;
  6287. }
  6288. ;
  6289. create function DB.DBA.RDF_FORMAT_TRIPLE_DICT_AS_JSON_LD (inout triples_dict any) returns long varchar
  6290. {
  6291. declare triples, ses any;
  6292. ses := string_output ();
  6293. if (214 <> __tag (triples_dict))
  6294. {
  6295. triples := vector ();
  6296. }
  6297. else
  6298. triples := dict_list_keys (triples_dict, 1);
  6299. DB.DBA.RDF_TRIPLES_TO_JSON_LD (triples, ses);
  6300. return ses;
  6301. }
  6302. ;
  6303. create function DB.DBA.RDF_FORMAT_TRIPLE_DICT_AS_HTML_UL (inout triples_dict any) returns long varchar
  6304. {
  6305. declare triples, ses any;
  6306. ses := string_output ();
  6307. if (214 <> __tag (triples_dict))
  6308. {
  6309. triples := vector ();
  6310. }
  6311. else
  6312. triples := dict_list_keys (triples_dict, 1);
  6313. DB.DBA.RDF_TRIPLES_TO_HTML_UL (triples, ses);
  6314. return ses;
  6315. }
  6316. ;
  6317. create function DB.DBA.RDF_FORMAT_TRIPLE_DICT_AS_HTML_TR (inout triples_dict any) returns long varchar
  6318. {
  6319. declare triples, ses any;
  6320. ses := string_output ();
  6321. if (214 <> __tag (triples_dict))
  6322. {
  6323. triples := vector ();
  6324. }
  6325. else
  6326. triples := dict_list_keys (triples_dict, 1);
  6327. DB.DBA.RDF_TRIPLES_TO_HTML_TR (triples, ses);
  6328. return ses;
  6329. }
  6330. ;
  6331. create function DB.DBA.RDF_FORMAT_TRIPLE_DICT_AS_HTML_MICRODATA (inout triples_dict any) returns long varchar
  6332. {
  6333. declare triples, ses any;
  6334. ses := string_output ();
  6335. if (214 <> __tag (triples_dict))
  6336. {
  6337. triples := vector ();
  6338. }
  6339. else
  6340. triples := dict_list_keys (triples_dict, 1);
  6341. DB.DBA.RDF_TRIPLES_TO_HTML_MICRODATA (triples, ses);
  6342. return ses;
  6343. }
  6344. ;
  6345. create function DB.DBA.RDF_FORMAT_TRIPLE_DICT_AS_HTML_NICE_MICRODATA (inout triples_dict any) returns long varchar
  6346. {
  6347. declare triples, ses any;
  6348. ses := string_output ();
  6349. if (214 <> __tag (triples_dict))
  6350. {
  6351. triples := vector ();
  6352. }
  6353. else
  6354. triples := dict_list_keys (triples_dict, 1);
  6355. DB.DBA.RDF_TRIPLES_TO_HTML_NICE_MICRODATA (triples, ses);
  6356. return ses;
  6357. }
  6358. ;
  6359. create function DB.DBA.RDF_FORMAT_TRIPLE_DICT_AS_HTML_NICE_TTL (inout triples_dict any) returns long varchar
  6360. {
  6361. declare triples, ses any;
  6362. ses := string_output ();
  6363. if (214 <> __tag (triples_dict))
  6364. triples := vector ();
  6365. else
  6366. triples := dict_list_keys (triples_dict, 1);
  6367. DB.DBA.RDF_TRIPLES_TO_HTML_NICE_TTL (triples, ses);
  6368. return ses;
  6369. }
  6370. ;
  6371. create procedure DB.DBA.RDF_TRIPLES_TO_HTML_NICE_TTL (inout triples any, inout ses any)
  6372. {
  6373. declare tcount integer;
  6374. tcount := length (triples);
  6375. if (0 = tcount)
  6376. {
  6377. http ('# Empty Turtle\n', ses);
  6378. return;
  6379. }
  6380. rowvector_obj_sort (triples, 2, 1);
  6381. rowvector_subj_sort (triples, 1, 1);
  6382. rowvector_subj_sort (triples, 0, 1);
  6383. if (2666 < tcount) -- The "nice" algorithm is too slow to be applied to large outputs. There's also a limit for 8000 namespace prefixes.
  6384. {
  6385. http (sprintf ('# The result consists of %d triples so it is too long to be pretty-printed. The dump below contains that triples without any decoration', tcount), ses);
  6386. http ('<xmp>', ses);
  6387. DB.DBA.RDF_TRIPLES_TO_TTL (triples, ses);
  6388. http ('</xmp>', ses);
  6389. return;
  6390. }
  6391. http ('<pre>', ses);
  6392. DB.DBA.RDF_TRIPLES_TO_NICE_TTL_IMPL (triples, 257, ses);
  6393. http ('</pre>', ses);
  6394. }
  6395. ;
  6396. create function DB.DBA.RDF_FORMAT_TRIPLE_DICT_AS_JSON_MICRODATA (inout triples_dict any) returns long varchar
  6397. {
  6398. declare triples, ses any;
  6399. ses := string_output ();
  6400. if (214 <> __tag (triples_dict))
  6401. {
  6402. triples := vector ();
  6403. }
  6404. else
  6405. triples := dict_list_keys (triples_dict, 1);
  6406. DB.DBA.RDF_TRIPLES_TO_JSON_MICRODATA (triples, ses);
  6407. return ses;
  6408. }
  6409. ;
  6410. create function DB.DBA.RDF_FORMAT_TRIPLE_DICT_AS_CSV (inout triples_dict any) returns long varchar
  6411. {
  6412. declare triples, ses any;
  6413. ses := string_output ();
  6414. if (214 <> __tag (triples_dict))
  6415. {
  6416. triples := vector ();
  6417. }
  6418. else
  6419. triples := dict_list_keys (triples_dict, 1);
  6420. DB.DBA.RDF_TRIPLES_TO_CSV (triples, ses);
  6421. return ses;
  6422. }
  6423. ;
  6424. create function DB.DBA.RDF_FORMAT_TRIPLE_DICT_AS_TSV (inout triples_dict any) returns long varchar
  6425. {
  6426. declare triples, ses any;
  6427. ses := string_output ();
  6428. if (214 <> __tag (triples_dict))
  6429. {
  6430. triples := vector ();
  6431. }
  6432. else
  6433. triples := dict_list_keys (triples_dict, 1);
  6434. DB.DBA.RDF_TRIPLES_TO_TSV (triples, ses);
  6435. return ses;
  6436. }
  6437. ;
  6438. create function DB.DBA.RDF_FORMAT_TRIPLE_DICT_AS_RDFA_XHTML (inout triples_dict any) returns long varchar
  6439. {
  6440. declare triples, ses any;
  6441. ses := string_output ();
  6442. if (214 <> __tag (triples_dict))
  6443. {
  6444. triples := vector ();
  6445. }
  6446. else
  6447. triples := dict_list_keys (triples_dict, 1);
  6448. DB.DBA.RDF_TRIPLES_TO_RDFA_XHTML (triples, ses);
  6449. return ses;
  6450. }
  6451. ;
  6452. create function DB.DBA.RDF_FORMAT_TRIPLE_DICT_AS_CXML (inout triples_dict any) returns long varchar
  6453. {
  6454. declare triples, ses any;
  6455. declare accept varchar;
  6456. declare add_http_headers integer;
  6457. add_http_headers := 0;
  6458. ses := string_output ();
  6459. if (214 <> __tag (triples_dict))
  6460. {
  6461. triples := vector ();
  6462. }
  6463. else
  6464. triples := dict_list_keys (triples_dict, 1);
  6465. DB.DBA.RDF_TRIPLES_TO_CXML (triples, ses, accept, add_http_headers, 0);
  6466. return ses;
  6467. }
  6468. ;
  6469. create function DB.DBA.RDF_FORMAT_TRIPLE_DICT_AS_CXML_QRCODE (inout triples_dict any) returns long varchar
  6470. {
  6471. declare triples, ses any;
  6472. declare accept varchar;
  6473. declare add_http_headers integer;
  6474. add_http_headers := 0;
  6475. ses := string_output ();
  6476. if (214 <> __tag (triples_dict))
  6477. {
  6478. triples := vector ();
  6479. }
  6480. else
  6481. triples := dict_list_keys (triples_dict, 1);
  6482. DB.DBA.RDF_TRIPLES_TO_CXML (triples, ses, accept, add_http_headers, 1);
  6483. return ses;
  6484. }
  6485. ;
  6486. --!AWK PUBLIC
  6487. create procedure DB.DBA.RDF_FORMAT_BOOL_RESULT_AS_XML_INIT (inout _env any)
  6488. {
  6489. _env := 0;
  6490. }
  6491. ;
  6492. --!AWK PUBLIC
  6493. create procedure DB.DBA.RDF_FORMAT_BOOL_RESULT_AS_XML_ACC (inout _env any, in one any array)
  6494. {
  6495. _env := 1;
  6496. }
  6497. ;
  6498. --!AWK PUBLIC
  6499. create function DB.DBA.RDF_FORMAT_BOOL_RESULT_AS_XML_FIN (inout _env any) returns long varchar
  6500. {
  6501. declare ses any;
  6502. declare ans varchar;
  6503. ses := string_output ();
  6504. if (isinteger (_env) and _env)
  6505. ans := 'true';
  6506. else
  6507. ans := 'false';
  6508. http ('<sparql xmlns="http://www.w3.org/2005/sparql-results#" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.w3.org/2001/sw/DataAccess/rf1/result2.xsd">
  6509. <head></head>
  6510. <boolean>' || ans || '</boolean>
  6511. </sparql>', ses);
  6512. return ses;
  6513. }
  6514. ;
  6515. create aggregate DB.DBA.RDF_FORMAT_BOOL_RESULT_AS_XML (in one any array) returns long varchar
  6516. from DB.DBA.RDF_FORMAT_BOOL_RESULT_AS_XML_INIT, DB.DBA.RDF_FORMAT_BOOL_RESULT_AS_XML_ACC, DB.DBA.RDF_FORMAT_BOOL_RESULT_AS_XML_FIN
  6517. ;
  6518. --!AWK PUBLIC
  6519. create procedure DB.DBA.RDF_FORMAT_BOOL_RESULT_AS_RDF_XML_INIT (inout _env any)
  6520. {
  6521. _env := 0;
  6522. }
  6523. ;
  6524. --!AWK PUBLIC
  6525. create procedure DB.DBA.RDF_FORMAT_BOOL_RESULT_AS_RDF_XML_ACC (inout _env any, in one any array)
  6526. {
  6527. _env := 1;
  6528. }
  6529. ;
  6530. --!AWK PUBLIC
  6531. create function DB.DBA.RDF_FORMAT_BOOL_RESULT_AS_RDF_XML_FIN (inout _env any) returns long varchar
  6532. {
  6533. declare ses any;
  6534. declare ans varchar;
  6535. ses := string_output ();
  6536. if (isinteger (_env) and _env)
  6537. ans := '1';
  6538. else
  6539. ans := '0';
  6540. http ('<rdf:RDF
  6541. xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
  6542. xmlns:rs="http://www.w3.org/2005/sparql-results#"
  6543. xmlns:xsd="http://www.w3.org/2001/XMLSchema#" >
  6544. <rs:results rdf:nodeID="rset">
  6545. <rs:boolean rdf:datatype="http://www.w3.org/2001/XMLSchema#boolean">' || ans || '</rs:boolean></rs:results></rdf:RDF>', ses);
  6546. return ses;
  6547. }
  6548. ;
  6549. create aggregate DB.DBA.RDF_FORMAT_BOOL_RESULT_AS_RDF_XML (in one any array) returns long varchar
  6550. from DB.DBA.RDF_FORMAT_BOOL_RESULT_AS_RDF_XML_INIT, DB.DBA.RDF_FORMAT_BOOL_RESULT_AS_RDF_XML_ACC, DB.DBA.RDF_FORMAT_BOOL_RESULT_AS_RDF_XML_FIN
  6551. ;
  6552. --!AWK PUBLIC
  6553. create procedure DB.DBA.RDF_FORMAT_BOOL_RESULT_AS_TTL_INIT (inout _env any)
  6554. {
  6555. _env := 0;
  6556. }
  6557. ;
  6558. --!AWK PUBLIC
  6559. create procedure DB.DBA.RDF_FORMAT_BOOL_RESULT_AS_TTL_ACC (inout _env any, in one any array)
  6560. {
  6561. _env := 1;
  6562. }
  6563. ;
  6564. --!AWK PUBLIC
  6565. create function DB.DBA.RDF_FORMAT_BOOL_RESULT_AS_TTL_FIN (inout _env any) returns long varchar
  6566. {
  6567. declare ses any;
  6568. declare ans varchar;
  6569. ses := string_output ();
  6570. if (isinteger (_env) and _env)
  6571. ans := 'TRUE';
  6572. else
  6573. ans := 'FALSE';
  6574. http ('@prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> .
  6575. @prefix rs: <http://www.w3.org/2005/sparql-results#> .\n', ses);
  6576. http (sprintf ('[] rdf:type rs:results ; rs:boolean %s .', ans), ses);
  6577. return ses;
  6578. }
  6579. ;
  6580. create aggregate DB.DBA.RDF_FORMAT_BOOL_RESULT_AS_TTL (in one any array) returns long varchar
  6581. from DB.DBA.RDF_FORMAT_BOOL_RESULT_AS_TTL_INIT, DB.DBA.RDF_FORMAT_BOOL_RESULT_AS_TTL_ACC, DB.DBA.RDF_FORMAT_BOOL_RESULT_AS_TTL_FIN
  6582. ;
  6583. --!AWK PUBLIC
  6584. create function DB.DBA.RDF_FORMAT_BOOL_RESULT_AS_NT_FIN (inout _env any) returns long varchar
  6585. {
  6586. declare ses any;
  6587. declare ans varchar;
  6588. ses := string_output ();
  6589. if (isinteger (_env) and _env)
  6590. ans := 'true';
  6591. else
  6592. ans := 'false';
  6593. http (sprintf ('_:_ <http://www.w3.org/1999/02/22-rdf-syntax-ns#type> <http://www.w3.org/2005/sparql-results#results> .\n_:_ <http://www.w3.org/2005/sparql-results#boolean> "%s"^^<http://www.w3.org/2001/XMLSchema#boolean> .\n', ans), ses);
  6594. return ses;
  6595. }
  6596. ;
  6597. create aggregate DB.DBA.RDF_FORMAT_BOOL_RESULT_AS_NT (in one any array) returns long varchar
  6598. from DB.DBA.RDF_FORMAT_BOOL_RESULT_AS_TTL_INIT, -- Not DB.DBA.RDF_FORMAT_BOOL_RESULT_AS_NT_INIT
  6599. DB.DBA.RDF_FORMAT_BOOL_RESULT_AS_TTL_ACC, -- Not DB.DBA.RDF_FORMAT_BOOL_RESULT_AS_NT_ACC
  6600. DB.DBA.RDF_FORMAT_BOOL_RESULT_AS_NT_FIN
  6601. ;
  6602. create aggregate DB.DBA.RDF_FORMAT_BOOL_RESULT_AS_TTL (in one any array) returns long varchar
  6603. from DB.DBA.RDF_FORMAT_BOOL_RESULT_AS_TTL_INIT, DB.DBA.RDF_FORMAT_BOOL_RESULT_AS_TTL_ACC, DB.DBA.RDF_FORMAT_BOOL_RESULT_AS_TTL_FIN
  6604. ;
  6605. --!AWK PUBLIC
  6606. create function DB.DBA.RDF_FORMAT_BOOL_RESULT_AS_CSV_FIN (inout _env any) returns long varchar
  6607. {
  6608. declare ans varchar;
  6609. if (isinteger (_env) and _env)
  6610. return '"bool"\n1\n';
  6611. else
  6612. return '"bool"\n0\n';
  6613. }
  6614. ;
  6615. create aggregate DB.DBA.RDF_FORMAT_BOOL_RESULT_AS_CSV (in one any array) returns long varchar
  6616. from DB.DBA.RDF_FORMAT_BOOL_RESULT_AS_TTL_INIT, -- Not DB.DBA.RDF_FORMAT_BOOL_RESULT_AS_CSV_INIT
  6617. DB.DBA.RDF_FORMAT_BOOL_RESULT_AS_TTL_ACC, -- Not DB.DBA.RDF_FORMAT_BOOL_RESULT_AS_CSV_ACC
  6618. DB.DBA.RDF_FORMAT_BOOL_RESULT_AS_CSV_FIN
  6619. ;
  6620. -----
  6621. -- Insert, delete, modify operations for lists of triples
  6622. -- By default, SPARQL 1.0 codegen makes calls of SPARQL_INSERT_DICT_CONTENT() / SPARQL_DELETE_DICT_CONTENT() / SPARQL_MODIFY_BY_DICT_CONTENTS()
  6623. -- with SPARQL_CONSTRUCT as an aggregate that makes dictionary of triples
  6624. -- SPARQL 1.1 codegen can also make calls of SPARQL_INSERT_QUAD_DICT_CONTENT() / SPARQL_DELETE_QUAD_DICT_CONTENT() / SPARQL_MODIFY_BY_QUAD_DICT_CONTENTS()
  6625. -- with SPARQL_CONSTRUCT as an aggregate that makes dictionary of triples or quads.
  6626. -- The optimizer can tweak these calls for optimization: instead of plain constant for default graph IRI,
  6627. -- a call of SPARQL_INSERT_CTOR / SPARQL_DELETE_CTOR / SPARQL_MODIFY_CTOR can be placed.
  6628. -- Thus some triples will be inserted/deleted witout being accumulated in dictionary for the whole time of the selection process.
  6629. -- Accomulators SPARQL_INSERT_CTOR_ACC / SPARQL_DELETE_CTOR_ACC / SPARQL_MODIFY_CTOR_ACC are based on a common
  6630. -- SPARQL_INS_OR_DEL_CTOR_IMPL that calls either RDF_INSERT_TRIPLES / RDF_INSERT_QUADS or RDF_DELETE_TRIPLES_AGG / RDF_DELETE_QUADS, depending on the requested operation code.
  6631. -- A common finalizer SPARQL_INS_OR_DEL_OR_MODIFY_CTOR_FIN calls RDF_INSERT_TRIPLES / RDF_INSERT_QUADS or RDF_DELETE_TRIPLES /* without _AGG suffix*/ / RDF_DELETE_QUADS.
  6632. create procedure DB.DBA.RDF_INSERT_TRIPLES_CL (inout graph_iri any, inout triples any, in log_mode integer := null)
  6633. {
  6634. declare is_text, ctr, old_log_enable, l integer;
  6635. declare ro_id_dict, dp any;
  6636. if ('1' = registry_get ('cl_rdf_text_index'))
  6637. is_text := 1;
  6638. if (not isiri_id (graph_iri))
  6639. graph_iri := iri_to_id (graph_iri);
  6640. if (__rdf_graph_is_in_enabled_repl (graph_iri))
  6641. DB.DBA.RDF_REPL_INSERT_TRIPLES (id_to_iri (graph_iri), triples);
  6642. connection_set ('g_iid', graph_iri);
  6643. ro_id_dict := null;
  6644. --ro_id_dict := dict_new ();
  6645. --connection_set ('g_dict', ro_id_dict);
  6646. dp := dpipe (0, 'IRI_TO_ID_1', 'IRI_TO_ID_1', 'IRI_TO_ID_1', 'MAKE_RO_1', 'IRI_TO_ID_1');
  6647. dpipe_set_rdf_load (dp);
  6648. l := length (triples);
  6649. for (ctr := 0; ctr < l; ctr := ctr + 1)
  6650. {
  6651. declare r, o_val any;
  6652. r := triples[ctr];
  6653. o_val := r[2];
  6654. if (__tag (o_val) in (__tag of varchar, __tag of XML))
  6655. {
  6656. if (is_text)
  6657. {
  6658. -- make first first non default type because if all is default it will make no box
  6659. declare o_val_2 any;
  6660. o_val_2 := rdf_box (o_val, 300, 257, 0, 1);
  6661. rdf_box_set_is_text (o_val_2, 1);
  6662. rdf_box_set_type (o_val_2, 257);
  6663. -- dbg_obj_princ ('DB.DBA.RDF_INSERT_TRIPLES_CL inserts text1 ', r[0], r[1], null, o_val_2, null);
  6664. dpipe_input (dp, r[0], r[1], null, o_val_2, null);
  6665. }
  6666. else
  6667. {
  6668. -- dbg_obj_princ ('DB.DBA.RDF_INSERT_TRIPLES_CL inserts text0 ', r[0], r[1], null, o_val, null);
  6669. -- dbg_obj_princ ('zero is_text in sparql.sql:6618 ', o_val);
  6670. dpipe_input (dp, r[0], r[1], null, o_val, null);
  6671. }
  6672. }
  6673. else
  6674. {
  6675. -- dbg_obj_princ ('DB.DBA.RDF_INSERT_TRIPLES_CL inserts ', r[0], r[1], null, o_val);
  6676. -- dbg_obj_princ ('unknown is_text in sparql.sql:6626 ', o_val);
  6677. dpipe_input (dp, r[0], r[1], null, o_val, null);
  6678. }
  6679. if (mod (ctr + 1, 40000) = 0 and l > 60000)
  6680. {
  6681. dpipe_next (dp, 0);
  6682. dpipe_next (dp, 1);
  6683. dpipe_reuse (dp);
  6684. }
  6685. }
  6686. dpipe_next (dp, 0);
  6687. dpipe_next (dp, 1);
  6688. if (ro_id_dict is not null)
  6689. DB.DBA.RDF_OBJ_ADD_KEYWORD_FOR_GRAPH (graph_iri, ro_id_dict);
  6690. }
  6691. ;
  6692. /* insert */
  6693. create procedure DB.DBA.RDF_INSERT_TRIPLES (in graph_iid any, inout triples any, in log_mode integer := null)
  6694. {
  6695. declare ctr, old_log_enable integer;
  6696. declare ro_id_dict any;
  6697. if (0 = sys_stat ('cl_run_local_only'))
  6698. return RDF_INSERT_TRIPLES_CL (graph_iid, triples, log_mode);
  6699. if (not isiri_id (graph_iid))
  6700. graph_iid := iri_to_id (graph_iid);
  6701. if (__rdf_graph_is_in_enabled_repl (graph_iid))
  6702. DB.DBA.RDF_REPL_INSERT_TRIPLES (id_to_iri (graph_iid), triples);
  6703. old_log_enable := log_enable (log_mode, 1);
  6704. declare exit handler for sqlstate '*' { log_enable (old_log_enable, 1); resignal; };
  6705. if (0 = bit_and (old_log_enable, 2))
  6706. {
  6707. declare dp any;
  6708. dp := rl_local_dpipe ();
  6709. connection_set ('g_iid', graph_iid);
  6710. for (ctr := length (triples) - 1; ctr >= 0; ctr := ctr - 1)
  6711. {
  6712. declare s_iid, p_iid, obj, o_type, o_lang any;
  6713. s_iid := triples[ctr][0];
  6714. p_iid := triples[ctr][1];
  6715. obj := triples[ctr][2];
  6716. if (isiri_id (obj))
  6717. dpipe_input (dp, s_iid, p_iid, obj, null);
  6718. else
  6719. {
  6720. __rdf_obj_set_is_text_if_ft_rule_check (obj, graph_iid, p_iid, null);
  6721. dpipe_input (dp, s_iid, p_iid, null, obj);
  6722. }
  6723. }
  6724. rl_flush (dp, graph_iid);
  6725. return;
  6726. }
  6727. if (not is_atomic ())
  6728. {
  6729. declare app_env any;
  6730. -- dbg_obj_princ ('DB.DBA.RDF_INSERT_TRIPLES, not atomic');
  6731. app_env := vector (async_queue (0, 1), rl_local_dpipe (), 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
  6732. connection_set ('g_iid', graph_iid);
  6733. for (ctr := length (triples) - 1; ctr >= 0; ctr := ctr - 1)
  6734. {
  6735. declare s_iid, p_iid, obj, o_type, o_lang any;
  6736. s_iid := triples[ctr][0];
  6737. p_iid := triples[ctr][1];
  6738. obj := triples[ctr][2];
  6739. if (isiri_id (obj))
  6740. dpipe_input (app_env[1], s_iid, p_iid, obj, null);
  6741. else
  6742. {
  6743. __rdf_obj_set_is_text_if_ft_rule_check (obj, graph_iid, p_iid, null);
  6744. dpipe_input (app_env[1], s_iid, p_iid, null, obj);
  6745. }
  6746. if (dpipe_count (app_env[1]) > dc_batch_sz ())
  6747. rl_send (app_env, graph_iid);
  6748. }
  6749. rl_send (app_env, graph_iid);
  6750. commit work;
  6751. aq_wait_all (app_env[0]);
  6752. connection_set ('g_dict', null);
  6753. log_enable (old_log_enable, 1);
  6754. return;
  6755. }
  6756. ro_id_dict := null;
  6757. for (ctr := length (triples) - 1; ctr >= 0; ctr := ctr - 1)
  6758. {
  6759. declare p_iid, o_orig, o_final any;
  6760. declare need_digest integer;
  6761. p_iid := triples[ctr][1];
  6762. o_final := o_orig := triples[ctr][2];
  6763. if (isiri_id (o_final))
  6764. goto do_insert;
  6765. if (ro_id_dict is null and __rdf_obj_ft_rule_check (graph_iid, p_iid))
  6766. ro_id_dict := dict_new ();
  6767. -- dbg_obj_princ ('DB.DBA.RDF_INSERT_TRIPLES got ', graph_iid, triples[ctr][0], p_iid, o_final);
  6768. need_digest := rdf_box_needs_digest (o_final, ro_id_dict);
  6769. if (1 < need_digest)
  6770. {
  6771. o_final := DB.DBA.RDF_MAKE_OBJ_OF_SQLVAL_FT (o_final, graph_iid, p_iid, ro_id_dict);
  6772. --if (not rdf_box_is_storeable (o_final))
  6773. -- {
  6774. -- -- dbg_obj_princ ('OBLOM', 'Bad O after DB.DBA.MAKE_OBJ_OF_SQLVAL_FT', o_orig, '=>', o_final);
  6775. -- signal ('OBLOM', 'Bad O after MAKE_OBJ_OF_SQLVAL_FT');
  6776. -- }
  6777. }
  6778. else
  6779. {
  6780. o_final := DB.DBA.RDF_OBJ_ADD (257, o_final, 257);
  6781. --if (not rdf_box_is_storeable (o_final))
  6782. -- {
  6783. -- -- dbg_obj_princ ('OBLOM', 'Bad O after DB.DBA.RDF_OBJ_ADD', o_orig, '=>', o_final);
  6784. -- signal ('OBLOM', 'Bad O after DB.DBA.RDF_OBJ_ADD');
  6785. -- }
  6786. }
  6787. do_insert:
  6788. -- dbg_obj_princ ('DB.DBA.RDF_INSERT_TRIPLES inserts ', graph_iid, triples[ctr][0], p_iid, o_final);
  6789. insert soft DB.DBA.RDF_QUAD (G,S,P,O)
  6790. values (graph_iid, triples[ctr][0], p_iid, o_final);
  6791. }
  6792. if (ro_id_dict is not null)
  6793. DB.DBA.RDF_OBJ_ADD_KEYWORD_FOR_GRAPH (graph_iid, ro_id_dict);
  6794. log_enable (old_log_enable, 1);
  6795. }
  6796. ;
  6797. create procedure DB.DBA.RDF_DELETE_TRIPLES (in graph_iri any, in triples any, in log_mode integer := null)
  6798. {
  6799. declare ctr, old_log_enable, l integer;
  6800. if (not isiri_id (graph_iri))
  6801. graph_iri := iri_to_id (graph_iri);
  6802. if (__rdf_graph_is_in_enabled_repl (graph_iri))
  6803. DB.DBA.RDF_REPL_DELETE_TRIPLES (id_to_iri (graph_iri), triples);
  6804. old_log_enable := log_enable (log_mode, 1);
  6805. declare exit handler for sqlstate '*' { log_enable (old_log_enable, 1); resignal; };
  6806. if (1 = sys_stat ('enable_vec'))
  6807. {
  6808. declare gv, sv, pv, ov any;
  6809. l := length (triples);
  6810. gv := make_array (l, 'any');
  6811. sv := make_array (l, 'any');
  6812. pv := make_array (l, 'any');
  6813. ov := make_array (l, 'any');
  6814. for (ctr := 0; ctr < l; ctr := ctr + 1)
  6815. {
  6816. declare r any;
  6817. r := triples[ctr];
  6818. gv[ctr] := graph_iri;
  6819. sv[ctr] := r[0];
  6820. pv[ctr] := r[1];
  6821. ov[ctr] := DB.DBA.RDF_OBJ_OF_LONG (r[2]);
  6822. }
  6823. for vectored (in gi any := gv, in si any := sv, in pi any := pv, in oi any array := ov)
  6824. {
  6825. delete from DB.DBA.RDF_QUAD where G = gi and S = si and P = pi and O = oi;
  6826. }
  6827. log_enable (old_log_enable, 1);
  6828. return;
  6829. }
  6830. for (ctr := length (triples) - 1; ctr >= 0; ctr := ctr - 1)
  6831. {
  6832. declare o_short any;
  6833. o_short := DB.DBA.RDF_OBJ_OF_LONG (triples[ctr][2]);
  6834. -- {
  6835. -- whenever sqlstate '*' goto strange_fail;
  6836. delete from DB.DBA.RDF_QUAD
  6837. where G = graph_iri and S = triples[ctr][0] and P = triples[ctr][1] and O = o_short;
  6838. -- goto complete;
  6839. -- }
  6840. --strange_fail:
  6841. -- if (not exists (select top 1 1 from DB.DBA.RDF_QUAD
  6842. -- where G = graph_iri and S = triples[ctr][0] and P = triples[ctr][1] and O = o_short ) )
  6843. -- goto complete;
  6844. -- delete from DB.DBA.RDF_QUAD
  6845. -- where G = graph_iri and S = triples[ctr][0] and P = triples[ctr][1] and O = o_short;
  6846. -- complete: ;
  6847. }
  6848. log_enable (old_log_enable, 1);
  6849. }
  6850. ;
  6851. -- /* delete */
  6852. create procedure DB.DBA.RDF_DELETE_TRIPLES_AGG (in graph_iid any, inout triples any, in log_mode integer := null)
  6853. {
  6854. declare ctr, old_log_enable, l integer;
  6855. if (not isiri_id (graph_iid))
  6856. graph_iid := iri_to_id (graph_iid);
  6857. if (__rdf_graph_is_in_enabled_repl (graph_iid))
  6858. DB.DBA.RDF_REPL_DELETE_TRIPLES (id_to_iri (graph_iid), triples);
  6859. old_log_enable := log_enable (log_mode, 1);
  6860. declare exit handler for sqlstate '*' { log_enable (old_log_enable, 1); resignal; };
  6861. for vectored (in a_triple any array := triples)
  6862. {
  6863. declare a_s, a_p, a_o any array;
  6864. a_s := a_triple[0];
  6865. a_p := a_triple[1];
  6866. a_o := a_triple[2];
  6867. if (not isiri_id (a_s))
  6868. a_s := __i2idn (a_s);
  6869. if (not isiri_id (a_p))
  6870. a_p := __i2idn (a_p);
  6871. if (isiri_id (a_s) and isiri_id (a_p))
  6872. {
  6873. if (isiri_id (a_o))
  6874. delete from DB.DBA.RDF_QUAD where G = graph_iid and S = a_s and P = a_p and O = a_o;
  6875. else
  6876. {
  6877. declare o_val any array;
  6878. declare o_dt_and_lang_twobyte integer;
  6879. declare search_fields_are_ok integer;
  6880. search_fields_are_ok := __rdf_box_to_ro_id_search_fields (a_o, o_val, o_dt_and_lang_twobyte);
  6881. -- dbg_obj_princ ('__rdf_box_to_ro_id_search_fields (', a_o, ') returned ', search_fields_are_ok, o_val, o_dt_and_lang_twobyte);
  6882. if (__tag of rdf_box = __tag (a_o) and rdf_box_is_complete (a_o))
  6883. delete from DB.DBA.RDF_QUAD where G = graph_iid and S = a_s and P = a_p and O = a_o;
  6884. else if (search_fields_are_ok)
  6885. delete from DB.DBA.RDF_QUAD where G = graph_iid and S = a_s and P = a_p and O = (select rdf_box_from_ro_id(RO_ID) from DB.DBA.RDF_OBJ where RO_VAL = o_val and RO_DT_AND_LANG = o_dt_and_lang_twobyte);
  6886. else if (isstring (a_o)) /* it should be string IRI otherwise it's in RDF_OBJ */
  6887. delete from DB.DBA.RDF_QUAD where G = graph_iid and S = a_s and P = a_p and O = iri_to_id (a_o);
  6888. else
  6889. delete from DB.DBA.RDF_QUAD where G = graph_iid and S = a_s and P = a_p and O = a_o;
  6890. }
  6891. }
  6892. }
  6893. log_enable (old_log_enable, 1);
  6894. }
  6895. ;
  6896. create procedure DB.DBA.RDF_MODIFY_TRIPLES (in graph_iri any, in del_triples any, in ins_triples any, in log_mode integer := null)
  6897. {
  6898. DB.DBA.RDF_DELETE_TRIPLES (graph_iri, del_triples, log_mode);
  6899. DB.DBA.RDF_INSERT_TRIPLES (graph_iri, ins_triples, log_mode);
  6900. }
  6901. ;
  6902. --!AWK PUBLIC
  6903. create procedure DB.DBA.SPARQL_INS_OR_DEL_OR_MODIFY_CTOR_INIT (inout _env any)
  6904. {
  6905. _env := 0;
  6906. }
  6907. ;
  6908. --!AWK PUBLIC
  6909. create procedure DB.DBA.SPARQL_INS_OR_DEL_CTOR_IMPL (inout _env any, in graph_iri any, in opcodes any, in vars any, in log_mode integer, in ctor_op integer)
  6910. {
  6911. declare triple_ctr, quads_found integer;
  6912. declare blank_ids any;
  6913. declare dict any;
  6914. declare action_ctr integer;
  6915. declare old_log_enable integer;
  6916. old_log_enable := log_enable (log_mode, 1);
  6917. -- dbg_obj_princ ('DB.DBA.SPARQL_INS_OR_DEL_CTOR_IMPL (', _env, graph_iri, opcodes, vars, log_mode, ctor_op, ')');
  6918. declare exit handler for sqlstate '*' { log_enable (old_log_enable, 1); resignal; };
  6919. blank_ids := 0;
  6920. action_ctr := 0;
  6921. quads_found := _env[5 + ctor_op];
  6922. for (triple_ctr := length (opcodes) - 1; triple_ctr >= 0; triple_ctr := triple_ctr-1)
  6923. {
  6924. declare fld_ctr, fld_count integer;
  6925. declare triple_vec any;
  6926. declare g_opcode integer;
  6927. g_opcode := aref_or_default (opcodes, triple_ctr, 6, null);
  6928. if (g_opcode is null)
  6929. {
  6930. fld_count := 3;
  6931. triple_vec := vector (0,0,0);
  6932. }
  6933. else
  6934. {
  6935. fld_count := 4;
  6936. triple_vec := vector (0,0,0,0);
  6937. }
  6938. for (fld_ctr := fld_count - 1; fld_ctr >= 0; fld_ctr := fld_ctr - 1)
  6939. {
  6940. declare op integer;
  6941. declare arg any;
  6942. op := opcodes[triple_ctr][fld_ctr * 2];
  6943. arg := opcodes[triple_ctr][fld_ctr * 2 + 1];
  6944. if (1 = op)
  6945. {
  6946. declare i any;
  6947. i := vars[arg];
  6948. if (i is null)
  6949. goto end_of_adding_triple;
  6950. if (isiri_id (i))
  6951. {
  6952. if (fld_ctr in (1,3) and is_bnode_iri_id (i))
  6953. signal ('RDF01', 'Bad variable value in INSERT: blank node can not be used as predicate or graph');
  6954. }
  6955. else if ((isstring (i) and (1 = __box_flags (i))) or (217 = __tag(i)))
  6956. {
  6957. if (fld_ctr in (1,3) and (i like 'bnode://%'))
  6958. signal ('RDF01', 'Bad variable value in INSERT: blank node can not be used as predicate or graph');
  6959. i := iri_to_id (i);
  6960. }
  6961. else if (2 <> fld_ctr)
  6962. signal ('RDF01',
  6963. sprintf ('Bad variable value in INSERT: "%.100s" (tag %d box flags %d) is not a valid %s, only object of a triple can be a literal',
  6964. __rdf_strsqlval (i), __tag (i), __box_flags (i),
  6965. case (fld_ctr) when 1 then 'predicate' else 'subject' end ) );
  6966. triple_vec[fld_ctr] := i;
  6967. }
  6968. else if (2 = op)
  6969. {
  6970. if (isinteger (blank_ids))
  6971. blank_ids := vector (iri_id_from_num (sequence_next ('RDF_URL_IID_BLANK')));
  6972. while (arg >= length (blank_ids))
  6973. blank_ids := vector_concat (blank_ids, vector (iri_id_from_num (sequence_next ('RDF_URL_IID_BLANK'))));
  6974. if (fld_ctr in (1,3))
  6975. signal ('RDF01', 'Bad triple for INSERT: blank node can not be used as predicate');
  6976. triple_vec[fld_ctr] := blank_ids[arg];
  6977. }
  6978. else if (3 = op)
  6979. {
  6980. if (arg is null)
  6981. goto end_of_adding_triple;
  6982. if (isiri_id (arg))
  6983. {
  6984. if (fld_ctr in (1,3) and is_bnode_iri_id (arg))
  6985. signal ('RDF01', 'Bad const value in INSERT: blank node can not be used as predicate or graph');
  6986. }
  6987. else if ((isstring (arg) and (1 = __box_flags (arg))) or (217 = __tag(arg)))
  6988. {
  6989. if (fld_ctr in (1,3) and (arg like 'bnode://%'))
  6990. signal ('RDF01', 'Bad const value in INSERT: blank node can not be used as predicate or graph');
  6991. arg := iri_to_id (arg);
  6992. }
  6993. else if (2 <> fld_ctr)
  6994. signal ('RDF01',
  6995. sprintf ('Bad const value in INSERT: "%.100s" (tag %d box flags %d) is not a valid %s, only object of a triple can be a literal',
  6996. __rdf_strsqlval (arg), __tag (arg), __box_flags (arg),
  6997. case (fld_ctr) when 1 then 'predicate' else 'subject' end ) );
  6998. else if (__tag of vector = __tag (arg))
  6999. arg := DB.DBA.RDF_MAKE_LONG_OF_TYPEDSQLVAL_STRINGS (arg[0], arg[1], arg[2]);
  7000. triple_vec[fld_ctr] := arg;
  7001. }
  7002. else signal ('RDFXX', 'Bad opcode in DB.DBA.SPARQL_INSERT_CTOR()');
  7003. }
  7004. -- dbg_obj_princ ('generated triple:', triple_vec);
  7005. if (4 = fld_count)
  7006. quads_found := 1;
  7007. dict := _env [2 + ctor_op];
  7008. dict_put (dict, triple_vec, 1);
  7009. if (1 = ctor_op)
  7010. {
  7011. -- delete from DB.DBA.RDF_QUAD
  7012. -- where G = _env[0] and S = triple_vec[0] and P = triple_vec[1] and O = DB.DBA.RDF_OBJ_OF_LONG(triple_vec[2]);
  7013. if (80000 <= dict_size (dict))
  7014. {
  7015. if (quads_found)
  7016. {
  7017. DB.DBA.RDF_DELETE_QUADS (_env[0], dict_list_keys (dict, 2), _env[8], _env[5]);
  7018. quads_found := 0;
  7019. }
  7020. else
  7021. DB.DBA.RDF_DELETE_TRIPLES_AGG (_env[0], dict_list_keys (dict, 2), _env[5]);
  7022. }
  7023. }
  7024. else
  7025. {
  7026. -- insert soft DB.DBA.RDF_QUAD (G,S,P,O)
  7027. -- values (_env[0], triple_vec[0], triple_vec[1], DB.DBA.RDF_OBJ_OF_LONG(triple_vec[2]));
  7028. if (80000 <= dict_size (dict))
  7029. {
  7030. if (quads_found)
  7031. {
  7032. DB.DBA.RDF_INSERT_QUADS (_env[0], dict_list_keys (dict, 2), _env[8], _env[5]);
  7033. quads_found := 0;
  7034. }
  7035. else
  7036. DB.DBA.RDF_INSERT_TRIPLES (_env[0], dict_list_keys (dict, 2), _env[5]);
  7037. }
  7038. }
  7039. action_ctr := action_ctr + 1;
  7040. end_of_adding_triple: ;
  7041. }
  7042. _env[ctor_op] := _env[ctor_op] + action_ctr;
  7043. _env[5 + ctor_op] := quads_found;
  7044. log_enable (old_log_enable, 1);
  7045. }
  7046. ;
  7047. --!AWK PUBLIC
  7048. create function DB.DBA.SPARQL_DELETE_CTOR_ACC (inout _env any, in graph_iri any, in opcodes any, in vars any, in uid integer, in log_mode integer)
  7049. {
  7050. if (not (isarray (_env)))
  7051. -- 0 1 2 3 4 5 6 7 8
  7052. _env := vector (iri_to_id (graph_iri), 0, 0, dict_new (80000), null, log_mode, 0, 0, uid);
  7053. if (not _env[1])
  7054. __rgs_assert_cbk (graph_iri, uid, 2, 'SPARUL DELETE');
  7055. DB.DBA.SPARQL_INS_OR_DEL_CTOR_IMPL (_env, graph_iri, opcodes, vars, log_mode, 1);
  7056. }
  7057. ;
  7058. --!AWK PUBLIC
  7059. create procedure DB.DBA.SPARQL_INSERT_CTOR_ACC (inout _env any, in graph_iri any, in opcodes any, in vars any, in uid integer, in log_mode integer)
  7060. {
  7061. -- dbg_obj_princ ('DB.DBA.SPARQL_INSERT_CTOR_ACC (', _env, graph_iri, opcodes, vars, uid, log_mode);
  7062. if (not (isarray (_env)))
  7063. -- 0 1 2 3 4 5 6 7 8
  7064. _env := vector (iri_to_id (graph_iri), 0, 0, null, dict_new (80000), log_mode, 0, 0, uid);
  7065. if (not _env[2])
  7066. __rgs_assert_cbk (graph_iri, uid, 2, 'SPARUL INSERT');
  7067. DB.DBA.SPARQL_INS_OR_DEL_CTOR_IMPL (_env, graph_iri, opcodes, vars, log_mode, 2);
  7068. }
  7069. ;
  7070. --!AWK PUBLIC
  7071. create procedure DB.DBA.SPARQL_MODIFY_CTOR_ACC (inout _env any, in graph_iri any, in del_opcodes any, in ins_opcodes any, in vars any, in uid integer, in log_mode integer)
  7072. {
  7073. if (not (isarray (_env)))
  7074. -- 0 1 2 3 4 5 6 7 8
  7075. _env := vector (iri_to_id (graph_iri), 0, 0, dict_new (80000), dict_new (80000), log_mode, 0, 0, uid);
  7076. if (not _env[1] and not _env[2])
  7077. __rgs_assert_cbk (graph_iri, uid, 2, 'SPARUL MODIFY');
  7078. DB.DBA.SPARQL_INS_OR_DEL_CTOR_IMPL (_env, graph_iri, del_opcodes, vars, log_mode, 1);
  7079. DB.DBA.SPARQL_INS_OR_DEL_CTOR_IMPL (_env, graph_iri, ins_opcodes, vars, log_mode, 2);
  7080. }
  7081. ;
  7082. --!AWK PUBLIC
  7083. create procedure DB.DBA.SPARQL_INS_OR_DEL_OR_MODIFY_CTOR_FIN (inout _env any)
  7084. {
  7085. if (isarray (_env))
  7086. {
  7087. declare dict any;
  7088. dict := _env[3];
  7089. if (dict is not null and (0 < dict_size (dict)))
  7090. {
  7091. _env[3] := null;
  7092. if (_env[6])
  7093. DB.DBA.RDF_DELETE_QUADS (_env[0], dict_list_keys (dict, 2), _env[8], _env[5]);
  7094. else
  7095. DB.DBA.RDF_DELETE_TRIPLES (_env[0], dict_list_keys (dict, 2), _env[5]);
  7096. }
  7097. dict := _env[4];
  7098. if (dict is not null and (0 < dict_size (dict)))
  7099. {
  7100. _env[4] := null;
  7101. if (_env[7])
  7102. DB.DBA.RDF_INSERT_QUADS (_env[0], dict_list_keys (dict, 2), _env[8], _env[5]);
  7103. else
  7104. DB.DBA.RDF_INSERT_TRIPLES (_env[0], dict_list_keys (dict, 2), _env[5]);
  7105. }
  7106. }
  7107. return _env;
  7108. }
  7109. ;
  7110. --!AWK PUBLIC
  7111. create aggregate DB.DBA.SPARQL_DELETE_CTOR (in graph_iri any, in opcodes any, in vars any, in uid integer, in log_mode integer) returns any
  7112. from DB.DBA.SPARQL_INS_OR_DEL_OR_MODIFY_CTOR_INIT, DB.DBA.SPARQL_DELETE_CTOR_ACC, DB.DBA.SPARQL_INS_OR_DEL_OR_MODIFY_CTOR_FIN
  7113. ;
  7114. --!AWK PUBLIC
  7115. create aggregate DB.DBA.SPARQL_INSERT_CTOR (in graph_iri any, in opcodes any, in vars any, in uid integer, in log_mode integer) returns any
  7116. from DB.DBA.SPARQL_INS_OR_DEL_OR_MODIFY_CTOR_INIT, DB.DBA.SPARQL_INSERT_CTOR_ACC, DB.DBA.SPARQL_INS_OR_DEL_OR_MODIFY_CTOR_FIN
  7117. ;
  7118. --!AWK PUBLIC
  7119. create aggregate DB.DBA.SPARQL_MODIFY_CTOR (in graph_iri any, in del_opcodes any, in ins_opcodes any, in vars any, in uid integer, in log_mode integer) returns any
  7120. from DB.DBA.SPARQL_INS_OR_DEL_OR_MODIFY_CTOR_INIT, DB.DBA.SPARQL_MODIFY_CTOR_ACC, DB.DBA.SPARQL_INS_OR_DEL_OR_MODIFY_CTOR_FIN
  7121. ;
  7122. create function DB.DBA.SPARQL_INSERT_DICT_CONTENT (in graph_iri any, in triples_dict any, in uid integer, in log_mode integer := null, in compose_report integer := 0) returns any
  7123. {
  7124. declare triples any;
  7125. declare ins_count integer;
  7126. ins_count := 0;
  7127. if (__tag of vector = __tag (graph_iri))
  7128. {
  7129. ins_count := graph_iri[2]; -- 2, not 1
  7130. graph_iri := graph_iri[0]; -- the last op.
  7131. }
  7132. __rgs_assert_cbk (graph_iri, uid, 2, 'SPARUL INSERT');
  7133. while (dict_size (triples_dict) > 0)
  7134. {
  7135. triples := dict_destructive_list_rnd_keys (triples_dict, 80000);
  7136. DB.DBA.RDF_INSERT_TRIPLES (graph_iri, triples, log_mode);
  7137. ins_count := ins_count + length (triples);
  7138. }
  7139. if (isiri_id (graph_iri))
  7140. graph_iri := id_to_iri (graph_iri);
  7141. if (graph_iri is not null and __rdf_graph_is_in_enabled_repl (iri_to_id (graph_iri)))
  7142. repl_text ('__rdf_repl', '__rdf_repl_flush_queue ()');
  7143. if (compose_report)
  7144. {
  7145. if (ins_count)
  7146. return sprintf ('Insert into <%s>, %d (or less) triples -- done', graph_iri, ins_count);
  7147. else
  7148. return sprintf ('Insert into <%s>, 0 triples -- nothing to do', graph_iri);
  7149. }
  7150. else
  7151. return ins_count;
  7152. }
  7153. ;
  7154. create function DB.DBA.SPARQL_DELETE_DICT_CONTENT (in graph_iri any, in triples_dict any, in uid integer, in log_mode integer := null, in compose_report integer := 0) returns any
  7155. {
  7156. declare triples any;
  7157. declare del_count integer;
  7158. del_count := 0;
  7159. if (__tag of vector = __tag (graph_iri))
  7160. {
  7161. del_count := graph_iri[1];
  7162. graph_iri := graph_iri[0]; -- the last op.
  7163. }
  7164. __rgs_assert_cbk (graph_iri, uid, 2, 'SPARUL DELETE');
  7165. while (dict_size (triples_dict) > 0)
  7166. {
  7167. triples := dict_destructive_list_rnd_keys (triples_dict, 2000000);
  7168. DB.DBA.RDF_DELETE_TRIPLES_AGG (graph_iri, triples, log_mode);
  7169. del_count := del_count + length (triples);
  7170. }
  7171. if (isiri_id (graph_iri))
  7172. graph_iri := id_to_iri (graph_iri);
  7173. if (graph_iri is not null and __rdf_graph_is_in_enabled_repl (iri_to_id (graph_iri)))
  7174. repl_text ('__rdf_repl', '__rdf_repl_flush_queue ()');
  7175. if (compose_report)
  7176. {
  7177. if (del_count)
  7178. return sprintf ('Delete from <%s>, %d (or less) triples -- done', graph_iri, del_count);
  7179. else
  7180. return sprintf ('Delete from <%s>, 0 triples -- nothing to do', graph_iri);
  7181. }
  7182. else
  7183. return del_count;
  7184. }
  7185. ;
  7186. create function DB.DBA.SPARQL_MODIFY_BY_DICT_CONTENTS (in graph_iri any, in del_triples_dict any, in ins_triples_dict any, in uid integer, in log_mode integer := null, in compose_report integer := 0) returns any
  7187. {
  7188. declare del_count, ins_count integer;
  7189. del_count := 0;
  7190. ins_count := 0;
  7191. if (__tag of vector = __tag (graph_iri))
  7192. {
  7193. del_count := graph_iri[1];
  7194. ins_count := graph_iri[2];
  7195. graph_iri := graph_iri[0]; -- the last op.
  7196. }
  7197. __rgs_assert_cbk (graph_iri, uid, 2, 'SPARUL MODIFY');
  7198. if (del_triples_dict is not null)
  7199. {
  7200. del_count := del_count + dict_size (del_triples_dict);
  7201. DB.DBA.SPARQL_DELETE_DICT_CONTENT (graph_iri, del_triples_dict, uid, log_mode);
  7202. }
  7203. if (ins_triples_dict is not null)
  7204. {
  7205. ins_count := ins_count + dict_size (ins_triples_dict);
  7206. DB.DBA.SPARQL_INSERT_DICT_CONTENT (graph_iri, ins_triples_dict, uid, log_mode);
  7207. }
  7208. if (isiri_id (graph_iri))
  7209. graph_iri := id_to_iri (graph_iri);
  7210. if (graph_iri is not null and __rdf_graph_is_in_enabled_repl (iri_to_id (graph_iri)))
  7211. repl_text ('__rdf_repl', '__rdf_repl_flush_queue ()');
  7212. if (compose_report)
  7213. return sprintf ('Modify <%s>, delete %d (or less) and insert %d (or less) triples -- done', graph_iri, del_count, ins_count);
  7214. else
  7215. return del_count + ins_count;
  7216. }
  7217. ;
  7218. -- /* delete quads */
  7219. create procedure DB.DBA.RDF_REPL_DEL (inout rquads any)
  7220. {
  7221. declare rquads_ctr, rquads_count, opcode integer;
  7222. declare g_iri, prev_g_iri varchar;
  7223. declare g_iid varchar;
  7224. declare ro_id_dict, app_env any;
  7225. rquads_count := length (rquads);
  7226. prev_g_iri := '';
  7227. for (rquads_ctr := 0; rquads_ctr < rquads_count; rquads_ctr := rquads_ctr + 1)
  7228. {
  7229. -- dbg_obj_princ ('DB.DBA.RDF_REPL_DEL(), rquad ', rquads_ctr, ' / ', rquads_count, ': ', rquads[rquads_ctr]);
  7230. g_iri := rquads[rquads_ctr][1];
  7231. if (g_iri <> prev_g_iri)
  7232. {
  7233. g_iid := iri_to_id (g_iri);
  7234. --DB.DBA.TTLP_EV_CL_GS_NEW_GRAPH (g_iri, g_iid, app_env);
  7235. prev_g_iri := g_iri;
  7236. }
  7237. opcode := rquads[rquads_ctr][0];
  7238. if (0 = opcode)
  7239. {
  7240. delete from DB.DBA.RDF_QUAD
  7241. where G = g_iid and S = iri_to_id_repl (rquads[rquads_ctr][2]) and P = iri_to_id_repl (rquads[rquads_ctr][3])
  7242. and O = DB.DBA.RDF_MAKE_OBJ_OF_SQLVAL (rquads[rquads_ctr][4]);
  7243. if (__rdf_graph_is_in_enabled_repl (g_iid))
  7244. __rdf_repl_quad (160 + opcode, g_iri, rquads[rquads_ctr][2], rquads[rquads_ctr][3], rquads[rquads_ctr][4]);
  7245. }
  7246. else if (1 = opcode)
  7247. {
  7248. declare obj any;
  7249. if (isgeometry (rquads[rquads_ctr][4]))
  7250. {
  7251. obj := rdf_box (rquads[rquads_ctr][4], 256, 257, 0, 1);
  7252. rdf_geo_set_id (obj);
  7253. }
  7254. else
  7255. obj := DB.DBA.RDF_MAKE_OBJ_OF_TYPEDSQLVAL (rquads[rquads_ctr][4], iri_to_id_repl (rquads[rquads_ctr][5]), null);
  7256. delete from DB.DBA.RDF_QUAD
  7257. where G = g_iid and S = iri_to_id_repl (rquads[rquads_ctr][2]) and P = iri_to_id_repl (rquads[rquads_ctr][3]) and O = obj;
  7258. if (__rdf_graph_is_in_enabled_repl (g_iid))
  7259. __rdf_repl_quad (160 + opcode, g_iri, rquads[rquads_ctr][2], rquads[rquads_ctr][3], rquads[rquads_ctr][4], rquads[rquads_ctr][5], null);
  7260. }
  7261. else if (2 = opcode)
  7262. {
  7263. delete from DB.DBA.RDF_QUAD
  7264. where G = g_iid and S = iri_to_id_repl (rquads[rquads_ctr][2]) and P = iri_to_id_repl (rquads[rquads_ctr][3])
  7265. and O = DB.DBA.RDF_MAKE_OBJ_OF_TYPEDSQLVAL (rquads[rquads_ctr][4], null, rquads[rquads_ctr][5]);
  7266. if (__rdf_graph_is_in_enabled_repl (g_iid))
  7267. __rdf_repl_quad (160 + opcode, g_iri, rquads[rquads_ctr][2], rquads[rquads_ctr][3], rquads[rquads_ctr][4], null, rquads[rquads_ctr][5]);
  7268. }
  7269. else if (4 = opcode)
  7270. {
  7271. delete from DB.DBA.RDF_QUAD
  7272. where G = g_iid and S = iri_to_id_repl (rquads[rquads_ctr][2]) and P = iri_to_id_repl (rquads[rquads_ctr][3])
  7273. and O = iri_to_id_repl (rquads[rquads_ctr][4]);
  7274. if (__rdf_graph_is_in_enabled_repl (g_iid))
  7275. __rdf_repl_quad (160 + opcode, g_iri, rquads[rquads_ctr][2], rquads[rquads_ctr][3], rquads[rquads_ctr][4]);
  7276. }
  7277. }
  7278. app_env := vector (1, null);
  7279. DB.DBA.TTLP_EV_COMMIT (g_iri, app_env);
  7280. --if (1 <> sys_stat ('cl_run_local_only'))
  7281. -- rdf_dpipe_flush_gs (app_env, 1);
  7282. connection_set ('g_dict', null);
  7283. commit work;
  7284. }
  7285. ;
  7286. --#IF VER=5
  7287. --!AFTER
  7288. --#ENDIF
  7289. create function DB.DBA.SPARUL_CLEAR (in graph_iris any, in inside_sponge integer, in uid integer := 0, in log_mode integer := null, in compose_report integer := 0, in options any := null, in silent integer := 0) returns any
  7290. {
  7291. declare g_iid IRI_ID;
  7292. declare old_log_enable integer;
  7293. declare txtreport varchar;
  7294. txtreport := '';
  7295. if (__tag of vector <> __tag (graph_iris))
  7296. graph_iris := vector (graph_iris);
  7297. foreach (any g_iri in graph_iris) do
  7298. {
  7299. if (isiri_id (g_iri))
  7300. g_iri := id_to_iri (g_iri);
  7301. g_iid := iri_to_id (g_iri);
  7302. __rgs_assert_cbk (g_iri, uid, 2, 'SPARUL CLEAR GRAPH');
  7303. }
  7304. foreach (any g_iri in graph_iris) do
  7305. {
  7306. if (isiri_id (g_iri))
  7307. g_iri := id_to_iri (g_iri);
  7308. g_iid := iri_to_id (g_iri);
  7309. if (__rdf_graph_is_in_enabled_repl (g_iid))
  7310. {
  7311. repl_text ('__rdf_repl', '__rdf_repl_flush_queue()');
  7312. repl_text ('__rdf_repl', 'sparql define input:storage "" clear graph iri ( ?? )', g_iri);
  7313. }
  7314. old_log_enable := log_enable (log_mode, 1);
  7315. declare exit handler for sqlstate '*' { log_enable (old_log_enable, 1); resignal; };
  7316. exec (sprintf ('
  7317. delete from DB.DBA.RDF_QUAD
  7318. where G = __i2id (''%S'') ', g_iri));
  7319. delete from DB.DBA.RDF_QUAD table option (index RDF_QUAD_GS, index_only) where G = iri_to_id (g_iri, 0) option (index_only, index RDF_QUAD_GS);
  7320. delete from DB.DBA.RDF_OBJ_RO_FLAGS_WORDS where VT_WORD = rdf_graph_keyword (g_iid);
  7321. if (not inside_sponge)
  7322. {
  7323. delete from DB.DBA.SYS_HTTP_SPONGE where HS_LOCAL_IRI = g_iri;
  7324. delete from DB.DBA.SYS_HTTP_SPONGE where HS_LOCAL_IRI like concat ('destMD5=', md5 (g_iri), '&graphMD5=%');
  7325. }
  7326. if (compose_report)
  7327. {
  7328. if (txtreport <> '')
  7329. txtreport := txtreport || '\n';
  7330. txtreport := txtreport || sprintf ('Clear graph <%s> -- done', g_iri);
  7331. }
  7332. }
  7333. /*091202 commit work; */
  7334. log_enable (old_log_enable, 1);
  7335. if (compose_report)
  7336. return txtreport;
  7337. return 1;
  7338. }
  7339. ;
  7340. create function DB.DBA.SPARUL_LOAD (in graph_iri any, in resource varchar, in uid integer, in log_mode integer, in compose_report integer, in options any := null, in silent integer := 0) returns any
  7341. {
  7342. declare old_log_enable integer;
  7343. declare grab_params any;
  7344. declare grabbed any;
  7345. declare res integer;
  7346. __rgs_assert_cbk (graph_iri, uid, 2, 'SPARUL LOAD');
  7347. old_log_enable := log_enable (log_mode, 1);
  7348. declare exit handler for sqlstate '*' { log_enable (old_log_enable, 1); if (silent) goto fail; resignal; };
  7349. grabbed := dict_new();
  7350. if (isiri_id (graph_iri))
  7351. graph_iri := id_to_iri (graph_iri);
  7352. grab_params := vector_concat (vector (
  7353. 'base_iri', resource,
  7354. 'get:destination', graph_iri,
  7355. 'get:soft', get_keyword ('get:soft', options, 'replacing'),
  7356. 'get:refresh', get_keyword ('get:refresh', options, -1),
  7357. 'get:error-recovery', get_keyword ('get:error-recovery', options, 'signal'),
  7358. -- 'flags', flags,
  7359. 'get:strategy', get_keyword ('get:strategy', options, 'rdfa-only'),
  7360. 'get:private', get_keyword ('get:private', options, null),
  7361. 'grabbed', grabbed ),
  7362. options );
  7363. commit work;
  7364. res := DB.DBA.RDF_GRAB_SINGLE (resource, grabbed, grab_params);
  7365. commit work;
  7366. log_enable (old_log_enable, 1);
  7367. if (res)
  7368. {
  7369. if (compose_report)
  7370. return sprintf ('Load <%s> into graph <%s> -- done', resource, graph_iri);
  7371. else
  7372. return 1;
  7373. }
  7374. else
  7375. {
  7376. if (compose_report)
  7377. return sprintf ('Load <%s> into graph <%s> -- failed', resource, graph_iri);
  7378. else
  7379. return 0;
  7380. }
  7381. fail:
  7382. if (compose_report)
  7383. return sprintf ('Load silent <%s> into graph <%s> -- failed: %s: %s', resource, graph_iri, __SQL_STATE, __SQL_MESSAGE);
  7384. else
  7385. return 0;
  7386. }
  7387. ;
  7388. create function DB.DBA.SPARUL_LOAD_SERVICE_DATA (in service_iri any, in proxy_iri varchar, in uid integer, in log_mode integer, in compose_report integer, in options any := null, in silent integer := 0) returns any
  7389. {
  7390. declare old_log_enable integer;
  7391. declare mdta, rows any;
  7392. declare stat, msg varchar;
  7393. __rgs_assert_cbk (service_iri, uid, 2, 'SPARUL LOAD SERVICE DATA');
  7394. -- dbg_obj_princ ('DB.DBA.SPARUL_LOAD_SERVICE_DATA (', service_iri, proxy_iri, uid, log_mode, compose_report, options, silent, ')');
  7395. old_log_enable := log_enable (log_mode, 1);
  7396. stat := '00000';
  7397. exec ('DB.DBA.SPARQL_SD_PROBE (?, ?, 0, 0)', stat, msg, vector (service_iri, proxy_iri), 10000, mdta, rows);
  7398. log_enable (old_log_enable, 1);
  7399. if (stat <> '00000')
  7400. {
  7401. if (not silent) signal (stat, msg);
  7402. if (compose_report)
  7403. return sprintf ('Load service <%s> data failed: %s: %s', service_iri, stat, msg);
  7404. else
  7405. return 0;
  7406. }
  7407. if (compose_report)
  7408. {
  7409. if (length (rows))
  7410. return sprintf ('Load service <%s> data -- done. %s', service_iri, rows[length(rows)-1][1]);
  7411. else
  7412. return sprintf ('Load service <%s> data -- nothing done', service_iri);
  7413. }
  7414. else
  7415. return 1;
  7416. }
  7417. ;
  7418. create function DB.DBA.SPARUL_CREATE (in graph_iri any, in silent1 integer, in uid integer, in log_mode integer, in compose_report integer, in options any := null, in silent integer := 0) returns any
  7419. {
  7420. declare g_iid IRI_ID;
  7421. declare old_log_enable integer;
  7422. __rgs_assert_cbk (graph_iri, uid, 2, 'SPARUL CREATE GRAPH');
  7423. g_iid := iri_to_id (graph_iri);
  7424. if (__rdf_graph_is_in_enabled_repl (g_iid))
  7425. repl_text ('__rdf_repl', 'sparql define input:storage "" create graph iri ( ?? )', graph_iri);
  7426. if ((silent1 is not null) and silent1)
  7427. silent := 1;
  7428. if (exists (select top 1 1 from DB.DBA.RDF_EXPLICITLY_CREATED_GRAPH where REC_GRAPH_IID = g_iid))
  7429. {
  7430. if (silent)
  7431. {
  7432. if (compose_report)
  7433. return sprintf ('Create silent graph <%s> -- already exists', graph_iri);
  7434. else
  7435. return 0;
  7436. }
  7437. else
  7438. signal ('22023', 'SPARUL_CREATE() failed: graph <' || graph_iri || '> has been explicitly created before');
  7439. }
  7440. if (silent)
  7441. {
  7442. old_log_enable := log_enable (log_mode, 1);
  7443. declare exit handler for sqlstate '*' { log_enable (old_log_enable, 1); resignal; };
  7444. insert soft DB.DBA.RDF_EXPLICITLY_CREATED_GRAPH (REC_GRAPH_IID) values (iri_to_id (graph_iri));
  7445. /*091202 commit work; */
  7446. log_enable (old_log_enable, 1);
  7447. if (compose_report)
  7448. return sprintf ('Create silent graph <%s> -- done', graph_iri);
  7449. else
  7450. return 1;
  7451. }
  7452. if (exists (select top 1 1 from DB.DBA.RDF_QUAD where G = iri_to_id (graph_iri)))
  7453. signal ('22023', 'SPARUL_CREATE() failed: graph <' || graph_iri || '> contains triples already');
  7454. if (exists (sparql define input:storage ""
  7455. ask from <http://www.openlinksw.com/schemas/virtrdf#>
  7456. where { ?qmv virtrdf:qmGraphRange-rvrFixedValue `iri(?:graph_iri)` } ) )
  7457. signal ('22023', 'SPARUL_CREATE() failed: graph <' || graph_iri || '> is used for mapping relational data to RDF');
  7458. old_log_enable := log_enable (log_mode, 1);
  7459. declare exit handler for sqlstate '*' { log_enable (old_log_enable, 1); resignal; };
  7460. insert soft DB.DBA.RDF_EXPLICITLY_CREATED_GRAPH (REC_GRAPH_IID) values (iri_to_id (graph_iri));
  7461. /*091202 commit work; */
  7462. log_enable (old_log_enable, 1);
  7463. if (compose_report)
  7464. return sprintf ('Create graph <%s> -- done', graph_iri);
  7465. else
  7466. return 1;
  7467. }
  7468. ;
  7469. create function DB.DBA.SPARUL_DROP (in graph_iris any, in silent1 integer, in uid integer, in log_mode integer, in compose_report integer, in options any := null, in silent integer := 0) returns any
  7470. {
  7471. declare g_iid IRI_ID;
  7472. declare old_log_enable integer;
  7473. declare txtreport varchar;
  7474. txtreport := '';
  7475. if ((silent1 is not null) and silent1)
  7476. silent := 1;
  7477. if (__tag of vector <> __tag (graph_iris))
  7478. graph_iris := vector (graph_iris);
  7479. foreach (any g_iri in graph_iris) do
  7480. {
  7481. if (isiri_id (g_iri))
  7482. g_iri := id_to_iri (g_iri);
  7483. g_iid := iri_to_id (g_iri);
  7484. __rgs_assert_cbk (g_iri, uid, 2, 'SPARUL DROP GRAPH');
  7485. }
  7486. foreach (any g_iri in graph_iris) do
  7487. {
  7488. if (isiri_id (g_iri))
  7489. g_iri := id_to_iri (g_iri);
  7490. g_iid := iri_to_id (g_iri);
  7491. if (__rdf_graph_is_in_enabled_repl (g_iid))
  7492. {
  7493. repl_text ('__rdf_repl', '__rdf_repl_flush_queue()');
  7494. repl_text ('__rdf_repl', 'sparql define input:storage "" drop graph iri ( ?? )', g_iri);
  7495. }
  7496. old_log_enable := log_enable (log_mode, 1);
  7497. declare exit handler for sqlstate '*' { log_enable (old_log_enable, 1); resignal; };
  7498. if (not exists (select top 1 1 from DB.DBA.RDF_EXPLICITLY_CREATED_GRAPH where REC_GRAPH_IID = g_iid))
  7499. {
  7500. if (silent)
  7501. {
  7502. if (exists (select top 1 1 from DB.DBA.RDF_QUAD where G = g_iid))
  7503. {
  7504. DB.DBA.SPARUL_CLEAR (g_iri, 0, uid);
  7505. log_enable (old_log_enable, 1);
  7506. if (compose_report)
  7507. return sprintf ('Drop silent graph <%s> -- graph has not been explicitly created before, triples were removed', g_iri);
  7508. else
  7509. return 2;
  7510. }
  7511. if (compose_report)
  7512. return sprintf ('Drop silent graph <%s> -- nothing to do', g_iri);
  7513. else
  7514. return 0;
  7515. }
  7516. else
  7517. signal ('22023', 'SPARUL_DROP() failed: graph <' || g_iri || '> has not been explicitly created before');
  7518. }
  7519. if (silent)
  7520. {
  7521. DB.DBA.SPARUL_CLEAR (g_iri, 0, uid);
  7522. delete from DB.DBA.RDF_EXPLICITLY_CREATED_GRAPH where REC_GRAPH_IID = g_iid;
  7523. /*091202 commit work; */
  7524. log_enable (old_log_enable, 1);
  7525. if (compose_report)
  7526. return sprintf ('Drop silent graph <%s> -- done', g_iri);
  7527. else
  7528. return 1;
  7529. }
  7530. if (exists (sparql define input:storage ""
  7531. ask from <http://www.openlinksw.com/schemas/virtrdf#>
  7532. where { ?qmv virtrdf:qmGraphRange-rvrFixedValue `iri(?:g_iri)` } ) )
  7533. signal ('22023', 'SPARUL_DROP() failed: graph <' || g_iri || '> is used for mapping relational data to RDF');
  7534. DB.DBA.SPARUL_CLEAR (g_iri, 0, uid);
  7535. delete from DB.DBA.RDF_EXPLICITLY_CREATED_GRAPH where REC_GRAPH_IID = g_iid;
  7536. if (compose_report)
  7537. {
  7538. if (txtreport <> '')
  7539. txtreport := txtreport || '\n';
  7540. txtreport := txtreport || sprintf ('Drop graph <%s> -- done', g_iri);
  7541. }
  7542. }
  7543. log_enable (old_log_enable, 1);
  7544. /*091202 commit work; */
  7545. if (compose_report)
  7546. return txtreport;
  7547. return 1;
  7548. }
  7549. ;
  7550. create function DB.DBA.SPARUL_RUN (in results any, in compose_report integer := 0) returns any
  7551. {
  7552. --commit work;
  7553. if (compose_report)
  7554. {
  7555. declare ses any;
  7556. ses := string_output ();
  7557. foreach (varchar r in results) do
  7558. {
  7559. http (cast (r as varchar) || '\n', ses);
  7560. }
  7561. http ('Commit -- done\n', ses);
  7562. return string_output_string (ses);
  7563. }
  7564. else
  7565. {
  7566. declare res integer;
  7567. res := 0;
  7568. foreach (integer c in results) do
  7569. {
  7570. res := res + c;
  7571. }
  7572. return res;
  7573. }
  7574. }
  7575. ;
  7576. -- SPARQL 1.1 BINDINGS
  7577. --!AWK PUBLIC
  7578. create procedure DB.DBA.SPARQL_BINDINGS_VIEW_IMP (in dta any)
  7579. {
  7580. declare rcount, rctr integer;
  7581. declare BND any;
  7582. result_names (BND);
  7583. rcount := length (dta);
  7584. for (rctr := 0; rctr < rcount; rctr := rctr+1)
  7585. result (dta[rctr]);
  7586. }
  7587. ;
  7588. create procedure view DB.DBA.SPARQL_BINDINGS_VIEW as DB.DBA.SPARQL_BINDINGS_VIEW_IMP (dta) (BND any)
  7589. ;
  7590. grant select on DB.DBA.SPARQL_BINDINGS_VIEW to public
  7591. ;
  7592. --!AWK PUBLIC
  7593. create procedure DB.DBA.SPARQL_BINDINGS_VIEW_C1_IMP (in dta any)
  7594. {
  7595. declare rcount, rctr integer;
  7596. declare BND0 any;
  7597. result_names (BND0);
  7598. rcount := length (dta);
  7599. for (rctr := 0; rctr < rcount; rctr := rctr+1)
  7600. result (dta[rctr][0]);
  7601. }
  7602. ;
  7603. --!AWK PUBLIC
  7604. create procedure DB.DBA.SPARQL_BINDINGS_VIEW_C2_IMP (in dta any)
  7605. {
  7606. declare rcount, rctr integer;
  7607. declare BND0, BND1 any;
  7608. result_names (BND0, BND1);
  7609. rcount := length (dta);
  7610. for (rctr := 0; rctr < rcount; rctr := rctr+1)
  7611. result (dta[rctr][0], dta[rctr][1]);
  7612. }
  7613. ;
  7614. --!AWK PUBLIC
  7615. create procedure DB.DBA.SPARQL_BINDINGS_VIEW_C3_IMP (in dta any)
  7616. {
  7617. declare rcount, rctr integer;
  7618. declare BND0, BND1, BND2 any;
  7619. result_names (BND0, BND1, BND2);
  7620. rcount := length (dta);
  7621. for (rctr := 0; rctr < rcount; rctr := rctr+1)
  7622. result (dta[rctr][0], dta[rctr][1], dta[rctr][2]);
  7623. }
  7624. ;
  7625. --!AWK PUBLIC
  7626. create procedure DB.DBA.SPARQL_BINDINGS_VIEW_C4_IMP (in dta any)
  7627. {
  7628. declare rcount, rctr integer;
  7629. declare BND0, BND1, BND2, BND3 any;
  7630. result_names (BND0, BND1, BND2, BND3);
  7631. rcount := length (dta);
  7632. for (rctr := 0; rctr < rcount; rctr := rctr+1)
  7633. result (dta[rctr][0], dta[rctr][1], dta[rctr][2], dta[rctr][3]);
  7634. }
  7635. ;
  7636. create procedure view DB.DBA.SPARQL_BINDINGS_VIEW_C1 as DB.DBA.SPARQL_BINDINGS_VIEW_C1_IMP (dta) (BND0 any)
  7637. ;
  7638. create procedure view DB.DBA.SPARQL_BINDINGS_VIEW_C2 as DB.DBA.SPARQL_BINDINGS_VIEW_C1_IMP (dta) (BND0 any, BND1 any)
  7639. ;
  7640. create procedure view DB.DBA.SPARQL_BINDINGS_VIEW_C3 as DB.DBA.SPARQL_BINDINGS_VIEW_C1_IMP (dta) (BND0 any, BND1 any, BND2 any)
  7641. ;
  7642. create procedure view DB.DBA.SPARQL_BINDINGS_VIEW_C4 as DB.DBA.SPARQL_BINDINGS_VIEW_C1_IMP (dta) (BND0 any, BND1 any, BND2 any, BND3 any)
  7643. ;
  7644. grant select on DB.DBA.SPARQL_BINDINGS_VIEW_C1 to public
  7645. ;
  7646. grant select on DB.DBA.SPARQL_BINDINGS_VIEW_C2 to public
  7647. ;
  7648. grant select on DB.DBA.SPARQL_BINDINGS_VIEW_C3 to public
  7649. ;
  7650. grant select on DB.DBA.SPARQL_BINDINGS_VIEW_C4 to public
  7651. ;
  7652. -- SPARQL 1.1 UPDATE functions
  7653. create procedure DB.DBA.RDF_INSERT_QUADS (in dflt_graph_iri any, inout quads any, in uid integer, in log_mode integer := null) returns any
  7654. {
  7655. declare groups any;
  7656. declare group_ctr, group_count integer;
  7657. declare qtst, all_sv, all_pv, all_ov, all_gv, repl_sv, repl_pv, repl_ov, repl_gv any;
  7658. qtst := quads;
  7659. __rgs_prepare_del_or_ins (qtst, uid, dflt_graph_iri, all_sv, all_pv, all_ov, all_gv, repl_sv, repl_pv, repl_ov, repl_gv);
  7660. rowvector_graph_sort (quads, 3, 1);
  7661. groups := rowvector_graph_partition (quads, 3);
  7662. group_count := length (groups);
  7663. for (group_ctr := 0; group_ctr < group_count; group_ctr := group_ctr+1)
  7664. {
  7665. declare g_group, g any;
  7666. g_group := aref_set_0 (groups, group_ctr);
  7667. g := aref_or_default (g_group, 0, 3, dflt_graph_iri);
  7668. __rgs_assert_cbk (g, uid, 2, 'SPARQL 1.1 INSERT');
  7669. DB.DBA.RDF_INSERT_TRIPLES (g, g_group, log_mode);
  7670. if (isiri_id (g))
  7671. g := id_to_iri (g);
  7672. if (g is not null and __rdf_graph_is_in_enabled_repl (iri_to_id (g)))
  7673. repl_text ('__rdf_repl', '__rdf_repl_flush_queue ()');
  7674. }
  7675. }
  7676. ;
  7677. create function DB.DBA.RDF_DELETE_QUADS (in dflt_graph_iri any, inout quads any, in uid integer, in log_mode integer := null) returns any
  7678. {
  7679. declare groups any;
  7680. declare group_ctr, group_count integer;
  7681. declare old_log_enable integer;
  7682. old_log_enable := log_enable (log_mode, 1);
  7683. declare exit handler for sqlstate '*' { log_enable (old_log_enable, 1); resignal; };
  7684. declare repl_quads any array;
  7685. declare all_sv, all_pv, all_ov, all_gv, repl_sv, repl_pv, repl_ov, repl_gv any;
  7686. -- dbg_obj_princ ('__rgs_prepare_del_or_ins (', quads, uid, dflt_graph_iri, ') formed the following:');
  7687. __rgs_prepare_del_or_ins (quads, uid, dflt_graph_iri, all_sv, all_pv, all_ov, all_gv, repl_sv, repl_pv, repl_ov, repl_gv);
  7688. for vectored (in a_s any array := all_sv, in a_p any array := all_pv, in a_o any array := all_ov, in a_g any array := all_gv)
  7689. {
  7690. declare o_val any array;
  7691. declare o_dt_and_lang_twobyte integer;
  7692. if (not isinteger (a_g))
  7693. {
  7694. if (not isiri_id (a_s))
  7695. a_s := __i2idn (a_s);
  7696. if (not isiri_id (a_p))
  7697. a_p := __i2idn (a_p);
  7698. if (isiri_id (a_s) and isiri_id (a_p))
  7699. {
  7700. if (isiri_id (a_o))
  7701. delete from DB.DBA.RDF_QUAD where G = a_g and S = a_s and P = a_p and O = a_o;
  7702. else
  7703. {
  7704. declare o_val any array;
  7705. declare o_dt_and_lang_twobyte integer;
  7706. declare search_fields_are_ok integer;
  7707. search_fields_are_ok := __rdf_box_to_ro_id_search_fields (a_o, o_val, o_dt_and_lang_twobyte);
  7708. -- dbg_obj_princ ('__rdf_box_to_ro_id_search_fields (', a_o, ') returned ', search_fields_are_ok, o_val, o_dt_and_lang_twobyte);
  7709. if (search_fields_are_ok)
  7710. delete from DB.DBA.RDF_QUAD where G = a_g and S = a_s and P = a_p and O = (select rdf_box_from_ro_id(RO_ID) from DB.DBA.RDF_OBJ where RO_VAL = o_val and RO_DT_AND_LANG = o_dt_and_lang_twobyte);
  7711. else if (isstring (a_o)) /* it should be string IRI otherwise it's in RDF_OBJ */
  7712. delete from DB.DBA.RDF_QUAD where G = a_g and S = a_s and P = a_p and O = iri_to_id (a_o);
  7713. else
  7714. delete from DB.DBA.RDF_QUAD where G = a_g and S = a_s and P = a_p and O = a_o;
  7715. }
  7716. }
  7717. }
  7718. }
  7719. if (0 < length (repl_sv))
  7720. {
  7721. for vectored (in r_s any array := repl_sv, in r_p any array := repl_pv, in r_o any array := repl_ov, in r_g any array := repl_gv, out repl_quads := r_q)
  7722. {
  7723. declare r_q, r_o any array;
  7724. declare r_g_iri, r_s_iri, r_p_iri varchar;
  7725. r_g_iri := iri_canonicalize (__id2in (r_q[3]));
  7726. r_s_iri := iri_canonicalize (__id2in (r_q[0]));
  7727. r_p_iri := iri_canonicalize (__id2in (r_q[1]));
  7728. r_o := r_q[2];
  7729. if (isiri_id (r_o) or (__tag (r_o) = 217) or ((__tag (r_o) = __tag of varchar) and bit_and (1, __box_flags (r_o))))
  7730. r_q := vector (r_g_iri, r_s_iri, r_p_iri, iri_canonicalize (__id2in (r_o)));
  7731. else
  7732. r_q := vector (r_g_iri, r_s_iri, r_p_iri, __ro2sq (r_o));
  7733. }
  7734. repl_text ('__rdf_repl', 'DB.DBA.RDF_REPL_DELETE_QUADS (?)', repl_quads);
  7735. }
  7736. log_enable (old_log_enable, 1);
  7737. }
  7738. ;
  7739. create function DB.DBA.SPARQL_INSERT_QUAD_DICT_CONTENT (in dflt_graph_iri any, in quads_dict any, in uid integer, in log_mode integer := null, in compose_report integer := 0) returns any
  7740. {
  7741. declare ins_count, ins_grp_count integer;
  7742. declare res_ses any;
  7743. ins_count := 0;
  7744. ins_grp_count := 0;
  7745. if (__tag of vector = __tag (dflt_graph_iri))
  7746. {
  7747. ins_count := dflt_graph_iri[2]; -- 2, not 1
  7748. dflt_graph_iri := dflt_graph_iri[0]; -- the last op.
  7749. }
  7750. while (dict_size (quads_dict) > 0)
  7751. {
  7752. declare quads, groups any;
  7753. declare group_ctr, group_count, g_ins_count integer;
  7754. quads := dict_destructive_list_rnd_keys (quads_dict, 80000);
  7755. declare qtst, all_sv, all_pv, all_ov, all_gv, repl_sv, repl_pv, repl_ov, repl_gv any;
  7756. qtst := quads;
  7757. -- dbg_obj_princ ('__rgs_prepare_del_or_ins (', qtst, uid, dflt_graph_iri, ') formed the following:');
  7758. __rgs_prepare_del_or_ins (qtst, uid, dflt_graph_iri, all_sv, all_pv, all_ov, all_gv, repl_sv, repl_pv, repl_ov, repl_gv);
  7759. -- dbg_obj_princ ('All items:');
  7760. --for vectored (in a_s any array := all_sv, in a_p any array := all_pv, in a_o any array := all_ov, in a_g any array := all_gv) {
  7761. -- dbg_obj_princ (a_s, a_p, a_o, a_g);
  7762. --}
  7763. -- dbg_obj_princ ('Replication items:');
  7764. --for vectored (in r_s any array := repl_sv, in r_p any array := repl_pv, in r_o any array := repl_ov, in r_g any array := repl_gv) {
  7765. -- dbg_obj_princ (r_s, r_p, r_o, r_g);
  7766. --}
  7767. rowvector_graph_sort (quads, 3, 1);
  7768. groups := rowvector_graph_partition (quads, 3);
  7769. group_count := length (groups);
  7770. for (group_ctr := 0; group_ctr < group_count; group_ctr := group_ctr+1)
  7771. {
  7772. declare g_group, g any;
  7773. g_group := aref_set_0 (groups, group_ctr);
  7774. g := aref_or_default (g_group, 0, 3, dflt_graph_iri);
  7775. __rgs_assert_cbk (g, uid, 2, 'SPARQL 1.1 INSERT');
  7776. DB.DBA.RDF_INSERT_TRIPLES (g, g_group, log_mode);
  7777. g_ins_count := length (g_group);
  7778. ins_count := ins_count + g_ins_count;
  7779. ins_grp_count := ins_grp_count + 1;
  7780. if (isiri_id (g))
  7781. g := id_to_iri (g);
  7782. if (g is not null and __rdf_graph_is_in_enabled_repl (iri_to_id (g)))
  7783. repl_text ('__rdf_repl', '__rdf_repl_flush_queue ()');
  7784. if (compose_report and ins_grp_count < 1000)
  7785. {
  7786. if (group_ctr)
  7787. http ('\n', res_ses);
  7788. else
  7789. res_ses := string_output();
  7790. http (sprintf ('Insert into <%s>, %d (or less) quads -- done', g, g_ins_count), res_ses);
  7791. }
  7792. }
  7793. }
  7794. if (compose_report)
  7795. {
  7796. if (ins_grp_count >= 1000)
  7797. return sprintf ('Insert into %d (or more) graphs, total %d (or less) quads -- done', ins_grp_count, ins_count);
  7798. if (ins_count)
  7799. return string_output_string (res_ses);
  7800. else
  7801. return sprintf ('Insert into <%s>, 0 quads -- nothing to do', dflt_graph_iri);
  7802. }
  7803. else
  7804. return ins_count;
  7805. }
  7806. ;
  7807. create function DB.DBA.SPARQL_DELETE_QUAD_DICT_CONTENT (in dflt_graph_iri any, in quads_dict any, in uid integer, in log_mode integer := null, in compose_report integer := 0) returns any
  7808. {
  7809. declare del_count, del_grp_count integer;
  7810. declare res_ses any;
  7811. del_count := 0;
  7812. declare old_log_enable integer;
  7813. old_log_enable := log_enable (log_mode, 1);
  7814. declare exit handler for sqlstate '*' { log_enable (old_log_enable, 1); resignal; };
  7815. if (__tag of vector = __tag (dflt_graph_iri))
  7816. {
  7817. del_count := dflt_graph_iri[1]; -- 1 for del count
  7818. dflt_graph_iri := dflt_graph_iri[0]; -- the last op.
  7819. }
  7820. while (dict_size (quads_dict) > 0)
  7821. {
  7822. declare quads, groups any;
  7823. declare group_ctr, group_count, g_del_count integer;
  7824. declare repl_quads any array;
  7825. quads := dict_destructive_list_rnd_keys (quads_dict, 80000);
  7826. declare all_sv, all_pv, all_ov, all_gv, repl_sv, repl_pv, repl_ov, repl_gv any;
  7827. -- dbg_obj_princ ('__rgs_prepare_del_or_ins (', quads, uid, dflt_graph_iri, ') formed the following:');
  7828. __rgs_prepare_del_or_ins (quads, uid, dflt_graph_iri, all_sv, all_pv, all_ov, all_gv, repl_sv, repl_pv, repl_ov, repl_gv);
  7829. for vectored (in a_s any array := all_sv, in a_p any array := all_pv, in a_o any array := all_ov, in a_g any array := all_gv)
  7830. {
  7831. declare o_val any array;
  7832. declare o_dt_and_lang_twobyte integer;
  7833. if (not isinteger (a_g))
  7834. {
  7835. if (not isiri_id (a_s))
  7836. a_s := __i2idn (a_s);
  7837. if (not isiri_id (a_p))
  7838. a_p := __i2idn (a_p);
  7839. if (isiri_id (a_s) and isiri_id (a_p))
  7840. {
  7841. if (isiri_id (a_o))
  7842. delete from DB.DBA.RDF_QUAD where G = a_g and S = a_s and P = a_p and O = a_o;
  7843. else
  7844. {
  7845. declare o_val any array;
  7846. declare o_dt_and_lang_twobyte integer;
  7847. declare search_fields_are_ok integer;
  7848. search_fields_are_ok := __rdf_box_to_ro_id_search_fields (a_o, o_val, o_dt_and_lang_twobyte);
  7849. -- dbg_obj_princ ('__rdf_box_to_ro_id_search_fields (', a_o, ') returned ', search_fields_are_ok, o_val, o_dt_and_lang_twobyte);
  7850. if (search_fields_are_ok)
  7851. delete from DB.DBA.RDF_QUAD where G = a_g and S = a_s and P = a_p and O = (select rdf_box_from_ro_id(RO_ID) from DB.DBA.RDF_OBJ where RO_VAL = o_val and RO_DT_AND_LANG = o_dt_and_lang_twobyte);
  7852. else if (isstring (a_o)) /* it should be string IRI otherwise it's in RDF_OBJ */
  7853. delete from DB.DBA.RDF_QUAD where G = a_g and S = a_s and P = a_p and O = iri_to_id (a_o);
  7854. else
  7855. delete from DB.DBA.RDF_QUAD where G = a_g and S = a_s and P = a_p and O = a_o;
  7856. }
  7857. }
  7858. }
  7859. }
  7860. if (0 < length (repl_sv))
  7861. {
  7862. for vectored (in r_s any array := repl_sv, in r_p any array := repl_pv, in r_o any array := repl_ov, in r_g any array := repl_gv, out repl_quads := r_q)
  7863. {
  7864. declare r_q, r_o any array;
  7865. declare r_g_iri, r_s_iri, r_p_iri varchar;
  7866. r_g_iri := iri_canonicalize (__id2in (r_q[3]));
  7867. r_s_iri := iri_canonicalize (__id2in (r_q[0]));
  7868. r_p_iri := iri_canonicalize (__id2in (r_q[1]));
  7869. r_o := r_q[2];
  7870. if (isiri_id (r_o) or (__tag (r_o) = 217) or ((__tag (r_o) = __tag of varchar) and bit_and (1, __box_flags (r_o))))
  7871. r_q := vector (r_g_iri, r_s_iri, r_p_iri, iri_canonicalize (__id2in (r_o)));
  7872. else
  7873. r_q := vector (r_g_iri, r_s_iri, r_p_iri, __ro2sq (r_o));
  7874. }
  7875. repl_text ('__rdf_repl', 'DB.DBA.RDF_REPL_DELETE_QUADS (?)', repl_quads);
  7876. }
  7877. del_count := del_count + length (quads);
  7878. }
  7879. log_enable (old_log_enable, 1);
  7880. if (compose_report)
  7881. {
  7882. if (del_count)
  7883. return sprintf ('Delete %d (or less) quads -- done', del_count);
  7884. else
  7885. return sprintf ('Delete from <%s>, 0 quads -- nothing to do', dflt_graph_iri);
  7886. }
  7887. else
  7888. return del_count;
  7889. }
  7890. ;
  7891. create function DB.DBA.SPARQL_MODIFY_BY_QUAD_DICT_CONTENTS (in dflt_graph_iri any, in del_quads_dict any, in ins_quads_dict any, in uid integer, in log_mode integer := null, in compose_report integer := 0) returns any
  7892. {
  7893. declare del_count, ins_count integer;
  7894. declare del_rep, ins_rep any;
  7895. del_count := 0;
  7896. ins_count := 0;
  7897. if (__tag of vector = __tag (dflt_graph_iri))
  7898. {
  7899. del_count := dflt_graph_iri[1];
  7900. ins_count := dflt_graph_iri[2];
  7901. dflt_graph_iri := dflt_graph_iri[0]; -- the last op.
  7902. }
  7903. if (del_quads_dict is not null)
  7904. {
  7905. del_count := del_count + dict_size (del_quads_dict);
  7906. del_rep := DB.DBA.SPARQL_DELETE_QUAD_DICT_CONTENT (dflt_graph_iri, del_quads_dict, uid, log_mode, compose_report);
  7907. }
  7908. else if (compose_report)
  7909. del_rep := '';
  7910. else
  7911. del_rep := 0;
  7912. if (ins_quads_dict is not null)
  7913. {
  7914. ins_count := ins_count + dict_size (ins_quads_dict);
  7915. ins_rep := DB.DBA.SPARQL_INSERT_QUAD_DICT_CONTENT (dflt_graph_iri, ins_quads_dict, uid, log_mode, compose_report);
  7916. }
  7917. else if (compose_report)
  7918. ins_rep := '';
  7919. else
  7920. ins_rep := 0;
  7921. if (compose_report)
  7922. return concat (del_rep, case when ins_rep <> '' and del_rep <> '' then '\n' else '' end, ins_rep);
  7923. else
  7924. return del_count + ins_count;
  7925. }
  7926. ;
  7927. create function DB.DBA.SPARUL_COPYMOVEADD_IMPL (in opname varchar, in src_g_iri any, in tgt_g_iri any, in uid integer := 0, in log_mode integer := null, in compose_report integer := 0, in options any := null, in silent integer := 0) returns any
  7928. {
  7929. declare src_g_iid IRI_ID;
  7930. declare tgt_g_iid IRI_ID;
  7931. declare old_log_enable, src_repl, tgt_repl integer;
  7932. declare qry, stat, msg varchar;
  7933. if (isiri_id (src_g_iri))
  7934. src_g_iri := id_to_iri (src_g_iri);
  7935. src_g_iid := iri_to_id (src_g_iri);
  7936. if (isiri_id (tgt_g_iri))
  7937. tgt_g_iri := id_to_iri (tgt_g_iri);
  7938. tgt_g_iid := iri_to_id (tgt_g_iri);
  7939. __rgs_assert_cbk (tgt_g_iri, uid, 2, 'SPARQL 1.1 ' || opname);
  7940. __rgs_assert_cbk (src_g_iri, uid, case (opname) when 'MOVE' then 2 else 1 end, 'SPARQL 1.1 ' || opname);
  7941. if (src_g_iid = tgt_g_iid)
  7942. {
  7943. if (compose_report)
  7944. return sprintf ('%s <%s> to itself -- nothing to do', opname, src_g_iri);
  7945. return 1;
  7946. }
  7947. src_repl := __rdf_graph_is_in_enabled_repl (src_g_iid);
  7948. tgt_repl := __rdf_graph_is_in_enabled_repl (tgt_g_iid);
  7949. if (src_repl and not tgt_repl)
  7950. signal ('22023', sprintf ('SPARQL 1.1 can not %s replicated graph <%s> to non-replicated graph <%s>, both should be in same replication status', src_g_iri, tgt_g_iri));
  7951. if (tgt_repl and not src_repl)
  7952. signal ('22023', sprintf ('SPARQL 1.1 can not %s non-replicated graph <%s> to replicated graph <%s>, both should be in same replication status', src_g_iri, tgt_g_iri));
  7953. if ('ADD' <> opname)
  7954. DB.DBA.SPARUL_CLEAR (tgt_g_iri, 0, uid, log_mode, 0, options, silent);
  7955. if (src_repl and tgt_repl)
  7956. {
  7957. repl_text ('__rdf_repl', '__rdf_repl_flush_queue()');
  7958. repl_text ('__rdf_repl', 'sparql define input:storage "" add iri( ?? ) to iri( ?? )', src_g_iri, tgt_g_iri);
  7959. }
  7960. old_log_enable := log_enable (log_mode, 1);
  7961. declare exit handler for sqlstate '*' { log_enable (old_log_enable, 1); resignal; };
  7962. stat := '00000';
  7963. qry := sprintf ('insert soft DB.DBA.RDF_QUAD (G,S,P,O) select __i2id (''%S''), t.S, t.P, t.O from DB.DBA.RDF_QUAD t where t.G = __i2id (''%S'') ',
  7964. tgt_g_iri, src_g_iri );
  7965. exec (qry, stat, msg);
  7966. if (stat <> '00000')
  7967. signal (stat, msg);
  7968. if ('MOVE' = opname)
  7969. DB.DBA.SPARUL_CLEAR (src_g_iri, 0, uid, log_mode, 0, options, silent);
  7970. /*091202 commit work; */
  7971. log_enable (old_log_enable, 1);
  7972. if (compose_report)
  7973. return sprintf ('%s <%s> to <%s> -- done', opname, src_g_iri, tgt_g_iri);
  7974. return 1;
  7975. }
  7976. ;
  7977. create function DB.DBA.SPARUL_COPY (in src_g_iri any, in tgt_g_iri any, in uid integer := 0, in log_mode integer := null, in compose_report integer := 0, in options any := null, in silent integer := 0) returns any
  7978. {
  7979. return DB.DBA.SPARUL_COPYMOVEADD_IMPL ('COPY', src_g_iri, tgt_g_iri, uid, log_mode, compose_report, options, silent);
  7980. }
  7981. ;
  7982. create function DB.DBA.SPARUL_MOVE (in src_g_iri any, in tgt_g_iri any, in uid integer := 0, in log_mode integer := null, in compose_report integer := 0, in options any := null, in silent integer := 0) returns any
  7983. {
  7984. return DB.DBA.SPARUL_COPYMOVEADD_IMPL ('MOVE', src_g_iri, tgt_g_iri, uid, log_mode, compose_report, options, silent);
  7985. }
  7986. ;
  7987. create function DB.DBA.SPARUL_ADD (in src_g_iri any, in tgt_g_iri any, in uid integer := 0, in log_mode integer := null, in compose_report integer := 0, in options any := null, in silent integer := 0) returns any
  7988. {
  7989. return DB.DBA.SPARUL_COPYMOVEADD_IMPL ('ADD', src_g_iri, tgt_g_iri, uid, log_mode, compose_report, options, silent);
  7990. }
  7991. ;
  7992. create procedure DB.DBA.SPARQL_SELECT_KNOWN_GRAPHS (in return_iris integer := 1, in lim integer := 2000000000)
  7993. {
  7994. declare specials, specials_vec any;
  7995. declare last_iri_id, cur_iri_id IRI_ID;
  7996. declare cr cursor for select G from DB.DBA.RDF_QUAD table option (index G) where G > last_iri_id and not (dict_get (specials, G, 0));
  7997. declare cr_cl cursor for select G from DB.DBA.RDF_QUAD table option (index G) where G > last_iri_id and 0 >= position (G, specials_vec);
  7998. declare GRAPH_IRI varchar;
  7999. declare GRAPH_IID IRI_ID;
  8000. declare ctr, len integer;
  8001. if (lim is null)
  8002. lim := 2000000000;
  8003. if (return_iris)
  8004. result_names (GRAPH_IRI);
  8005. else
  8006. result_names (GRAPH_IID);
  8007. specials := dict_new (50);
  8008. set isolation = 'repeatable';
  8009. for (sparql define input:storage ""
  8010. select distinct ?graph_rvr_fixed
  8011. from <http://www.openlinksw.com/schemas/virtrdf#>
  8012. where { ?qmv virtrdf:qmGraphRange-rvrFixedValue ?graph_rvr_fixed } ) do
  8013. {
  8014. dict_put (specials, iri_to_id ("graph_rvr_fixed"), 1);
  8015. }
  8016. if (dict_size (specials) >= lim)
  8017. goto done_all;
  8018. for (select REC_GRAPH_IID from DB.DBA.RDF_EXPLICITLY_CREATED_GRAPH) do
  8019. {
  8020. dict_put (specials, REC_GRAPH_IID, 2);
  8021. }
  8022. len := dict_size (specials);
  8023. if (len >= lim)
  8024. goto done_all;
  8025. last_iri_id := #i0;
  8026. -- if (1 <> sys_stat ('cl_run_local_only'))
  8027. -- {
  8028. specials_vec := dict_list_keys (specials, 0);
  8029. whenever not found goto done_rdf_quad_cl;
  8030. open cr_cl (prefetch 1);
  8031. next_fetch_cr_cl:
  8032. fetch cr_cl into cur_iri_id;
  8033. if (return_iris)
  8034. result (id_to_iri (cur_iri_id));
  8035. else
  8036. result (cur_iri_id);
  8037. lim := lim - 1;
  8038. if (len >= lim)
  8039. goto done_rdf_quad_cl;
  8040. last_iri_id := cur_iri_id;
  8041. close cr_cl;
  8042. open cr_cl (prefetch 1);
  8043. goto next_fetch_cr_cl;
  8044. done_rdf_quad_cl:
  8045. close cr_cl;
  8046. -- }
  8047. -- else
  8048. -- {
  8049. -- whenever not found goto done_rdf_quad;
  8050. -- open cr (prefetch 1);
  8051. --next_fetch_cr:
  8052. -- fetch cr into cur_iri_id;
  8053. -- if (return_iris)
  8054. -- result (id_to_iri (cur_iri_id));
  8055. -- else
  8056. -- result (cur_iri_id);
  8057. -- lim := lim - 1;
  8058. -- if (len >= lim)
  8059. -- goto done_rdf_quad;
  8060. -- last_iri_id := cur_iri_id;
  8061. -- goto next_fetch_cr;
  8062. --done_rdf_quad:
  8063. -- close cr;
  8064. -- }
  8065. done_all:
  8066. specials := dict_list_keys (specials, 1);
  8067. len := length (specials);
  8068. for (ctr := 0; ctr < len; ctr := ctr + 1)
  8069. if (return_iris)
  8070. result (id_to_iri (specials[ctr]));
  8071. else
  8072. result (specials[ctr]);
  8073. }
  8074. ;
  8075. -----
  8076. -- Built-in operations of SPARQL as SQL functions
  8077. --!AWK PUBLIC
  8078. create function DB.DBA.RDF_REGEX (in s varchar, in p varchar, in coll varchar := null)
  8079. {
  8080. if (not iswidestring (s) and not isstring (s))
  8081. return 0;
  8082. if (regexp_match (p, s, 0, coalesce (coll, ''), 1) is not null)
  8083. return 1;
  8084. return 0;
  8085. }
  8086. ;
  8087. --!AWK PUBLIC
  8088. create function DB.DBA.RDF_LANGMATCHES (in r varchar, in t varchar)
  8089. {
  8090. if ((t is null) or (r is null))
  8091. return null;
  8092. if ('*' = t)
  8093. {
  8094. if (r <> '')
  8095. return 1;
  8096. return 0;
  8097. }
  8098. t := upper (t);
  8099. r := upper (r);
  8100. if (r = t)
  8101. return 1;
  8102. if (r like t || '-%')
  8103. return 1;
  8104. return 0;
  8105. }
  8106. ;
  8107. --!AWK PUBLIC
  8108. create procedure DB.DBA.BEST_LANGMATCH_INIT (inout env any)
  8109. {
  8110. env := vector (0, -2);
  8111. }
  8112. ;
  8113. --!AWK PUBLIC
  8114. create procedure DB.DBA.BEST_LANGMATCH_ACC (inout env any, in obj any array, in range varchar, in dflt_lang varchar)
  8115. {
  8116. declare lang varchar;
  8117. declare pct integer;
  8118. if (obj is null)
  8119. return;
  8120. if (__tag (env) <> __tag of vector)
  8121. env := vector (0, -2);
  8122. if (__tag of rdf_box = __tag (obj))
  8123. {
  8124. declare twobyte integer;
  8125. twobyte := rdf_box_lang (obj);
  8126. if (257 = twobyte)
  8127. lang := dflt_lang;
  8128. else
  8129. {
  8130. whenever not found goto badlang;
  8131. select lower (RL_ID) into lang from DB.DBA.RDF_LANGUAGE where RL_TWOBYTE = twobyte;
  8132. goto lang_ready;
  8133. badlang:
  8134. signal ('RDFXX', sprintf ('Unknown language in DB.DBA.BEST_LANGMATCH_ACC, bad lang id %d', twobyte));
  8135. }
  8136. }
  8137. else if (__tag of varchar = __tag (obj))
  8138. lang := dflt_lang;
  8139. else
  8140. {
  8141. if (env[1] = -2)
  8142. env := vector (obj, -1);
  8143. return;
  8144. }
  8145. lang_ready:
  8146. pct := langmatches_pct_http (lang, range);
  8147. if (env[1] < pct)
  8148. env := vector (obj, pct);
  8149. }
  8150. ;
  8151. --!AWK PUBLIC
  8152. create function DB.DBA.BEST_LANGMATCH_FINAL (inout env any) returns any
  8153. {
  8154. if (__tag (env) <> __tag of vector)
  8155. return null;
  8156. return env[0];
  8157. }
  8158. ;
  8159. --!AWK PUBLIC
  8160. create aggregate DB.DBA.BEST_LANGMATCH (inout obj any, in range varchar, in dflt_lang varchar) from
  8161. DB.DBA.BEST_LANGMATCH_INIT,
  8162. DB.DBA.BEST_LANGMATCH_ACC,
  8163. DB.DBA.BEST_LANGMATCH_FINAL
  8164. ;
  8165. --!AWK PUBLIC
  8166. create procedure DB.DBA.SPARQL_CONSTRUCT_INIT (inout _env any)
  8167. {
  8168. _env := 0; -- No actual initialization
  8169. }
  8170. ;
  8171. --!AWK PUBLIC
  8172. create procedure DB.DBA.SPARQL_CONSTRUCT_ACC (inout _env any, in opcodes any, in vars any, in stats any, in use_dict_limit integer)
  8173. {
  8174. declare triple_ctr integer;
  8175. declare blank_ids any;
  8176. if (214 <> __tag(_env))
  8177. {
  8178. if (use_dict_limit)
  8179. _env := dict_new (31, sys_stat ('sparql_result_set_max_rows'), sys_stat ('sparql_max_mem_in_use'));
  8180. else
  8181. _env := dict_new (31);
  8182. if (0 < length (stats))
  8183. DB.DBA.SPARQL_CONSTRUCT_ACC (_env, stats, vector(), vector(), use_dict_limit);
  8184. }
  8185. blank_ids := 0;
  8186. for (triple_ctr := length (opcodes) - 1; triple_ctr >= 0; triple_ctr := triple_ctr-1)
  8187. {
  8188. declare fld_ctr, fld_count integer;
  8189. declare triple_vec any;
  8190. declare g_opcode integer;
  8191. g_opcode := aref_or_default (opcodes, triple_ctr, 6, null);
  8192. if (g_opcode is null)
  8193. {
  8194. fld_count := 3;
  8195. triple_vec := vector (0,0,0);
  8196. }
  8197. else
  8198. {
  8199. fld_count := 4;
  8200. triple_vec := vector (0,0,0,0);
  8201. }
  8202. -- dbg_obj_princ ('opcodes[triple_ctr]=', opcodes[triple_ctr]);
  8203. for (fld_ctr := fld_count - 1; fld_ctr >= 0; fld_ctr := fld_ctr - 1)
  8204. {
  8205. declare op integer;
  8206. declare arg any;
  8207. op := opcodes[triple_ctr][fld_ctr * 2];
  8208. arg := opcodes[triple_ctr][fld_ctr * 2 + 1];
  8209. if (1 = op)
  8210. {
  8211. declare i any;
  8212. i := vars[arg];
  8213. if (i is null)
  8214. goto end_of_adding_triple;
  8215. if (isiri_id (i))
  8216. {
  8217. if (fld_ctr in (1,3) and is_bnode_iri_id (i))
  8218. signal ('RDF01', 'Bad variable value in CONSTRUCT: blank node can not be used as predicate or graph');
  8219. }
  8220. else if ((isstring (i) and (1 = __box_flags (i))) or (217 = __tag(i)))
  8221. {
  8222. if (fld_ctr in (1,3) and (i like 'bnode://%'))
  8223. signal ('RDF01', 'Bad variable value in CONSTRUCT: blank node can not be used as predicate or graph');
  8224. i := iri_to_id (i);
  8225. }
  8226. else if (2 <> fld_ctr)
  8227. signal ('RDF01',
  8228. sprintf ('Bad variable value in CONSTRUCT: "%.100s" (tag %d box flags %d) is not a valid %s, only object of a triple can be a literal',
  8229. __rdf_strsqlval (i), __tag (i), __box_flags (i),
  8230. case (fld_ctr) when 1 then 'predicate' else 'subject' end ) );
  8231. triple_vec[fld_ctr] := i;
  8232. }
  8233. else if (2 = op)
  8234. {
  8235. if (isinteger (blank_ids))
  8236. blank_ids := vector (iri_id_from_num (sequence_next ('RDF_URL_IID_BLANK')));
  8237. while (arg >= length (blank_ids))
  8238. blank_ids := vector_concat (blank_ids, vector (iri_id_from_num (sequence_next ('RDF_URL_IID_BLANK'))));
  8239. if (fld_ctr in (1,3))
  8240. signal ('RDF01', 'Bad triple for CONSTRUCT: blank node can not be used as predicate or graph');
  8241. triple_vec[fld_ctr] := blank_ids[arg];
  8242. }
  8243. else if (3 = op)
  8244. {
  8245. if (arg is null)
  8246. goto end_of_adding_triple;
  8247. if (isiri_id (arg))
  8248. {
  8249. if (fld_ctr in (1,3) and is_bnode_iri_id (arg))
  8250. signal ('RDF01', 'Bad const value in CONSTRUCT: blank node can not be used as predicate or graph');
  8251. }
  8252. else if ((isstring (arg) and (1 = __box_flags (arg))) or (217 = __tag(arg)))
  8253. {
  8254. if (fld_ctr in (1,3) and (arg like 'bnode://%'))
  8255. signal ('RDF01', 'Bad const value in CONSTRUCT: blank node can not be used as predicate or graph');
  8256. arg := iri_to_id (arg);
  8257. }
  8258. else if (2 <> fld_ctr)
  8259. signal ('RDF01',
  8260. sprintf ('Bad const value in CONSTRUCT: "%.100s" (tag %d box flags %d) is not a valid %s, only object of a triple can be a literal',
  8261. __rdf_strsqlval (arg), __tag (arg), __box_flags (arg),
  8262. case (fld_ctr) when 1 then 'predicate' else 'subject' end ) );
  8263. else if (__tag of vector = __tag (arg))
  8264. arg := DB.DBA.RDF_MAKE_LONG_OF_TYPEDSQLVAL_STRINGS (arg[0], arg[1], arg[2]);
  8265. triple_vec[fld_ctr] := arg;
  8266. }
  8267. else signal ('RDFXX', 'Bad opcode in DB.DBA.SPARQL_CONSTRUCT()');
  8268. }
  8269. -- dbg_obj_princ ('generated triple:', triple_vec);
  8270. dict_put (_env, triple_vec, 0);
  8271. end_of_adding_triple: ;
  8272. }
  8273. }
  8274. ;
  8275. --!AWK PUBLIC
  8276. create procedure DB.DBA.SPARQL_CONSTRUCT_FIN (inout _env any)
  8277. {
  8278. if (214 <> __tag(_env))
  8279. _env := dict_new ();
  8280. return _env;
  8281. }
  8282. ;
  8283. --!AWK PUBLIC
  8284. create aggregate DB.DBA.SPARQL_CONSTRUCT (in opcodes any, in vars any, in stats any, in use_dict_limit integer) returns any
  8285. from DB.DBA.SPARQL_CONSTRUCT_INIT, DB.DBA.SPARQL_CONSTRUCT_ACC, DB.DBA.SPARQL_CONSTRUCT_FIN
  8286. ;
  8287. create procedure DB.DBA.SPARQL_DESC_AGG_INIT (inout _env any)
  8288. {
  8289. _env := 0; -- No actual initialization
  8290. }
  8291. ;
  8292. create procedure DB.DBA.SPARQL_INSERT_DATA (in graph_iri any, in triple_ops any)
  8293. {
  8294. for vectored (in triple_op any := triple_ops)
  8295. {
  8296. declare op, s, p, o any;
  8297. if (isiri_id (o_val))
  8298. __rdf_repl_quad (84, graph_iri, s_iri, p_iri, iri_canonicalize (o_val));
  8299. else if (__tag of rdf_box <> __tag (o_val))
  8300. __rdf_repl_quad (80, graph_iri, s_iri, p_iri, o_val);
  8301. else
  8302. {
  8303. declare dt_twobyte, lang_twobyte integer;
  8304. dt_twobyte := rdf_box_type (o_val);
  8305. lang_twobyte := rdf_box_lang (o_val);
  8306. if (257 <> dt_twobyte)
  8307. __rdf_repl_quad (81, graph_iri, s_iri, p_iri, rdf_box_data (o_val), (select RDT_QNAME from DB.DBA.RDF_DATATYPE where RDT_TWOBYTE = dt_twobyte), NULL);
  8308. else if (257 <> lang_twobyte)
  8309. __rdf_repl_quad (82, graph_iri, s_iri, p_iri, rdf_box_data (o_val), NULL, (select RL_ID from DB.DBA.RDF_LANGUAGE where RL_TWOBYTE = lang_twobyte));
  8310. else
  8311. __rdf_repl_quad (80, graph_iri, s_iri, p_iri, rdf_box_data (o_val));
  8312. }
  8313. }
  8314. }
  8315. ;
  8316. create procedure DB.DBA.SPARQL_DESC_AGG_ACC (inout _env any, in vars any)
  8317. {
  8318. declare var_ctr integer;
  8319. declare blank_ids any;
  8320. if (214 <> __tag(_env))
  8321. {
  8322. _env := dict_new (31, sys_stat ('sparql_result_set_max_rows'), sys_stat ('sparql_max_mem_in_use'));
  8323. }
  8324. for (var_ctr := length (vars) - 1; var_ctr >= 0; var_ctr := var_ctr - 1)
  8325. {
  8326. declare i any;
  8327. i := vars[var_ctr];
  8328. if (isiri_id (i))
  8329. dict_put (_env, i, 0);
  8330. }
  8331. }
  8332. ;
  8333. create procedure DB.DBA.SPARQL_DESC_AGG_FIN (inout _env any)
  8334. {
  8335. declare subjects, options, res any;
  8336. declare subj_ctr integer;
  8337. if (214 <> __tag(_env))
  8338. return dict_new ();
  8339. return _env;
  8340. }
  8341. ;
  8342. create aggregate DB.DBA.SPARQL_DESC_AGG (in vars any) returns any
  8343. from DB.DBA.SPARQL_DESC_AGG_INIT, DB.DBA.SPARQL_DESC_AGG_ACC, DB.DBA.SPARQL_DESC_AGG_FIN
  8344. ;
  8345. create procedure DB.DBA.SPARQL_DESC_DICT (in subj_dict any, in consts any, in good_graphs any, in bad_graphs any, in storage_name any, in options any)
  8346. {
  8347. declare all_subj_descs, phys_subjects, sorted_good_graphs, sorted_bad_graphs, g_dict, res any;
  8348. declare uid, graphs_listed, g_ctr, good_g_count, bad_g_count, s_ctr, all_s_count, phys_s_count integer;
  8349. declare gs_app_callback, gs_app_uid, inf_ruleset, sameas varchar;
  8350. declare rdf_type_iid IRI_ID;
  8351. uid := get_keyword ('uid', options, http_nobody_uid());
  8352. gs_app_callback := get_keyword ('gs-app-callback', options);
  8353. if (gs_app_callback is not null)
  8354. gs_app_uid := get_keyword ('gs-app-uid', options);
  8355. inf_ruleset := get_keyword ('inference', options);
  8356. sameas := get_keyword ('same-as', options);
  8357. rdf_type_iid := iri_to_id (UNAME'http://www.w3.org/1999/02/22-rdf-syntax-ns#type');
  8358. res := dict_new ();
  8359. if (isinteger (consts))
  8360. return res;
  8361. foreach (any c in consts) do
  8362. {
  8363. if (isiri_id (c))
  8364. dict_put (subj_dict, c, 0);
  8365. }
  8366. all_subj_descs := dict_list_keys (subj_dict, 1);
  8367. all_s_count := length (all_subj_descs);
  8368. if (0 = all_s_count)
  8369. return res;
  8370. gvector_sort (all_subj_descs, 1, 0, 0);
  8371. if (__tag of integer = __tag (good_graphs))
  8372. graphs_listed := 0;
  8373. else
  8374. {
  8375. vectorbld_init (sorted_good_graphs);
  8376. foreach (any g in good_graphs) do
  8377. {
  8378. if (isiri_id (g) and g < min_bnode_iri_id () and
  8379. __rgs_ack_cbk (g, uid, 1) and
  8380. (gs_app_callback is null or bit_and (1, call (gs_app_callback) (g, gs_app_uid))) )
  8381. vectorbld_acc (sorted_good_graphs, g);
  8382. }
  8383. vectorbld_final (sorted_good_graphs);
  8384. good_g_count := length (sorted_good_graphs);
  8385. if (0 = good_g_count)
  8386. return res;
  8387. graphs_listed := 1;
  8388. }
  8389. vectorbld_init (sorted_bad_graphs);
  8390. foreach (any g in bad_graphs) do
  8391. {
  8392. if (isiri_id (g) and g < min_bnode_iri_id ())
  8393. vectorbld_acc (sorted_bad_graphs, g);
  8394. }
  8395. vectorbld_final (sorted_bad_graphs);
  8396. bad_g_count := length (sorted_bad_graphs);
  8397. vectorbld_init (phys_subjects);
  8398. if (storage_name is null)
  8399. storage_name := 'http://www.openlinksw.com/schemas/virtrdf#DefaultQuadStorage';
  8400. else if (('' = storage_name) and (inf_ruleset is null) and (sameas is null))
  8401. {
  8402. for (s_ctr := 0; s_ctr < all_s_count; s_ctr := s_ctr + 1)
  8403. {
  8404. declare s, phys_s any;
  8405. s := all_subj_descs [s_ctr];
  8406. if (isiri_id (s))
  8407. vectorbld_acc (phys_subjects, s);
  8408. else
  8409. {
  8410. phys_s := iri_to_id (s, 0, 0);
  8411. if (not isinteger (phys_s))
  8412. vectorbld_acc (phys_subjects, phys_s);
  8413. }
  8414. }
  8415. vectorbld_final (phys_subjects);
  8416. goto describe_physical_subjects;
  8417. }
  8418. -- dbg_obj_princ ('storage_name=',storage_name, ' sorted_good_graphs=', sorted_good_graphs, ' sorted_bad_graphs=', sorted_bad_graphs);
  8419. for (s_ctr := 0; s_ctr < all_s_count; s_ctr := s_ctr + 1)
  8420. {
  8421. declare s, phys_s, maps_s, maps_o any;
  8422. declare maps_s_len, maps_o_len integer;
  8423. s := all_subj_descs [s_ctr];
  8424. maps_s := sparql_quad_maps_for_quad (NULL, s, NULL, NULL, storage_name, case (graphs_listed) when 0 then vector() else sorted_good_graphs end, sorted_bad_graphs);
  8425. maps_o := sparql_quad_maps_for_quad (NULL, NULL, NULL, s, storage_name, case (graphs_listed) when 0 then vector() else sorted_good_graphs end, sorted_bad_graphs);
  8426. -- dbg_obj_princ ('s = ', s, ' maps_s = ', maps_s, ' maps_o = ', maps_o);
  8427. maps_s_len := length (maps_s);
  8428. maps_o_len := length (maps_o);
  8429. if ((inf_ruleset is null) and (sameas is null))
  8430. {
  8431. declare phys_as_s, phys_as_o integer;
  8432. phys_as_s := case when ((maps_s_len > 0) and (maps_s[maps_s_len-1][0] = UNAME'http://www.openlinksw.com/schemas/virtrdf#DefaultQuadMap')) then 1 else 0 end;
  8433. phys_as_o := case when ((maps_o_len > 0) and (maps_o[maps_o_len-1][0] = UNAME'http://www.openlinksw.com/schemas/virtrdf#DefaultQuadMap')) then 1 else 0 end;
  8434. if (phys_as_s or phys_as_o)
  8435. {
  8436. if (isiri_id (s))
  8437. {
  8438. phys_s := s;
  8439. vectorbld_acc (phys_subjects, phys_s);
  8440. }
  8441. else
  8442. {
  8443. phys_s := iri_to_id (s, 0, 0);
  8444. if (not isinteger (phys_s))
  8445. vectorbld_acc (phys_subjects, phys_s);
  8446. }
  8447. if (phys_as_s)
  8448. {
  8449. maps_s := subseq (maps_s, 0, maps_s_len-1);
  8450. maps_s_len := maps_s_len - 1;
  8451. }
  8452. if (phys_as_o)
  8453. {
  8454. maps_o := subseq (maps_o, 0, maps_o_len-1);
  8455. maps_o_len := maps_o_len - 1;
  8456. }
  8457. }
  8458. }
  8459. if ((maps_s_len > 0) or (maps_o_len > 0))
  8460. all_subj_descs [s_ctr] := vector (s, maps_s, maps_o);
  8461. else
  8462. all_subj_descs [s_ctr] := 0;
  8463. -- dbg_obj_princ ('s = ', s, ' maps = ', maps);
  8464. -- dbg_obj_princ ('all_subj_descs [', s_ctr, '] = ', all_subj_descs [s_ctr]);
  8465. }
  8466. vectorbld_final (phys_subjects);
  8467. for (s_ctr := 0; s_ctr < all_s_count; s_ctr := s_ctr + 1)
  8468. {
  8469. declare s_desc, s, maps_s, maps_o any;
  8470. declare map_ctr, maps_s_len, maps_o_len integer;
  8471. declare fname varchar;
  8472. s_desc := all_subj_descs [s_ctr];
  8473. if (isinteger (s_desc))
  8474. goto end_of_s;
  8475. s := s_desc[0];
  8476. maps_s := s_desc[1];
  8477. maps_o := s_desc[2];
  8478. maps_s_len := length (maps_s);
  8479. maps_o_len := length (maps_o);
  8480. fname := sprintf ('SPARQL_DESC_DICT_QMV1_%U', md5 (storage_name || ' ' || inf_ruleset || ' ' || sameas || ' ' || cast (graphs_listed as varchar) || md5_box (maps_s) || md5_box (maps_o) || md5_box (sorted_bad_graphs)));
  8481. if (not exists (select top 1 1 from Db.DBA.SYS_PROCEDURES where P_NAME = 'DB.DBA.' || fname))
  8482. {
  8483. declare ses, txt, saved_user any;
  8484. ses := string_output ();
  8485. http ('create procedure DB.DBA."' || fname || '" (in subj any, in res any', ses);
  8486. if (graphs_listed)
  8487. http (', inout sorted_good_graphs any', ses);
  8488. http (')\n', ses);
  8489. http ('{\n', ses);
  8490. http (' declare subj_iri varchar;\n', ses);
  8491. http (' subj_iri := id_to_iri_nosignal (subj);\n', ses);
  8492. if (maps_s_len > 0)
  8493. {
  8494. http (' for (sparql define output:valmode "LONG" define input:storage <' || storage_name || '> ', ses);
  8495. foreach (any g in sorted_bad_graphs) do
  8496. {
  8497. http (' define input:named-graph-exclude <' || id_to_iri_nosignal (g) || '>\n', ses);
  8498. }
  8499. if (inf_ruleset is not null)
  8500. http (' define input:inference <' || inf_ruleset || '>\n', ses);
  8501. if (sameas is not null)
  8502. http (' define input:same-as <' || sameas || '>\n', ses);
  8503. http ('select ?g1 ?p1 ?o1\n', ses);
  8504. http (' where { graph ?g1 {\n', ses);
  8505. for (map_ctr := 0; map_ctr < maps_s_len; map_ctr := map_ctr + 1)
  8506. {
  8507. if (map_ctr > 0) http (' union\n', ses);
  8508. http (' { quad map <' || maps_s[map_ctr][0] || '> { ?:subj_iri ?p1 ?o1 } }\n', ses);
  8509. }
  8510. http (' } } ) do {\n', ses);
  8511. if (graphs_listed)
  8512. http (' if (position (__i2idn ("g1"), sorted_good_graphs))\n', ses);
  8513. http (' dict_bitor_or_put (res, vector (subj, "p1", "o1"), 1);\n }\n', ses);
  8514. }
  8515. if (maps_o_len > 0)
  8516. {
  8517. http (' for (sparql define output:valmode "LONG" define input:storage <' || storage_name || '> ', ses);
  8518. foreach (any g in sorted_bad_graphs) do
  8519. {
  8520. http (' define input:named-graph-exclude <' || id_to_iri_nosignal (g) || '>\n', ses);
  8521. }
  8522. if (inf_ruleset is not null)
  8523. http (' define input:inference <' || inf_ruleset || '>\n', ses);
  8524. if (sameas is not null)
  8525. http (' define input:same-as <' || sameas || '>\n', ses);
  8526. http ('select ?g1 ?s1 ?p1\n', ses);
  8527. http (' where { graph ?g1 {\n', ses);
  8528. for (map_ctr := 0; map_ctr < maps_o_len; map_ctr := map_ctr + 1)
  8529. {
  8530. if (map_ctr > 0) http (' union\n', ses);
  8531. http (' { quad map <' || maps_o[map_ctr][0] || '> { ?s1 ?p1 ?o1 . FILTER (?p1 != rdf:type) . FILTER(isREF (?o1)) . FILTER (?o1 = iri(?:subj_iri)) } }\n', ses);
  8532. }
  8533. http (' } } ) do {\n', ses);
  8534. if (graphs_listed)
  8535. http (' if (position (__i2idn ("g1"), sorted_good_graphs))\n', ses);
  8536. http (' dict_bitor_or_put (res, vector ("s1", "p1", subj), 4);\n }\n', ses);
  8537. }
  8538. http ('}\n', ses);
  8539. txt := string_output_string (ses);
  8540. -- dbg_obj_princ ('Procedure text: ', txt); string_to_file (fname || '.sql', txt || '\n;', -2);
  8541. saved_user := user;
  8542. set_user_id ('dba', 1);
  8543. exec (txt);
  8544. set_user_id (saved_user);
  8545. }
  8546. if (graphs_listed)
  8547. {
  8548. -- dbg_obj_princ ('call (''DB.DBA.', fname, ''')(', s, res, sorted_good_graphs, ')');
  8549. call ('DB.DBA.' || fname)(s, res, sorted_good_graphs);
  8550. }
  8551. else
  8552. {
  8553. -- dbg_obj_princ ('call (''DB.DBA.', fname, ''')(', s, res, ')');
  8554. call ('DB.DBA.' || fname)(s, res);
  8555. }
  8556. end_of_s: ;
  8557. }
  8558. describe_physical_subjects:
  8559. gvector_sort (phys_subjects, 1, 0, 0);
  8560. phys_s_count := length (phys_subjects);
  8561. -- dbg_obj_princ ('phys_subjects = ', phys_subjects);
  8562. if (0 = phys_s_count)
  8563. return res;
  8564. -- dbg_obj_princ ('sorted_bad_graphs = ', sorted_bad_graphs);
  8565. if (graphs_listed)
  8566. {
  8567. gvector_sort (sorted_good_graphs, 1, 0, 0);
  8568. -- dbg_obj_princ ('sorted_good_graphs = ', sorted_good_graphs);
  8569. for (g_ctr := good_g_count - 1; g_ctr >= 0; g_ctr := g_ctr - 1)
  8570. {
  8571. declare graph any;
  8572. graph := sorted_good_graphs [g_ctr];
  8573. for (s_ctr := phys_s_count - 1; s_ctr >= 0; s_ctr := s_ctr - 1)
  8574. {
  8575. declare subj any;
  8576. subj := phys_subjects [s_ctr];
  8577. for (select P as p1, O as obj1 from DB.DBA.RDF_QUAD where G = graph and S = subj) do
  8578. {
  8579. -- dbg_obj_princ ('found5 ', subj, p1, ' in ', graph);
  8580. dict_bitor_or_put (res, vector (subj, p1, __rdf_long_of_obj (obj1)), 1);
  8581. }
  8582. for (select S as s1, P as p1 from DB.DBA.RDF_QUAD
  8583. where G = graph and O = subj and P <> rdf_type_iid
  8584. option (QUIETCAST)) do
  8585. {
  8586. -- dbg_obj_princ ('found2 ', s1, p1, subj, ' in ', graph);
  8587. dict_bitor_or_put (res, vector (s1, p1, subj), 4);
  8588. }
  8589. }
  8590. }
  8591. return res;
  8592. }
  8593. g_dict := dict_new ();
  8594. for (s_ctr := phys_s_count - 1; s_ctr >= 0; s_ctr := s_ctr - 1)
  8595. {
  8596. declare subj, graph any;
  8597. subj := phys_subjects [s_ctr];
  8598. graph := coalesce ((select top 1 G as g1 from DB.DBA.RDF_QUAD where O = subj and
  8599. 0 = position (G, sorted_bad_graphs) and
  8600. __rgs_ack_cbk (G, uid, 1) and
  8601. (gs_app_callback is null or bit_and (1, call (gs_app_callback) (G, gs_app_uid))) ) );
  8602. if (graph is not null)
  8603. dict_put (g_dict, graph, 0);
  8604. }
  8605. sorted_good_graphs := dict_list_keys (g_dict, 1);
  8606. if (0 = length (sorted_good_graphs))
  8607. {
  8608. g_dict := dict_new ();
  8609. for (s_ctr := phys_s_count - 1; s_ctr >= 0; s_ctr := s_ctr - 1)
  8610. {
  8611. declare subj, graph any;
  8612. subj := phys_subjects [s_ctr];
  8613. graph := coalesce ((select top 1 G as g1 from DB.DBA.RDF_QUAD where S = subj and P = rdf_type_iid and
  8614. 0 = position (G, sorted_bad_graphs) and
  8615. __rgs_ack_cbk (G, uid, 1) and
  8616. (gs_app_callback is null or bit_and (1, call (gs_app_callback) (G, gs_app_uid))) ) );
  8617. if (graph is not null)
  8618. dict_put (g_dict, graph, 0);
  8619. }
  8620. sorted_good_graphs := dict_list_keys (g_dict, 1);
  8621. }
  8622. -- dbg_obj_princ ('sorted_good_graphs = ', sorted_good_graphs);
  8623. gvector_sort (sorted_good_graphs, 1, 0, 0);
  8624. good_g_count := length (sorted_good_graphs);
  8625. -- dbg_obj_princ ('sorted_good_graphs = ', sorted_good_graphs);
  8626. for (g_ctr := good_g_count - 1; g_ctr >= 0; g_ctr := g_ctr - 1)
  8627. {
  8628. declare graph any;
  8629. graph := sorted_good_graphs [g_ctr];
  8630. for (s_ctr := phys_s_count - 1; s_ctr >= 0; s_ctr := s_ctr - 1)
  8631. {
  8632. declare subj any;
  8633. subj := phys_subjects [s_ctr];
  8634. for (select P as p1, O as obj1 from DB.DBA.RDF_QUAD where G = graph and S = subj) do
  8635. {
  8636. -- dbg_obj_princ ('found1 ', subj, p1, ' in ', graph);
  8637. dict_bitor_or_put (res, vector (subj, p1, __rdf_long_of_obj (obj1)), 1);
  8638. -- if (isiri_id (obj1))
  8639. -- {
  8640. -- for (select P as p2, O as obj2
  8641. -- from DB.DBA.RDF_QUAD
  8642. -- where G = graph and S = obj1 and not (isiri_id (O)) ) do
  8643. -- {
  8644. -- dict_bitor_or_put (dict, vector (obj1, p2, __rdf_long_of_obj (obj2)), 17);
  8645. -- }
  8646. -- }
  8647. }
  8648. for (select S as s1, P as p1 from DB.DBA.RDF_QUAD
  8649. where G = graph and O = subj and P <> rdf_type_iid
  8650. option (QUIETCAST)) do
  8651. {
  8652. -- dbg_obj_princ ('found2 ', s1, p1, subj, ' in ', graph);
  8653. dict_bitor_or_put (res, vector (s1, p1, subj), 4);
  8654. }
  8655. }
  8656. }
  8657. -- dbg_obj_princ ('final result is ', res);
  8658. return res;
  8659. }
  8660. ;
  8661. create procedure DB.DBA.SPARQL_DESC_DICT_SPO (in subj_dict any, in consts any, in good_graphs any, in bad_graphs any, in storage_name any, in options any)
  8662. {
  8663. declare all_subj_descs, phys_subjects, sorted_good_graphs, sorted_bad_graphs, res any;
  8664. declare uid, graphs_listed, g_ctr, good_g_count, bad_g_count, s_ctr, all_s_count, phys_s_count integer;
  8665. declare gs_app_callback, gs_app_uid, inf_ruleset, sameas varchar;
  8666. declare rdf_type_iid IRI_ID;
  8667. uid := get_keyword ('uid', options, http_nobody_uid());
  8668. gs_app_callback := get_keyword ('gs-app-callback', options);
  8669. if (gs_app_callback is not null)
  8670. gs_app_uid := get_keyword ('gs-app-uid', options);
  8671. inf_ruleset := get_keyword ('inference', options);
  8672. sameas := get_keyword ('same-as', options);
  8673. rdf_type_iid := iri_to_id (UNAME'http://www.w3.org/1999/02/22-rdf-syntax-ns#type');
  8674. res := dict_new ();
  8675. if (isinteger (consts))
  8676. return res;
  8677. foreach (any c in consts) do
  8678. {
  8679. if (isiri_id (c))
  8680. dict_put (subj_dict, c, 0);
  8681. }
  8682. all_subj_descs := dict_list_keys (subj_dict, 1);
  8683. all_s_count := length (all_subj_descs);
  8684. if (0 = all_s_count)
  8685. return res;
  8686. gvector_sort (all_subj_descs, 1, 0, 0);
  8687. if (__tag of integer = __tag (good_graphs))
  8688. graphs_listed := 0;
  8689. else
  8690. {
  8691. vectorbld_init (sorted_good_graphs);
  8692. foreach (any g in good_graphs) do
  8693. {
  8694. if (isiri_id (g) and g < min_bnode_iri_id () and
  8695. __rgs_ack_cbk (g, uid, 1) and
  8696. (gs_app_callback is null or bit_and (1, call (gs_app_callback) (g, gs_app_uid))) )
  8697. vectorbld_acc (sorted_good_graphs, g);
  8698. }
  8699. vectorbld_final (sorted_good_graphs);
  8700. good_g_count := length (sorted_good_graphs);
  8701. if (0 = good_g_count)
  8702. return res;
  8703. graphs_listed := 1;
  8704. }
  8705. vectorbld_init (sorted_bad_graphs);
  8706. foreach (any g in bad_graphs) do
  8707. {
  8708. if (isiri_id (g) and g < min_bnode_iri_id ())
  8709. vectorbld_acc (sorted_bad_graphs, g);
  8710. }
  8711. vectorbld_final (sorted_bad_graphs);
  8712. bad_g_count := length (sorted_bad_graphs);
  8713. vectorbld_init (phys_subjects);
  8714. if (storage_name is null)
  8715. storage_name := 'http://www.openlinksw.com/schemas/virtrdf#DefaultQuadStorage';
  8716. else if (('' = storage_name) and (inf_ruleset is null) and (sameas is null))
  8717. {
  8718. for (s_ctr := 0; s_ctr < all_s_count; s_ctr := s_ctr + 1)
  8719. {
  8720. declare s, phys_s any;
  8721. s := all_subj_descs [s_ctr];
  8722. if (isiri_id (s))
  8723. vectorbld_acc (phys_subjects, s);
  8724. else
  8725. {
  8726. phys_s := iri_to_id (s, 0, 0);
  8727. if (not isinteger (phys_s))
  8728. vectorbld_acc (phys_subjects, phys_s);
  8729. }
  8730. }
  8731. vectorbld_final (phys_subjects);
  8732. goto describe_physical_subjects;
  8733. }
  8734. -- dbg_obj_princ ('storage_name=',storage_name, ' sorted_good_graphs=', sorted_good_graphs, ' sorted_bad_graphs=', sorted_bad_graphs);
  8735. for (s_ctr := 0; s_ctr < all_s_count; s_ctr := s_ctr + 1)
  8736. {
  8737. declare s, phys_s, maps any;
  8738. declare maps_len integer;
  8739. s := all_subj_descs [s_ctr];
  8740. maps := sparql_quad_maps_for_quad (NULL, s, NULL, NULL, storage_name, case (graphs_listed) when 0 then vector() else sorted_good_graphs end, sorted_bad_graphs);
  8741. -- dbg_obj_princ ('s = ', s, ' maps = ', maps);
  8742. maps_len := length (maps);
  8743. if ((maps_len > 0) and (inf_ruleset is null) and (sameas is null) and (maps[maps_len-1][0] = UNAME'http://www.openlinksw.com/schemas/virtrdf#DefaultQuadMap'))
  8744. {
  8745. if (isiri_id (s))
  8746. {
  8747. phys_s := s;
  8748. vectorbld_acc (phys_subjects, phys_s);
  8749. }
  8750. else
  8751. {
  8752. phys_s := iri_to_id (s, 0, 0);
  8753. if (not isinteger (phys_s))
  8754. vectorbld_acc (phys_subjects, phys_s);
  8755. }
  8756. maps := subseq (maps, 0, maps_len-1);
  8757. maps_len := maps_len - 1;
  8758. }
  8759. if (maps_len > 0)
  8760. all_subj_descs [s_ctr] := vector (s, maps);
  8761. else
  8762. all_subj_descs [s_ctr] := 0;
  8763. -- dbg_obj_princ ('s = ', s, ' maps = ', maps);
  8764. -- dbg_obj_princ ('all_subj_descs [', s_ctr, '] = ', all_subj_descs [s_ctr]);
  8765. }
  8766. vectorbld_final (phys_subjects);
  8767. for (s_ctr := 0; s_ctr < all_s_count; s_ctr := s_ctr + 1)
  8768. {
  8769. declare s_desc, s, maps any;
  8770. declare map_ctr, maps_len integer;
  8771. declare fname varchar;
  8772. s_desc := all_subj_descs [s_ctr];
  8773. if (isinteger (s_desc))
  8774. goto end_of_s;
  8775. s := s_desc[0];
  8776. maps := s_desc[1];
  8777. maps_len := length (maps);
  8778. fname := sprintf ('SPARQL_DESC_DICT_QMV1_%U', md5 (storage_name || ' ' || inf_ruleset || ' ' || sameas || ' ' || cast (graphs_listed as varchar) || md5_box (maps) || md5_box (sorted_bad_graphs)));
  8779. if (not exists (select top 1 1 from Db.DBA.SYS_PROCEDURES where P_NAME = 'DB.DBA.' || fname))
  8780. {
  8781. declare ses, txt, saved_user any;
  8782. ses := string_output ();
  8783. http ('create procedure DB.DBA."' || fname || '" (in subj any, in res any', ses);
  8784. if (graphs_listed)
  8785. http (', inout sorted_good_graphs any', ses);
  8786. http (')\n', ses);
  8787. http ('{\n', ses);
  8788. http (' declare subj_iri varchar;\n', ses);
  8789. http (' subj_iri := id_to_iri_nosignal (subj);\n', ses);
  8790. if (maps_len > 0)
  8791. {
  8792. http (' for (sparql define output:valmode "LONG" define input:storage <' || storage_name || '> ', ses);
  8793. foreach (any g in sorted_bad_graphs) do
  8794. {
  8795. http (' define input:named-graph-exclude <' || id_to_iri_nosignal (g) || '>\n', ses);
  8796. }
  8797. if (inf_ruleset is not null)
  8798. http (' define input:inference <' || inf_ruleset || '>\n', ses);
  8799. if (sameas is not null)
  8800. http (' define input:same-as <' || sameas || '>\n', ses);
  8801. http ('select ?g1 ?p1 ?o1\n', ses);
  8802. http (' where { graph ?g1 {\n', ses);
  8803. for (map_ctr := 0; map_ctr < maps_len; map_ctr := map_ctr + 1)
  8804. {
  8805. if (map_ctr > 0) http (' union\n', ses);
  8806. http (' { quad map <' || maps[map_ctr][0] || '> { ?:subj_iri ?p1 ?o1 } }\n', ses);
  8807. }
  8808. http (' } } ) do {\n', ses);
  8809. if (graphs_listed)
  8810. http (' if (position (__i2idn ("g1"), sorted_good_graphs))\n', ses);
  8811. http (' dict_bitor_or_put (res, vector (subj, "p1", "o1"), 1);\n }\n', ses);
  8812. }
  8813. http ('}\n', ses);
  8814. txt := string_output_string (ses);
  8815. -- dbg_obj_princ ('Procedure text: ', txt);
  8816. saved_user := user;
  8817. set_user_id ('dba', 1);
  8818. exec (txt);
  8819. set_user_id (saved_user);
  8820. }
  8821. if (graphs_listed)
  8822. {
  8823. -- dbg_obj_princ ('call (''DB.DBA.', fname, ''')(', s, res, sorted_good_graphs, ')');
  8824. call ('DB.DBA.' || fname)(s, res, sorted_good_graphs);
  8825. }
  8826. else
  8827. {
  8828. -- dbg_obj_princ ('call (''DB.DBA.', fname, ''')(', s, res, ')');
  8829. call ('DB.DBA.' || fname)(s, res);
  8830. }
  8831. end_of_s: ;
  8832. }
  8833. describe_physical_subjects:
  8834. gvector_sort (phys_subjects, 1, 0, 0);
  8835. phys_s_count := length (phys_subjects);
  8836. -- dbg_obj_princ ('phys_subjects = ', phys_subjects);
  8837. if (0 = phys_s_count)
  8838. return res;
  8839. -- dbg_obj_princ ('sorted_bad_graphs = ', sorted_bad_graphs);
  8840. if (graphs_listed)
  8841. {
  8842. gvector_sort (sorted_good_graphs, 1, 0, 0);
  8843. -- dbg_obj_princ ('sorted_good_graphs = ', sorted_good_graphs);
  8844. for (g_ctr := good_g_count - 1; g_ctr >= 0; g_ctr := g_ctr - 1)
  8845. {
  8846. declare graph any;
  8847. graph := sorted_good_graphs [g_ctr];
  8848. for (s_ctr := phys_s_count - 1; s_ctr >= 0; s_ctr := s_ctr - 1)
  8849. {
  8850. declare subj any;
  8851. subj := phys_subjects [s_ctr];
  8852. for (select P as p1, O as obj1 from DB.DBA.RDF_QUAD where G = graph and S = subj) do
  8853. {
  8854. -- dbg_obj_princ ('found3 ', subj, p1, ' in ', graph);
  8855. dict_bitor_or_put (res, vector (subj, p1, __rdf_long_of_obj (obj1)), 1);
  8856. }
  8857. }
  8858. }
  8859. return res;
  8860. }
  8861. for (s_ctr := phys_s_count - 1; s_ctr >= 0; s_ctr := s_ctr - 1)
  8862. {
  8863. declare subj any;
  8864. subj := phys_subjects [s_ctr];
  8865. for (select P as p1, O as obj1 from DB.DBA.RDF_QUAD where
  8866. 0 = position (G, sorted_bad_graphs) and
  8867. S = subj and
  8868. __rgs_ack_cbk (G, uid, 1) and
  8869. (gs_app_callback is null or bit_and (1, call (gs_app_callback) (G, gs_app_uid))) ) do
  8870. {
  8871. -- dbg_obj_princ ('found4 ', subj, p1);
  8872. dict_bitor_or_put (res, vector (subj, p1, __rdf_long_of_obj (obj1)), 1);
  8873. }
  8874. }
  8875. return res;
  8876. }
  8877. ;
  8878. create procedure DB.DBA.SPARQL_DESC_DICT_SPO_PHYSICAL (in subj_dict any, in consts any, in good_graphs any, in bad_graphs any, in storage_name any, in options any)
  8879. {
  8880. declare all_subj_descs, phys_subjects, sorted_good_graphs, sorted_bad_graphs, g_dict, res any;
  8881. declare uid, graphs_listed, g_ctr, good_g_count, bad_g_count, s_ctr, all_s_count, phys_s_count integer;
  8882. declare gs_app_callback, gs_app_uid varchar;
  8883. declare rdf_type_iid IRI_ID;
  8884. uid := get_keyword ('uid', options, http_nobody_uid());
  8885. gs_app_callback := get_keyword ('gs-app-callback', options);
  8886. if (gs_app_callback is not null)
  8887. gs_app_uid := get_keyword ('gs-app-uid', options);
  8888. rdf_type_iid := iri_to_id (UNAME'http://www.w3.org/1999/02/22-rdf-syntax-ns#type');
  8889. res := dict_new ();
  8890. if (isinteger (consts))
  8891. return res;
  8892. foreach (any c in consts) do
  8893. {
  8894. if (isiri_id (c))
  8895. dict_put (subj_dict, c, 0);
  8896. }
  8897. all_subj_descs := dict_list_keys (subj_dict, 1);
  8898. all_s_count := length (all_subj_descs);
  8899. if (0 = all_s_count)
  8900. return res;
  8901. gvector_sort (all_subj_descs, 1, 0, 0);
  8902. if (__tag of integer = __tag (good_graphs))
  8903. graphs_listed := 0;
  8904. else
  8905. {
  8906. vectorbld_init (sorted_good_graphs);
  8907. foreach (any g in good_graphs) do
  8908. {
  8909. if (isiri_id (g) and g < min_bnode_iri_id () and
  8910. __rgs_ack_cbk (g, uid, 1) and
  8911. (gs_app_callback is null or bit_and (1, call (gs_app_callback) (g, gs_app_uid))) )
  8912. vectorbld_acc (sorted_good_graphs, g);
  8913. }
  8914. vectorbld_final (sorted_good_graphs);
  8915. good_g_count := length (sorted_good_graphs);
  8916. if (0 = good_g_count)
  8917. return res;
  8918. graphs_listed := 1;
  8919. }
  8920. vectorbld_init (sorted_bad_graphs);
  8921. foreach (any g in bad_graphs) do
  8922. {
  8923. if (isiri_id (g) and g < min_bnode_iri_id ())
  8924. vectorbld_acc (sorted_bad_graphs, g);
  8925. }
  8926. vectorbld_final (sorted_bad_graphs);
  8927. bad_g_count := length (sorted_bad_graphs);
  8928. vectorbld_init (phys_subjects);
  8929. for (s_ctr := 0; s_ctr < all_s_count; s_ctr := s_ctr + 1)
  8930. {
  8931. declare s, phys_s any;
  8932. s := all_subj_descs [s_ctr];
  8933. if (isiri_id (s))
  8934. vectorbld_acc (phys_subjects, s);
  8935. else
  8936. {
  8937. phys_s := iri_to_id (s, 0, 0);
  8938. if (not isinteger (phys_s))
  8939. vectorbld_acc (phys_subjects, phys_s);
  8940. }
  8941. }
  8942. vectorbld_final (phys_subjects);
  8943. gvector_sort (phys_subjects, 1, 0, 0);
  8944. phys_s_count := length (phys_subjects);
  8945. -- dbg_obj_princ ('phys_subjects = ', phys_subjects);
  8946. if (0 = phys_s_count)
  8947. return res;
  8948. -- dbg_obj_princ ('sorted_bad_graphs = ', sorted_bad_graphs);
  8949. if (graphs_listed)
  8950. {
  8951. gvector_sort (sorted_good_graphs, 1, 0, 0);
  8952. -- dbg_obj_princ ('sorted_good_graphs = ', sorted_good_graphs);
  8953. for (g_ctr := good_g_count - 1; g_ctr >= 0; g_ctr := g_ctr - 1)
  8954. {
  8955. declare graph any;
  8956. graph := sorted_good_graphs [g_ctr];
  8957. for (s_ctr := phys_s_count - 1; s_ctr >= 0; s_ctr := s_ctr - 1)
  8958. {
  8959. declare subj any;
  8960. subj := phys_subjects [s_ctr];
  8961. for (select P as p1, O as obj1 from DB.DBA.RDF_QUAD where G = graph and S = subj) do
  8962. {
  8963. -- dbg_obj_princ ('found5 ', subj, p1, ' in ', graph);
  8964. dict_bitor_or_put (res, vector (subj, p1, __rdf_long_of_obj (obj1)), 1);
  8965. }
  8966. }
  8967. }
  8968. return res;
  8969. }
  8970. g_dict := dict_new ();
  8971. for (s_ctr := phys_s_count - 1; s_ctr >= 0; s_ctr := s_ctr - 1)
  8972. {
  8973. declare subj, graph any;
  8974. subj := phys_subjects [s_ctr];
  8975. graph := coalesce ((select top 1 G as g1 from DB.DBA.RDF_QUAD where O = subj and
  8976. 0 = position (G, sorted_bad_graphs) and
  8977. __rgs_ack_cbk (G, uid, 1) and
  8978. (gs_app_callback is null or bit_and (1, call (gs_app_callback) (G, gs_app_uid))) ) );
  8979. if (graph is not null)
  8980. dict_put (g_dict, graph, 0);
  8981. }
  8982. sorted_good_graphs := dict_list_keys (g_dict, 1);
  8983. if (0 = length (sorted_good_graphs))
  8984. {
  8985. g_dict := dict_new ();
  8986. for (s_ctr := phys_s_count - 1; s_ctr >= 0; s_ctr := s_ctr - 1)
  8987. {
  8988. declare subj, graph any;
  8989. subj := phys_subjects [s_ctr];
  8990. graph := coalesce ((select top 1 G as g1 from DB.DBA.RDF_QUAD where S = subj and P = rdf_type_iid and
  8991. 0 = position (G, sorted_bad_graphs) and
  8992. __rgs_ack_cbk (G, uid, 1) and
  8993. (gs_app_callback is null or bit_and (1, call (gs_app_callback) (G, gs_app_uid))) ) );
  8994. if (graph is not null)
  8995. dict_put (g_dict, graph, 0);
  8996. }
  8997. sorted_good_graphs := dict_list_keys (g_dict, 1);
  8998. }
  8999. -- dbg_obj_princ ('sorted_good_graphs = ', sorted_good_graphs);
  9000. gvector_sort (sorted_good_graphs, 1, 0, 0);
  9001. good_g_count := length (sorted_good_graphs);
  9002. -- dbg_obj_princ ('sorted_good_graphs = ', sorted_good_graphs);
  9003. for (g_ctr := good_g_count - 1; g_ctr >= 0; g_ctr := g_ctr - 1)
  9004. {
  9005. declare graph any;
  9006. graph := sorted_good_graphs [g_ctr];
  9007. for (s_ctr := phys_s_count - 1; s_ctr >= 0; s_ctr := s_ctr - 1)
  9008. {
  9009. declare subj any;
  9010. subj := phys_subjects [s_ctr];
  9011. for (select P as p1, O as obj1 from DB.DBA.RDF_QUAD where G = graph and S = subj) do
  9012. {
  9013. -- dbg_obj_princ ('found6 ', subj, p1, ' in ', graph);
  9014. dict_bitor_or_put (res, vector (subj, p1, __rdf_long_of_obj (obj1)), 1);
  9015. -- if (isiri_id (obj1))
  9016. -- {
  9017. -- for (select P as p2, O as obj2
  9018. -- from DB.DBA.RDF_QUAD
  9019. -- where G = graph and S = obj1 and not (isiri_id (O)) ) do
  9020. -- {
  9021. -- dict_bitor_or_put (dict, vector (obj1, p2, __rdf_long_of_obj (obj2)), 17);
  9022. -- }
  9023. -- }
  9024. }
  9025. -- for (select S as s1, P as p1 from DB.DBA.RDF_QUAD
  9026. -- where G = graph and O = subj and P <> rdf_type_iid
  9027. -- option (QUIETCAST)) do
  9028. -- {
  9029. -- dbg_obj_princ ('found7 ', s1, p1, subj, ' in ', graph);
  9030. -- dict_bitor_or_put (res, vector (s1, p1, subj), 4);
  9031. -- }
  9032. }
  9033. }
  9034. -- dbg_obj_princ ('final result is ', res);
  9035. return res;
  9036. }
  9037. ;
  9038. create procedure DB.DBA.SPARQL_DESC_DICT_CBD (in subj_dict any, in consts any, in good_graphs any, in bad_graphs any, in storage_name any, in options any)
  9039. {
  9040. declare all_subjs, phys_subjects, sorted_good_graphs, sorted_bad_graphs, next_iter_subjs, res any;
  9041. declare uid, graphs_listed, g_ctr, good_g_count, bad_g_count, s_ctr, all_s_count, phys_s_count integer;
  9042. declare gs_app_callback, gs_app_uid, inf_ruleset varchar;
  9043. declare rdf_type_iid IRI_ID;
  9044. uid := get_keyword ('uid', options, http_nobody_uid());
  9045. gs_app_callback := get_keyword ('gs-app-callback', options);
  9046. if (gs_app_callback is not null)
  9047. gs_app_uid := get_keyword ('gs-app-uid', options);
  9048. inf_ruleset := get_keyword ('inference', options);
  9049. rdf_type_iid := iri_to_id (UNAME'http://www.w3.org/1999/02/22-rdf-syntax-ns#type');
  9050. res := dict_new ();
  9051. if (isinteger (consts))
  9052. return res;
  9053. foreach (any c in consts) do
  9054. {
  9055. if (isiri_id (c))
  9056. dict_put (subj_dict, c, 0);
  9057. }
  9058. all_subjs := dict_list_keys (subj_dict, 0);
  9059. next_iter_subjs := dict_new ();
  9060. all_s_count := length (all_subjs);
  9061. if (0 = all_s_count)
  9062. return res;
  9063. next_iteration:
  9064. all_s_count := length (all_subjs);
  9065. gvector_sort (all_subjs, 1, 0, 0);
  9066. -- dbg_obj_princ ('new iteration: all_subjs = ', all_subjs);
  9067. if (__tag of integer = __tag (good_graphs))
  9068. graphs_listed := 0;
  9069. else
  9070. {
  9071. vectorbld_init (sorted_good_graphs);
  9072. foreach (any g in good_graphs) do
  9073. {
  9074. if (isiri_id (g) and g < min_bnode_iri_id () and
  9075. __rgs_ack_cbk (g, uid, 1) and
  9076. (gs_app_callback is null or bit_and (1, call (gs_app_callback) (g, gs_app_uid))) )
  9077. vectorbld_acc (sorted_good_graphs, g);
  9078. }
  9079. vectorbld_final (sorted_good_graphs);
  9080. good_g_count := length (sorted_good_graphs);
  9081. if (0 = good_g_count)
  9082. return res;
  9083. graphs_listed := 1;
  9084. }
  9085. vectorbld_init (sorted_bad_graphs);
  9086. foreach (any g in bad_graphs) do
  9087. {
  9088. if (isiri_id (g) and g < min_bnode_iri_id ())
  9089. vectorbld_acc (sorted_bad_graphs, g);
  9090. }
  9091. vectorbld_final (sorted_bad_graphs);
  9092. bad_g_count := length (sorted_bad_graphs);
  9093. vectorbld_init (phys_subjects);
  9094. if (storage_name is null)
  9095. storage_name := 'http://www.openlinksw.com/schemas/virtrdf#DefaultQuadStorage';
  9096. else if (('' = storage_name) and (inf_ruleset is null))
  9097. {
  9098. for (s_ctr := 0; s_ctr < all_s_count; s_ctr := s_ctr + 1)
  9099. {
  9100. declare s, phys_s any;
  9101. s := all_subjs [s_ctr];
  9102. if (isiri_id (s))
  9103. vectorbld_acc (phys_subjects, s);
  9104. else
  9105. {
  9106. phys_s := iri_to_id (s, 0, 0);
  9107. if (not isinteger (phys_s))
  9108. vectorbld_acc (phys_subjects, phys_s);
  9109. }
  9110. }
  9111. vectorbld_final (phys_subjects);
  9112. goto describe_physical_subjects;
  9113. }
  9114. -- dbg_obj_princ ('storage_name=',storage_name, ' sorted_good_graphs=', sorted_good_graphs, ' sorted_bad_graphs=', sorted_bad_graphs);
  9115. for (s_ctr := 0; s_ctr < all_s_count; s_ctr := s_ctr + 1)
  9116. {
  9117. declare s, phys_s, maps any;
  9118. declare maps_len integer;
  9119. s := all_subjs [s_ctr];
  9120. maps := sparql_quad_maps_for_quad (NULL, s, NULL, NULL, storage_name, case (graphs_listed) when 0 then vector() else sorted_good_graphs end, sorted_bad_graphs);
  9121. -- dbg_obj_princ ('s = ', s, id_to_iri (s), ' maps = ', maps);
  9122. maps_len := length (maps);
  9123. if ((maps_len > 0) and (inf_ruleset is null) and (maps[maps_len-1][0] = UNAME'http://www.openlinksw.com/schemas/virtrdf#DefaultQuadMap'))
  9124. {
  9125. if (isiri_id (s))
  9126. {
  9127. phys_s := s;
  9128. vectorbld_acc (phys_subjects, phys_s);
  9129. }
  9130. else
  9131. {
  9132. phys_s := iri_to_id (s, 0, 0);
  9133. if (not isinteger (phys_s))
  9134. vectorbld_acc (phys_subjects, phys_s);
  9135. }
  9136. maps := subseq (maps, 0, maps_len-1);
  9137. maps_len := maps_len - 1;
  9138. }
  9139. if (maps_len > 0)
  9140. all_subjs [s_ctr] := vector (s, maps);
  9141. else
  9142. all_subjs [s_ctr] := 0;
  9143. -- dbg_obj_princ ('s = ', s, ' maps = ', maps);
  9144. -- dbg_obj_princ ('all_subjs [', s_ctr, '] = ', all_subjs [s_ctr]);
  9145. }
  9146. vectorbld_final (phys_subjects);
  9147. for (s_ctr := 0; s_ctr < all_s_count; s_ctr := s_ctr + 1)
  9148. {
  9149. declare s_desc, s, maps any;
  9150. declare map_ctr, maps_len integer;
  9151. declare fname varchar;
  9152. s_desc := all_subjs [s_ctr];
  9153. if (isinteger (s_desc))
  9154. goto end_of_s;
  9155. s := s_desc[0];
  9156. maps := s_desc[1];
  9157. maps_len := length (maps);
  9158. fname := sprintf ('SPARQL_DESC_DICT_CBD_QMV1_%U', md5 (storage_name || inf_ruleset || cast (graphs_listed as varchar) || md5_box (maps) || md5_box (sorted_bad_graphs)));
  9159. if (not exists (select top 1 1 from Db.DBA.SYS_PROCEDURES where P_NAME = 'DB.DBA.' || fname))
  9160. {
  9161. declare ses, txt, saved_user any;
  9162. ses := string_output ();
  9163. http ('create procedure DB.DBA."' || fname || '" (in subj any, in subj_dict any, in next_iter_subjs any, in res any', ses);
  9164. if (graphs_listed)
  9165. http (', inout sorted_good_graphs any', ses);
  9166. http (')\n', ses);
  9167. http ('{\n', ses);
  9168. http (' declare subj_iri varchar;\n', ses);
  9169. http (' subj_iri := id_to_iri_nosignal (subj);\n', ses);
  9170. if (maps_len > 0)
  9171. {
  9172. http (' for (sparql define output:valmode "LONG" define input:storage <' || storage_name || '> ', ses);
  9173. foreach (any g in sorted_bad_graphs) do
  9174. {
  9175. http (' define input:named-graph-exclude <' || id_to_iri_nosignal (g) || '>\n', ses);
  9176. }
  9177. if (inf_ruleset is not null)
  9178. http (' define input:inference <' || inf_ruleset || '>\n', ses);
  9179. http ('select ?g1 ?p1 ?o1 ?g2 ?st2\n', ses);
  9180. http (' where { graph ?g1 {\n', ses);
  9181. for (map_ctr := 0; map_ctr < maps_len; map_ctr := map_ctr + 1)
  9182. {
  9183. if (map_ctr > 0) http (' union\n', ses);
  9184. http (' { quad map <' || maps[map_ctr][0] || '> { ?:subj_iri ?p1 ?o1 } }\n', ses);
  9185. }
  9186. http (' }\n', ses);
  9187. http (' optional { graph ?g2 {\n', ses);
  9188. http (' ?st2 a rdf:Statement ; rdf:subject ?:subj_iri ; rdf:predicate ?p1 ; rdf:object ?o1 } }\n', ses);
  9189. http (' } ) do {\n', ses);
  9190. if (graphs_listed)
  9191. http (' if (position (__i2idn ("g1"), sorted_good_graphs)) {\n', ses);
  9192. http (' dict_bitor_or_put (res, vector (subj, "p1", "o1"), 1);\n', ses);
  9193. http (' if (isiri_id ("o1") and "o1" > min_bnode_iri_id() and dict_get (subj_dict, "o1") is null)\n', ses);
  9194. http (' dict_put (next_iter_subjs, "o1", 1);\n', ses);
  9195. if (graphs_listed)
  9196. http (' if (position (__i2idn ("g2"), sorted_good_graphs)) {\n', ses);
  9197. http (' if ("st2" is not null and dict_get (subj_dict, "st2") is null)\n', ses);
  9198. http (' dict_put (next_iter_subjs, "o1", 1);\n', ses);
  9199. if (graphs_listed)
  9200. http (' } }\n', ses);
  9201. http (' }\n', ses);
  9202. }
  9203. http ('}\n', ses);
  9204. txt := string_output_string (ses);
  9205. -- dbg_obj_princ ('Procedure text: ', txt);
  9206. saved_user := user;
  9207. set_user_id ('dba', 1);
  9208. exec (txt);
  9209. set_user_id (saved_user);
  9210. }
  9211. if (graphs_listed)
  9212. {
  9213. -- dbg_obj_princ ('call (''DB.DBA.', fname, ''')(', s, subj_dict, next_iter_subjs, res, sorted_good_graphs, ')');
  9214. call ('DB.DBA.' || fname)(s, subj_dict, next_iter_subjs, res, sorted_good_graphs);
  9215. }
  9216. else
  9217. {
  9218. -- dbg_obj_princ ('call (''DB.DBA.', fname, ''')(', s, subj_dict, next_iter_subjs, res, ')');
  9219. call ('DB.DBA.' || fname)(s, subj_dict, next_iter_subjs, res);
  9220. }
  9221. end_of_s: ;
  9222. }
  9223. describe_physical_subjects:
  9224. gvector_sort (phys_subjects, 1, 0, 0);
  9225. phys_s_count := length (phys_subjects);
  9226. -- dbg_obj_princ ('phys_subjects = ', phys_subjects);
  9227. if (0 = phys_s_count)
  9228. return res;
  9229. -- dbg_obj_princ ('sorted_bad_graphs = ', sorted_bad_graphs);
  9230. if (graphs_listed)
  9231. {
  9232. gvector_sort (sorted_good_graphs, 1, 0, 0);
  9233. -- dbg_obj_princ ('sorted_good_graphs = ', sorted_good_graphs);
  9234. for (g_ctr := good_g_count - 1; g_ctr >= 0; g_ctr := g_ctr - 1)
  9235. {
  9236. declare graph any;
  9237. graph := sorted_good_graphs [g_ctr];
  9238. for (s_ctr := phys_s_count - 1; s_ctr >= 0; s_ctr := s_ctr - 1)
  9239. {
  9240. declare subj any;
  9241. subj := phys_subjects [s_ctr];
  9242. for (select P as p1, O as obj1 from DB.DBA.RDF_QUAD where G = graph and S = subj) do
  9243. {
  9244. -- dbg_obj_princ ('found3 ', subj, p1, ' in ', graph);
  9245. dict_bitor_or_put (res, vector (subj, p1, __rdf_long_of_obj (obj1)), 1);
  9246. if (isiri_id (obj1) and obj1 > min_bnode_iri_id() and dict_get (subj_dict, obj1) is null)
  9247. dict_put (next_iter_subjs, obj1, 1);
  9248. for (sparql define output:valmode "LONG"
  9249. select ?g2 ?st2 where {
  9250. graph ?g2 {
  9251. ?st2 a rdf:Statement ; rdf:subject ?:subj ; rdf:predicate ?:p1 ; rdf:object ?:obj1 } } ) do
  9252. {
  9253. if (position ("g2", sorted_good_graphs) and dict_get (subj_dict, "st2") is null)
  9254. dict_put (next_iter_subjs, "st2", 1);
  9255. }
  9256. }
  9257. }
  9258. }
  9259. }
  9260. else
  9261. {
  9262. for (s_ctr := phys_s_count - 1; s_ctr >= 0; s_ctr := s_ctr - 1)
  9263. {
  9264. declare subj any;
  9265. subj := phys_subjects [s_ctr];
  9266. for (select P as p1, O as obj1 from DB.DBA.RDF_QUAD where
  9267. 0 = position (G, sorted_bad_graphs) and
  9268. S = subj and
  9269. __rgs_ack_cbk (G, uid, 1) and
  9270. (gs_app_callback is null or bit_and (1, call (gs_app_callback) (G, gs_app_uid))) ) do
  9271. {
  9272. -- dbg_obj_princ ('found4 ', subj, p1);
  9273. dict_bitor_or_put (res, vector (subj, p1, __rdf_long_of_obj (obj1)), 1);
  9274. if (isiri_id (obj1) and obj1 > min_bnode_iri_id() and dict_get (subj_dict, obj1) is null)
  9275. dict_put (next_iter_subjs, obj1, 1);
  9276. for (sparql define output:valmode "LONG"
  9277. select ?g2 ?st2 where {
  9278. graph ?g2 {
  9279. ?st2 a rdf:Statement ; rdf:subject ?:subj ; rdf:predicate ?:p1 ; rdf:object ?:obj1 } } ) do
  9280. {
  9281. if (0 = position ("g2", sorted_bad_graphs) and
  9282. dict_get (subj_dict, "st2") is null and
  9283. __rgs_ack_cbk ("g2", uid, 1) and
  9284. (gs_app_callback is null or bit_and (1, call (gs_app_callback) ("g2", gs_app_uid))) )
  9285. dict_put (next_iter_subjs, "st2", 1);
  9286. }
  9287. }
  9288. }
  9289. }
  9290. ret_or_next_iter:
  9291. if (0 = dict_size (next_iter_subjs))
  9292. {
  9293. -- dbg_obj_princ ('no new subjs, res = ', dict_list_keys (res, 0));
  9294. return res;
  9295. }
  9296. all_subjs := dict_list_keys (next_iter_subjs, 1);
  9297. foreach (IRI_ID s in all_subjs) do dict_put (subj_dict, s, 1);
  9298. goto next_iteration;
  9299. }
  9300. ;
  9301. create procedure DB.DBA.SPARQL_DESC_DICT_CBD_PHYSICAL (in subj_dict any, in consts any, in good_graphs any, in bad_graphs any, in storage_name any, in options any)
  9302. {
  9303. declare all_subjs, sorted_good_graphs, sorted_bad_graphs, next_iter_subjs, res any;
  9304. declare uid, graphs_listed, g_ctr, good_g_count, bad_g_count, s_ctr, all_s_count integer;
  9305. declare gs_app_callback, gs_app_uid varchar;
  9306. declare rdf_type_iid IRI_ID;
  9307. uid := get_keyword ('uid', options, http_nobody_uid());
  9308. gs_app_callback := get_keyword ('gs-app-callback', options);
  9309. if (gs_app_callback is not null)
  9310. gs_app_uid := get_keyword ('gs-app-uid', options);
  9311. rdf_type_iid := iri_to_id (UNAME'http://www.w3.org/1999/02/22-rdf-syntax-ns#type');
  9312. res := dict_new ();
  9313. if (isinteger (consts))
  9314. return res;
  9315. foreach (any c in consts) do
  9316. {
  9317. if (isiri_id (c))
  9318. dict_put (subj_dict, c, 0);
  9319. }
  9320. all_subjs := dict_list_keys (subj_dict, 0);
  9321. next_iter_subjs := dict_new ();
  9322. all_s_count := length (all_subjs);
  9323. if (0 = all_s_count)
  9324. return res;
  9325. next_iteration:
  9326. all_s_count := length (all_subjs);
  9327. gvector_sort (all_subjs, 1, 0, 0);
  9328. -- dbg_obj_princ ('new iteration: all_subjs = ', all_subjs);
  9329. if (__tag of integer = __tag (good_graphs))
  9330. graphs_listed := 0;
  9331. else
  9332. {
  9333. vectorbld_init (sorted_good_graphs);
  9334. foreach (any g in good_graphs) do
  9335. {
  9336. if (isiri_id (g) and g < min_bnode_iri_id () and
  9337. __rgs_ack_cbk (g, uid, 1) and
  9338. (gs_app_callback is null or bit_and (1, call (gs_app_callback) (g, gs_app_uid))) )
  9339. vectorbld_acc (sorted_good_graphs, g);
  9340. }
  9341. vectorbld_final (sorted_good_graphs);
  9342. good_g_count := length (sorted_good_graphs);
  9343. if (0 = good_g_count)
  9344. return res;
  9345. graphs_listed := 1;
  9346. }
  9347. vectorbld_init (sorted_bad_graphs);
  9348. foreach (any g in bad_graphs) do
  9349. {
  9350. if (isiri_id (g) and g < min_bnode_iri_id ())
  9351. vectorbld_acc (sorted_bad_graphs, g);
  9352. }
  9353. vectorbld_final (sorted_bad_graphs);
  9354. bad_g_count := length (sorted_bad_graphs);
  9355. -- dbg_obj_princ ('all_subjs = ', all_subjs);
  9356. if (0 = all_s_count)
  9357. return res;
  9358. -- dbg_obj_princ ('sorted_bad_graphs = ', sorted_bad_graphs);
  9359. if (graphs_listed)
  9360. {
  9361. gvector_sort (sorted_good_graphs, 1, 0, 0);
  9362. -- dbg_obj_princ ('sorted_good_graphs = ', sorted_good_graphs);
  9363. for (g_ctr := good_g_count - 1; g_ctr >= 0; g_ctr := g_ctr - 1)
  9364. {
  9365. declare graph any;
  9366. graph := sorted_good_graphs [g_ctr];
  9367. for (s_ctr := all_s_count - 1; s_ctr >= 0; s_ctr := s_ctr - 1)
  9368. {
  9369. declare subj any;
  9370. subj := all_subjs [s_ctr];
  9371. for (select P as p1, O as obj1 from DB.DBA.RDF_QUAD where G = graph and S = subj) do
  9372. {
  9373. -- dbg_obj_princ ('found3 ', subj, p1, ' in ', graph);
  9374. dict_bitor_or_put (res, vector (subj, p1, __rdf_long_of_obj (obj1)), 1);
  9375. if (isiri_id (obj1) and obj1 > min_bnode_iri_id() and dict_get (subj_dict, obj1) is null)
  9376. dict_put (next_iter_subjs, obj1, 1);
  9377. for (sparql define output:valmode "LONG"
  9378. select ?g2 ?st2 where {
  9379. graph ?g2 {
  9380. ?st2 a rdf:Statement ; rdf:subject ?:subj ; rdf:predicate ?:p1 ; rdf:object ?:obj1 } } ) do
  9381. {
  9382. if (position ("g2", sorted_good_graphs) and dict_get (subj_dict, "st2") is null)
  9383. dict_put (next_iter_subjs, "st2", 1);
  9384. }
  9385. }
  9386. }
  9387. }
  9388. }
  9389. else
  9390. {
  9391. for (s_ctr := all_s_count - 1; s_ctr >= 0; s_ctr := s_ctr - 1)
  9392. {
  9393. declare subj any;
  9394. subj := all_subjs [s_ctr];
  9395. for (select P as p1, O as obj1 from DB.DBA.RDF_QUAD where
  9396. 0 = position (G, sorted_bad_graphs) and
  9397. S = subj and
  9398. __rgs_ack_cbk (G, uid, 1) and
  9399. (gs_app_callback is null or bit_and (1, call (gs_app_callback) (G, gs_app_uid))) ) do
  9400. {
  9401. -- dbg_obj_princ ('found4 ', subj, p1);
  9402. dict_bitor_or_put (res, vector (subj, p1, __rdf_long_of_obj (obj1)), 1);
  9403. if (isiri_id (obj1) and obj1 > min_bnode_iri_id() and dict_get (subj_dict, obj1) is null)
  9404. dict_put (next_iter_subjs, obj1, 1);
  9405. for (sparql define output:valmode "LONG"
  9406. select ?g2 ?st2 where {
  9407. graph ?g2 {
  9408. ?st2 a rdf:Statement ; rdf:subject ?:subj ; rdf:predicate ?:p1 ; rdf:object ?:obj1 } } ) do
  9409. {
  9410. if (0 = position ("g2", sorted_bad_graphs) and
  9411. dict_get (subj_dict, "st2") is null and
  9412. __rgs_ack_cbk ("g2", uid, 1) and
  9413. (gs_app_callback is null or bit_and (1, call (gs_app_callback) ("g2", gs_app_uid))) )
  9414. dict_put (next_iter_subjs, "st2", 1);
  9415. }
  9416. }
  9417. }
  9418. }
  9419. ret_or_next_iter:
  9420. if (0 = dict_size (next_iter_subjs))
  9421. {
  9422. -- dbg_obj_princ ('no new subjs, res = ', dict_list_keys (res, 0));
  9423. return res;
  9424. }
  9425. all_subjs := dict_list_keys (next_iter_subjs, 1);
  9426. foreach (IRI_ID s in all_subjs) do dict_put (subj_dict, s, 1);
  9427. goto next_iteration;
  9428. }
  9429. ;
  9430. create procedure DB.DBA.SPARQL_DESC_DICT_OBJCBD (in obj_dict any, in consts any, in good_graphs any, in bad_graphs any, in storage_name any, in options any)
  9431. {
  9432. declare all_objs, phys_objects, sorted_good_graphs, sorted_bad_graphs, next_iter_objs, res any;
  9433. declare uid, graphs_listed, g_ctr, good_g_count, bad_g_count, obj_ctr, all_obj_count, phys_obj_count integer;
  9434. declare gs_app_callback, gs_app_uid, inf_ruleset varchar;
  9435. declare rdf_type_iid IRI_ID;
  9436. uid := get_keyword ('uid', options, http_nobody_uid());
  9437. gs_app_callback := get_keyword ('gs-app-callback', options);
  9438. if (gs_app_callback is not null)
  9439. gs_app_uid := get_keyword ('gs-app-uid', options);
  9440. inf_ruleset := get_keyword ('inference', options);
  9441. rdf_type_iid := iri_to_id (UNAME'http://www.w3.org/1999/02/22-rdf-syntax-ns#type');
  9442. res := dict_new ();
  9443. if (isinteger (consts))
  9444. return res;
  9445. foreach (any c in consts) do
  9446. {
  9447. if (not isnumeric (c))
  9448. dict_put (obj_dict, c, 0);
  9449. }
  9450. all_objs := dict_list_keys (obj_dict, 0);
  9451. next_iter_objs := dict_new ();
  9452. all_obj_count := length (all_objs);
  9453. if (0 = all_obj_count)
  9454. return res;
  9455. next_iteration:
  9456. all_obj_count := length (all_objs);
  9457. gvector_sort (all_objs, 1, 0, 0);
  9458. -- dbg_obj_princ ('new iteration: all_objs = ', all_objs);
  9459. if (__tag of integer = __tag (good_graphs))
  9460. graphs_listed := 0;
  9461. else
  9462. {
  9463. vectorbld_init (sorted_good_graphs);
  9464. foreach (any g in good_graphs) do
  9465. {
  9466. if (is_named_iri_id (g) and
  9467. __rgs_ack_cbk (g, uid, 1) and
  9468. (gs_app_callback is null or bit_and (1, call (gs_app_callback) (g, gs_app_uid))) )
  9469. vectorbld_acc (sorted_good_graphs, g);
  9470. }
  9471. vectorbld_final (sorted_good_graphs);
  9472. good_g_count := length (sorted_good_graphs);
  9473. if (0 = good_g_count)
  9474. return res;
  9475. graphs_listed := 1;
  9476. }
  9477. vectorbld_init (sorted_bad_graphs);
  9478. foreach (any g in bad_graphs) do
  9479. {
  9480. if (is_named_iri_id (g))
  9481. vectorbld_acc (sorted_bad_graphs, g);
  9482. }
  9483. vectorbld_final (sorted_bad_graphs);
  9484. bad_g_count := length (sorted_bad_graphs);
  9485. vectorbld_init (phys_objects);
  9486. if (storage_name is null)
  9487. storage_name := 'http://www.openlinksw.com/schemas/virtrdf#DefaultQuadStorage';
  9488. else if (('' = storage_name) and (inf_ruleset is null))
  9489. {
  9490. for (obj_ctr := 0; obj_ctr < all_obj_count; obj_ctr := obj_ctr + 1)
  9491. {
  9492. declare obj, phys_obj any;
  9493. obj := all_objs [obj_ctr];
  9494. if (not isnumeric (obj))
  9495. {
  9496. if (isiri_id (obj))
  9497. vectorbld_acc (phys_objects, obj);
  9498. else
  9499. {
  9500. phys_obj := iri_to_id (obj, 0, 0);
  9501. if (not isinteger (phys_obj))
  9502. vectorbld_acc (phys_objects, phys_obj);
  9503. }
  9504. }
  9505. }
  9506. vectorbld_final (phys_objects);
  9507. goto describe_physical_objects;
  9508. }
  9509. -- dbg_obj_princ ('storage_name=',storage_name, ' sorted_good_graphs=', sorted_good_graphs, ' sorted_bad_graphs=', sorted_bad_graphs);
  9510. for (obj_ctr := 0; obj_ctr < all_obj_count; obj_ctr := obj_ctr + 1)
  9511. {
  9512. declare obj, phys_obj, maps any;
  9513. declare maps_len integer;
  9514. obj := all_objs [obj_ctr];
  9515. maps := sparql_quad_maps_for_quad (NULL, NULL, NULL, obj, storage_name, case (graphs_listed) when 0 then vector() else sorted_good_graphs end, sorted_bad_graphs);
  9516. -- dbg_obj_princ ('obj = ', obj, id_to_iri (obj), ' maps = ', maps);
  9517. maps_len := length (maps);
  9518. if ((maps_len > 0) and (inf_ruleset is null) and (maps[maps_len-1][0] = UNAME'http://www.openlinksw.com/schemas/virtrdf#DefaultQuadMap'))
  9519. {
  9520. if (not isnumeric (obj))
  9521. {
  9522. if (isiri_id (obj))
  9523. {
  9524. phys_obj := obj;
  9525. vectorbld_acc (phys_objects, phys_obj);
  9526. }
  9527. else
  9528. {
  9529. phys_obj := iri_to_id (obj, 0, 0);
  9530. if (not isinteger (phys_obj))
  9531. vectorbld_acc (phys_objects, phys_obj);
  9532. }
  9533. }
  9534. maps := subseq (maps, 0, maps_len-1);
  9535. maps_len := maps_len - 1;
  9536. }
  9537. if (maps_len > 0)
  9538. all_objs [obj_ctr] := vector (obj, maps);
  9539. else
  9540. all_objs [obj_ctr] := 0;
  9541. -- dbg_obj_princ ('obj = ', obj, ' maps = ', maps);
  9542. -- dbg_obj_princ ('all_objs [', obj_ctr, '] = ', all_objs [obj_ctr]);
  9543. }
  9544. vectorbld_final (phys_objects);
  9545. for (obj_ctr := 0; obj_ctr < all_obj_count; obj_ctr := obj_ctr + 1)
  9546. {
  9547. declare s_desc, obj, maps any;
  9548. declare map_ctr, maps_len integer;
  9549. declare fname varchar;
  9550. s_desc := all_objs [obj_ctr];
  9551. if (isinteger (s_desc))
  9552. goto end_of_s;
  9553. obj := s_desc[0];
  9554. maps := s_desc[1];
  9555. maps_len := length (maps);
  9556. fname := sprintf ('SPARQL_DESC_DICT_OBJCBD_QMV1_%U', md5 (storage_name || inf_ruleset || cast (graphs_listed as varchar) || md5_box (maps) || md5_box (sorted_bad_graphs)));
  9557. if (not exists (select top 1 1 from Db.DBA.SYS_PROCEDURES where P_NAME = 'DB.DBA.' || fname))
  9558. {
  9559. declare ses, txt, saved_user any;
  9560. ses := string_output ();
  9561. http ('create procedure DB.DBA."' || fname || '" (in obj any, in obj_dict any, in next_iter_objs any, in res any', ses);
  9562. if (graphs_listed)
  9563. http (', inout sorted_good_graphs any', ses);
  9564. http (')\n', ses);
  9565. http ('{\n', ses);
  9566. http (' declare obj_iri varchar;\n', ses);
  9567. http (' obj_iri := id_to_iri_nosignal (obj);\n', ses);
  9568. if (maps_len > 0)
  9569. {
  9570. http (' for (sparql define output:valmode "LONG" define input:storage <' || storage_name || '> ', ses);
  9571. foreach (any g in sorted_bad_graphs) do
  9572. {
  9573. http (' define input:named-graph-exclude <' || id_to_iri_nosignal (g) || '>\n', ses);
  9574. }
  9575. if (inf_ruleset is not null)
  9576. http (' define input:inference <' || inf_ruleset || '>\n', ses);
  9577. http ('select ?g1 ?p1 ?s1 ?g2 ?st2\n', ses);
  9578. http (' where { graph ?g1 {\n', ses);
  9579. for (map_ctr := 0; map_ctr < maps_len; map_ctr := map_ctr + 1)
  9580. {
  9581. if (map_ctr > 0) http (' union\n', ses);
  9582. http (' { quad map <' || maps[map_ctr][0] || '> { ?s1 ?p1 ?:obj_iri } }\n', ses);
  9583. }
  9584. http (' }\n', ses);
  9585. http (' optional { graph ?g2 {\n', ses);
  9586. http (' ?st2 a rdf:Statement ; rdf:object ?:obj_iri ; rdf:predicate ?p1 ; rdf:subject ?s1 } }\n', ses);
  9587. http (' } ) do {\n', ses);
  9588. if (graphs_listed)
  9589. http (' if (position (__i2idn ("g1"), sorted_good_graphs)) {\n', ses);
  9590. http (' dict_bitor_or_put (res, vector ("s1", "p1", obj), 1);\n', ses);
  9591. http (' if (is_bnode_iri_id ("s1") and dict_get (obj_dict, "s1") is null)\n', ses);
  9592. http (' dict_put (next_iter_objs, "s1", 1);\n', ses);
  9593. if (graphs_listed)
  9594. http (' if (position (__i2idn ("g2"), sorted_good_graphs)) {\n', ses);
  9595. http (' if ("st2" is not null and dict_get (obj_dict, "st2") is null)\n', ses);
  9596. http (' dict_put (next_iter_objs, "s1", 1);\n', ses);
  9597. if (graphs_listed)
  9598. http (' } }\n', ses);
  9599. http (' }\n', ses);
  9600. }
  9601. http ('}\n', ses);
  9602. txt := string_output_string (ses);
  9603. -- dbg_obj_princ ('Procedure text: ', txt);
  9604. saved_user := user;
  9605. set_user_id ('dba', 1);
  9606. exec (txt);
  9607. set_user_id (saved_user);
  9608. }
  9609. if (graphs_listed)
  9610. {
  9611. -- dbg_obj_princ ('call (''DB.DBA.', fname, ''')(', obj, obj_dict, next_iter_objs, res, sorted_good_graphs, ')');
  9612. call ('DB.DBA.' || fname)(obj, obj_dict, next_iter_objs, res, sorted_good_graphs);
  9613. }
  9614. else
  9615. {
  9616. -- dbg_obj_princ ('call (''DB.DBA.', fname, ''')(', obj, obj_dict, next_iter_objs, res, ')');
  9617. call ('DB.DBA.' || fname)(obj, obj_dict, next_iter_objs, res);
  9618. }
  9619. end_of_s: ;
  9620. }
  9621. describe_physical_objects:
  9622. gvector_sort (phys_objects, 1, 0, 0);
  9623. phys_obj_count := length (phys_objects);
  9624. -- dbg_obj_princ ('phys_objects = ', phys_objects);
  9625. if (0 = phys_obj_count)
  9626. return res;
  9627. -- dbg_obj_princ ('sorted_bad_graphs = ', sorted_bad_graphs);
  9628. if (graphs_listed)
  9629. {
  9630. gvector_sort (sorted_good_graphs, 1, 0, 0);
  9631. -- dbg_obj_princ ('sorted_good_graphs = ', sorted_good_graphs);
  9632. for (g_ctr := good_g_count - 1; g_ctr >= 0; g_ctr := g_ctr - 1)
  9633. {
  9634. declare graph any;
  9635. graph := sorted_good_graphs [g_ctr];
  9636. for (obj_ctr := phys_obj_count - 1; obj_ctr >= 0; obj_ctr := obj_ctr - 1)
  9637. {
  9638. declare obj any;
  9639. obj := phys_objects [obj_ctr];
  9640. for (select P as p1, S as subj1 from DB.DBA.RDF_QUAD where G = graph and O = obj) do
  9641. {
  9642. -- dbg_obj_princ ('found3 ', subj1, p1, obj, ' in ', graph);
  9643. dict_bitor_or_put (res, vector (subj1, p1, __rdf_long_of_obj (obj)), 1);
  9644. if (is_bnode_iri_id (subj1) and dict_get (obj_dict, subj1) is null)
  9645. dict_put (next_iter_objs, subj1, 1);
  9646. for (sparql define output:valmode "LONG"
  9647. select ?g2 ?st2 where {
  9648. graph ?g2 {
  9649. ?st2 a rdf:Statement ; rdf:object ?:obj ; rdf:predicate ?:p1 ; rdf:subject ?:subj1 } } ) do
  9650. {
  9651. if (position ("g2", sorted_good_graphs) and dict_get (obj_dict, "st2") is null)
  9652. dict_put (next_iter_objs, "st2", 1);
  9653. }
  9654. }
  9655. }
  9656. }
  9657. }
  9658. else
  9659. {
  9660. for (obj_ctr := phys_obj_count - 1; obj_ctr >= 0; obj_ctr := obj_ctr - 1)
  9661. {
  9662. declare obj any;
  9663. obj := phys_objects [obj_ctr];
  9664. for (select P as p1, S as subj1 from DB.DBA.RDF_QUAD where
  9665. 0 = position (G, sorted_bad_graphs) and
  9666. O = obj and
  9667. __rgs_ack_cbk (G, uid, 1) and
  9668. (gs_app_callback is null or bit_and (1, call (gs_app_callback) (G, gs_app_uid))) ) do
  9669. {
  9670. -- dbg_obj_princ ('found4 ', obj, p1);
  9671. dict_bitor_or_put (res, vector (subj1, p1, __rdf_long_of_obj (obj)), 1);
  9672. if (is_bnode_iri_id (subj1) and dict_get (obj_dict, subj1) is null)
  9673. dict_put (next_iter_objs, subj1, 1);
  9674. for (sparql define output:valmode "LONG"
  9675. select ?g2 ?st2 where {
  9676. graph ?g2 {
  9677. ?st2 a rdf:Statement ; rdf:object ?:obj ; rdf:predicate ?:p1 ; rdf:subject ?:subj1 } } ) do
  9678. {
  9679. if (0 = position ("g2", sorted_bad_graphs) and
  9680. dict_get (obj_dict, "st2") is null and
  9681. __rgs_ack_cbk ("g2", uid, 1) and
  9682. (gs_app_callback is null or bit_and (1, call (gs_app_callback) ("g2", gs_app_uid))) )
  9683. dict_put (next_iter_objs, "st2", 1);
  9684. }
  9685. }
  9686. }
  9687. }
  9688. ret_or_next_iter:
  9689. if (0 = dict_size (next_iter_objs))
  9690. {
  9691. -- dbg_obj_princ ('no new objs, res = ', dict_list_keys (res, 0));
  9692. return res;
  9693. }
  9694. all_objs := dict_list_keys (next_iter_objs, 1);
  9695. foreach (IRI_ID obj in all_objs) do dict_put (obj_dict, obj, 1);
  9696. goto next_iteration;
  9697. }
  9698. ;
  9699. create procedure DB.DBA.SPARQL_DESC_DICT_OBJCBD_PHYSICAL (in obj_dict any, in consts any, in good_graphs any, in bad_graphs any, in storage_name any, in options any)
  9700. {
  9701. declare all_objs, sorted_good_graphs, sorted_bad_graphs, next_iter_objs, res any;
  9702. declare uid, graphs_listed, g_ctr, good_g_count, bad_g_count, obj_ctr, all_obj_count integer;
  9703. declare gs_app_callback, gs_app_uid varchar;
  9704. declare rdf_type_iid IRI_ID;
  9705. uid := get_keyword ('uid', options, http_nobody_uid());
  9706. gs_app_callback := get_keyword ('gs-app-callback', options);
  9707. if (gs_app_callback is not null)
  9708. gs_app_uid := get_keyword ('gs-app-uid', options);
  9709. rdf_type_iid := iri_to_id (UNAME'http://www.w3.org/1999/02/22-rdf-syntax-ns#type');
  9710. res := dict_new ();
  9711. if (isinteger (consts))
  9712. return res;
  9713. foreach (any c in consts) do
  9714. {
  9715. if (not isnumeric (c))
  9716. dict_put (obj_dict, c, 0);
  9717. }
  9718. all_objs := dict_list_keys (obj_dict, 0);
  9719. next_iter_objs := dict_new ();
  9720. all_obj_count := length (all_objs);
  9721. if (0 = all_obj_count)
  9722. return res;
  9723. next_iteration:
  9724. all_obj_count := length (all_objs);
  9725. gvector_sort (all_objs, 1, 0, 0);
  9726. -- dbg_obj_princ ('new iteration: all_objs = ', all_objs);
  9727. if (__tag of integer = __tag (good_graphs))
  9728. graphs_listed := 0;
  9729. else
  9730. {
  9731. vectorbld_init (sorted_good_graphs);
  9732. foreach (any g in good_graphs) do
  9733. {
  9734. if (is_named_iri_id (g) and
  9735. __rgs_ack_cbk (g, uid, 1) and
  9736. (gs_app_callback is null or bit_and (1, call (gs_app_callback) (g, gs_app_uid))) )
  9737. vectorbld_acc (sorted_good_graphs, g);
  9738. }
  9739. vectorbld_final (sorted_good_graphs);
  9740. good_g_count := length (sorted_good_graphs);
  9741. if (0 = good_g_count)
  9742. return res;
  9743. graphs_listed := 1;
  9744. }
  9745. vectorbld_init (sorted_bad_graphs);
  9746. foreach (any g in bad_graphs) do
  9747. {
  9748. if (isnamed_iri_id (g))
  9749. vectorbld_acc (sorted_bad_graphs, g);
  9750. }
  9751. vectorbld_final (sorted_bad_graphs);
  9752. bad_g_count := length (sorted_bad_graphs);
  9753. -- dbg_obj_princ ('all_objs = ', all_objs);
  9754. if (0 = all_obj_count)
  9755. return res;
  9756. -- dbg_obj_princ ('sorted_bad_graphs = ', sorted_bad_graphs);
  9757. if (graphs_listed)
  9758. {
  9759. gvector_sort (sorted_good_graphs, 1, 0, 0);
  9760. -- dbg_obj_princ ('sorted_good_graphs = ', sorted_good_graphs);
  9761. for (g_ctr := good_g_count - 1; g_ctr >= 0; g_ctr := g_ctr - 1)
  9762. {
  9763. declare graph any;
  9764. graph := sorted_good_graphs [g_ctr];
  9765. for (obj_ctr := all_obj_count - 1; obj_ctr >= 0; obj_ctr := obj_ctr - 1)
  9766. {
  9767. declare obj any;
  9768. obj := all_objs [obj_ctr];
  9769. for (select P as p1, S as subj1 from DB.DBA.RDF_QUAD where G = graph and O = obj) do
  9770. {
  9771. -- dbg_obj_princ ('found3 ', subj1, p1, obj, ' in ', graph);
  9772. dict_bitor_or_put (res, vector (subj1, p1, __rdf_long_of_obj (obj)), 1);
  9773. if (is_bnode_iri_id (subj1) and dict_get (obj_dict, subj1) is null)
  9774. dict_put (next_iter_objs, subj1, 1);
  9775. for (sparql define output:valmode "LONG"
  9776. select ?g2 ?st2 where {
  9777. graph ?g2 {
  9778. ?st2 a rdf:Statement ; rdf:object ?:obj ; rdf:predicate ?:p1 ; rdf:subject ?:subj1 } } ) do
  9779. {
  9780. if (position ("g2", sorted_good_graphs) and dict_get (obj_dict, "st2") is null)
  9781. dict_put (next_iter_objs, "st2", 1);
  9782. }
  9783. }
  9784. }
  9785. }
  9786. }
  9787. else
  9788. {
  9789. for (obj_ctr := all_obj_count - 1; obj_ctr >= 0; obj_ctr := obj_ctr - 1)
  9790. {
  9791. declare obj any;
  9792. obj := all_objs [obj_ctr];
  9793. for (select P as p1, S as subj1 from DB.DBA.RDF_QUAD where
  9794. 0 = position (G, sorted_bad_graphs) and
  9795. O = obj and
  9796. __rgs_ack_cbk (G, uid, 1) and
  9797. (gs_app_callback is null or bit_and (1, call (gs_app_callback) (G, gs_app_uid))) ) do
  9798. {
  9799. -- dbg_obj_princ ('found4 ', subj1, p1, obj);
  9800. dict_bitor_or_put (res, vector (subj1, p1, __rdf_long_of_obj (obj)), 1);
  9801. if (is_bnode_iri_id (subj1) and dict_get (obj_dict, subj1) is null)
  9802. dict_put (next_iter_objs, subj1, 1);
  9803. for (sparql define output:valmode "LONG"
  9804. select ?g2 ?st2 where {
  9805. graph ?g2 {
  9806. ?st2 a rdf:Statement ; rdf:object ?:obj ; rdf:predicate ?:p1 ; rdf:subject ?:subj1 } } ) do
  9807. {
  9808. if (0 = position ("g2", sorted_bad_graphs) and
  9809. dict_get (obj_dict, "st2") is null and
  9810. __rgs_ack_cbk ("g2", uid, 1) and
  9811. (gs_app_callback is null or bit_and (1, call (gs_app_callback) ("g2", gs_app_uid))) )
  9812. dict_put (next_iter_objs, "st2", 1);
  9813. }
  9814. }
  9815. }
  9816. }
  9817. ret_or_next_iter:
  9818. if (0 = dict_size (next_iter_objs))
  9819. {
  9820. -- dbg_obj_princ ('no new objs, res = ', dict_list_keys (res, 0));
  9821. return res;
  9822. }
  9823. all_objs := dict_list_keys (next_iter_objs, 1);
  9824. foreach (IRI_ID obj in all_objs) do dict_put (obj_dict, obj, 1);
  9825. goto next_iteration;
  9826. }
  9827. ;
  9828. create procedure DB.DBA.SPARQL_DESC_DICT_SCBD (in node_dict any, in consts any, in good_graphs any, in bad_graphs any, in storage_name any, in options any)
  9829. {
  9830. declare cbd_res, objcbd_res, triples any;
  9831. cbd_res := DB.DBA.SPARQL_DESC_DICT_CBD (node_dict, consts, good_graphs, bad_graphs, storage_name, options);
  9832. objcbd_res := DB.DBA.SPARQL_DESC_DICT_OBJCBD (node_dict, consts, good_graphs, bad_graphs, storage_name, options);
  9833. again:
  9834. triples := dict_destructive_list_rnd_keys (objcbd_res, 80000);
  9835. if (0 = length (triples))
  9836. return cbd_res;
  9837. foreach (any triple in triples) do { dict_put (cbd_res, triple, 1); }
  9838. goto again;
  9839. }
  9840. ;
  9841. create procedure DB.DBA.SPARQL_DESC_DICT_SCBD_PHYSICAL (in node_dict any, in consts any, in good_graphs any, in bad_graphs any, in storage_name any, in options any)
  9842. {
  9843. declare cbd_res, objcbd_res, triples any;
  9844. cbd_res := DB.DBA.SPARQL_DESC_DICT_CBD_PHYSICAL (node_dict, consts, good_graphs, bad_graphs, storage_name, options);
  9845. objcbd_res := DB.DBA.SPARQL_DESC_DICT_OBJCBD_PHYSICAL (node_dict, consts, good_graphs, bad_graphs, storage_name, options);
  9846. again:
  9847. triples := dict_destructive_list_rnd_keys (objcbd_res, 80000);
  9848. if (0 = length (triples))
  9849. return cbd_res;
  9850. foreach (any triple in triples) do { dict_put (cbd_res, triple, 1); }
  9851. goto again;
  9852. }
  9853. ;
  9854. --!AWK PUBLIC
  9855. create procedure DB.DBA.RDF_DICT_OF_TRIPLES_TO_THREE_COLS (in dict any, in destructive integer := 0)
  9856. {
  9857. declare ctr, len, max_batch_sz integer;
  9858. declare editable_dict, triples, O any;
  9859. declare S, P, O_DT, O_LANG varchar;
  9860. declare O_IS_IRI, dt_twobyte, lang_twobyte integer;
  9861. result_names (S, P, O);
  9862. max_batch_sz := __min (sys_stat ('dc_max_batch_sz'), 1000000);
  9863. editable_dict := null;
  9864. if (not destructive and dict_size (dict) > max_batch_sz)
  9865. editable_dict := dict_duplicate (dict);
  9866. next_batch:
  9867. if (editable_dict is not null)
  9868. {
  9869. if (dict_size (editable_dict))
  9870. triples := dict_destructive_list_rnd_keys (editable_dict, max_batch_sz);
  9871. else
  9872. return;
  9873. }
  9874. else
  9875. {
  9876. if (dict_size (dict))
  9877. {
  9878. if (dict_size (dict) > max_batch_sz)
  9879. triples := dict_destructive_list_rnd_keys (dict, max_batch_sz);
  9880. else
  9881. {
  9882. triples := dict_list_keys (dict, destructive);
  9883. dict := null;
  9884. }
  9885. }
  9886. else
  9887. return;
  9888. }
  9889. DB.DBA.RDF_TRIPLES_BATCH_COMPLETE (triples);
  9890. -- exec_result_names (vector (vector ('S', 182, 0, 4072, 1, 0, 1, 0, 0, 0, 0, 0), vector ('P', 182, 0, 4072, 1, 0, 1, 0, 0, 0, 0, 0), vector ('O', 125, 0, 2147483647, 1, 0, 0, 0, 0, 0, 0, 0)));
  9891. len := length (triples);
  9892. for (ctr := 0; ctr < len; ctr := ctr+1)
  9893. {
  9894. if (isiri_id (triples[ctr][0]))
  9895. S := id_to_iri (triples[ctr][0]);
  9896. else
  9897. S := triples[ctr][0];
  9898. if (isiri_id (triples[ctr][1]))
  9899. P := id_to_iri (triples[ctr][1]);
  9900. else
  9901. P := triples[ctr][1];
  9902. O := triples[ctr][2];
  9903. if (isiri_id (O))
  9904. {
  9905. result (S, P, id_to_iri (O) --, 1, NULL, NULL
  9906. );
  9907. }
  9908. -- else if (is_rdf_box (O))
  9909. -- {
  9910. -- dt_twobyte := rdf_box_type (O);
  9911. -- O_DT := case (dt_twobyte) when 257 then NULL else coalesce (
  9912. -- (select id_to_iri (RDT_IID) from DB.DBA.RDF_DATATYPE where RDT_TWOBYTE = dt_twobyte) ) end;
  9913. -- lang_twobyte := rdf_box_lang (O);
  9914. -- O_LANG := case (lang_twobyte) when 257 then NULL else coalesce (
  9915. -- (select lower (RL_ID) from DB.DBA.RDF_LANGUAGE where RL_TWOBYTE = lang_twobyte) ) end;
  9916. -- result (S, P, O, 0, O_DT, O_LANG);
  9917. -- }
  9918. else if (S is not null and P is not null and O is not null)
  9919. result (S, P, O --, 0, __xsd_type (O, NULL), NULL
  9920. );
  9921. }
  9922. goto next_batch;
  9923. }
  9924. ;
  9925. --!AWK PUBLIC
  9926. create procedure DB.DBA.RDF_DICT_OF_TRIPLES_TO_FOUR_COLS (in dict any, in destructive integer := 0)
  9927. {
  9928. declare ctr, len integer;
  9929. declare triples, O any;
  9930. declare S, P, O_DT, O_LANG varchar;
  9931. declare O_IS_IRI, dt_twobyte, lang_twobyte integer;
  9932. triples := dict_list_keys (dict, destructive);
  9933. DB.DBA.RDF_TRIPLES_BATCH_COMPLETE (triples);
  9934. exec_result_names (vector (vector ('S', 182, 0, 4072, 1, 0, 1, 0, 0, 0, 0, 0), vector ('P', 182, 0, 4072, 1, 0, 1, 0, 0, 0, 0, 0), vector ('O', 182, 0, 2147483647, 1, 0, 0, 0, 0, 0, 0, 0), vector ('O_TYPE', 182, 0, 4072, 1, 0, 1, 0, 0, 0, 0, 0)));
  9935. len := length (triples);
  9936. for (ctr := 0; ctr < len; ctr := ctr+1)
  9937. {
  9938. if (isiri_id (triples[ctr][0]))
  9939. S := id_to_iri (triples[ctr][0]);
  9940. else
  9941. S := triples[ctr][0];
  9942. if (isiri_id (triples[ctr][1]))
  9943. P := id_to_iri (triples[ctr][1]);
  9944. else
  9945. P := triples[ctr][1];
  9946. O := triples[ctr][2];
  9947. if (isiri_id (O))
  9948. {
  9949. result (S, P, id_to_iri (O), NULL);
  9950. }
  9951. else if (is_rdf_box (O))
  9952. {
  9953. dt_twobyte := rdf_box_type (O);
  9954. O_DT := case (dt_twobyte) when 257 then NULL else coalesce (
  9955. (select id_to_iri (RDT_IID) from DB.DBA.RDF_DATATYPE where RDT_TWOBYTE = dt_twobyte) ) end;
  9956. lang_twobyte := rdf_box_lang (O);
  9957. --O_LANG := case (lang_twobyte) when 257 then NULL else coalesce (
  9958. -- (select lower (RL_ID) from DB.DBA.RDF_LANGUAGE where RL_TWOBYTE = lang_twobyte) ) end;
  9959. result (S, P, O, coalesce (O_DT, ''));
  9960. }
  9961. else if (S is not null and P is not null and O is not null)
  9962. result (S, P, O, coalesce (__xsd_type (O, NULL), ''));
  9963. }
  9964. }
  9965. ;
  9966. -----
  9967. -- Internal functions used in SQL generated by SPARQL compiler.
  9968. -- They will change frequently, do not try to use them in applications!
  9969. create function DB.DBA.RDF_TYPEMIN_OF_OBJ (in obj any) returns any
  9970. {
  9971. declare tag integer;
  9972. if (obj is null)
  9973. return NULL;
  9974. tag := __tag (obj);
  9975. if (tag in (__tag of integer, __tag of double precision, __tag of numeric))
  9976. return -3.40282347e+38;
  9977. if (tag = __tag of datetime)
  9978. return cast ('0101-01-01' as datetime);
  9979. if (tag = __tag of rdf_box)
  9980. return rdf_box ('', rdf_box_type (obj), 257, 0, 1);
  9981. if (tag = (__tag of varchar))
  9982. return '';
  9983. return NULL; -- Nothing else can be compared hence no min.
  9984. }
  9985. ;
  9986. create function DB.DBA.RDF_TYPEMAX_OF_OBJ (in obj any) returns any
  9987. {
  9988. declare tag integer;
  9989. if (obj is null)
  9990. return NULL;
  9991. tag := __tag (obj);
  9992. if (tag in (__tag of integer, __tag of double precision, __tag of numeric))
  9993. return 3.40282347e+38;
  9994. if (tag = __tag of datetime)
  9995. return cast ('9999-12-30' as datetime);
  9996. if (tag = __tag of rdf_box)
  9997. return rdf_box ('\377\377\377\377\377\377', rdf_box_type (obj), 257, 0, 1);
  9998. if (tag = (__tag of varchar))
  9999. return '\377\377\377\377\377\377';
  10000. return NULL; -- Nothing else can be compared hence no max.
  10001. }
  10002. ;
  10003. create function DB.DBA.RDF_IID_CMP (in obj1 any, in obj2 any) returns integer
  10004. {
  10005. return NULL;
  10006. }
  10007. ;
  10008. create function DB.DBA.RDF_OBJ_CMP (in obj1 any, in obj2 any) returns integer
  10009. {
  10010. declare tag1, tag2 integer;
  10011. if (obj1 is null or obj2 is null)
  10012. return NULL;
  10013. tag1 := __tag (obj1);
  10014. tag2 := __tag (obj2);
  10015. if (tag1 = __tag of rdf_box)
  10016. {
  10017. if (tag2 = __tag of rdf_box)
  10018. {
  10019. if (obj1 = obj2)
  10020. return 0;
  10021. if (rdf_box_type (obj1) <> rdf_box_type (obj2))
  10022. return null;
  10023. if (not rdf_box_is_complete (obj1))
  10024. {
  10025. declare id1 integer;
  10026. declare full1 varchar;
  10027. id1 := rdf_box_ro_id (obj1);
  10028. if (__tag of XML = rdf_box_data_tag (obj1))
  10029. return null;
  10030. full1 := (select case (isnull (RO_LONG)) when 0 then blob_to_string (RO_LONG) else RO_VAL end from DB.DBA.RDF_OBJ where RO_ID = id1);
  10031. if (full1 is null)
  10032. signal ('RDFXX', sprintf ('Integrity violation in DB.DBA.RDF_OBJ_CMP, bad id %d', id1));
  10033. rdf_box_set_data (obj1, full1, 1);
  10034. }
  10035. if (not rdf_box_is_complete (obj2))
  10036. {
  10037. declare id2 integer;
  10038. declare full2 varchar;
  10039. id2 := rdf_box_ro_id (obj2);
  10040. if (__tag of XML = rdf_box_data_tag (obj2))
  10041. return null;
  10042. full2 := (select case (isnull (RO_LONG)) when 0 then blob_to_string (RO_LONG) else RO_VAL end from DB.DBA.RDF_OBJ where RO_ID = id2);
  10043. if (full2 is null)
  10044. signal ('RDFXX', sprintf ('Integrity violation in DB.DBA.RDF_OBJ_CMP, bad id %d', id2));
  10045. rdf_box_set_data (obj2, full2, 1);
  10046. }
  10047. return rdf_box_strcmp (obj1, obj2);
  10048. }
  10049. return null;
  10050. }
  10051. if (tag1 in (__tag of integer, __tag of double precision, __tag of numeric))
  10052. {
  10053. if (tag2 in (__tag of integer, __tag of double precision, __tag of numeric))
  10054. {
  10055. if (obj1 <> obj2)
  10056. {
  10057. if (obj1 < obj2)
  10058. return -1;
  10059. return 1;
  10060. }
  10061. return 0;
  10062. }
  10063. return null;
  10064. }
  10065. if (tag1 = __tag of datetime)
  10066. {
  10067. if (tag2 = __tag of datetime)
  10068. {
  10069. if (obj1 <> obj2)
  10070. {
  10071. if (obj1 < obj2)
  10072. return -1;
  10073. return 1;
  10074. }
  10075. return 0;
  10076. }
  10077. return null;
  10078. }
  10079. return NULL;
  10080. }
  10081. ;
  10082. create function DB.DBA.RDF_LONG_CMP (in long1 any, in long2 any) returns integer
  10083. {
  10084. declare tag1, tag2 integer;
  10085. if (long1 is null or long2 is null)
  10086. return NULL;
  10087. tag1 := __tag (long1);
  10088. tag2 := __tag (long2);
  10089. if (tag1 = __tag of rdf_box)
  10090. {
  10091. if (tag2 = __tag of rdf_box)
  10092. return rdf_box_strcmp (long1, long2);
  10093. return null;
  10094. }
  10095. if (tag1 in (__tag of integer, __tag of double precision, __tag of numeric))
  10096. {
  10097. if (tag2 in (__tag of integer, __tag of double precision, __tag of numeric))
  10098. {
  10099. if (long1 <> long2)
  10100. {
  10101. if (long1 < long2)
  10102. return -1;
  10103. return 1;
  10104. }
  10105. return 0;
  10106. }
  10107. return null;
  10108. }
  10109. if (tag1 = __tag of datetime)
  10110. {
  10111. if (tag2 = __tag of datetime)
  10112. {
  10113. if (long1 <> long2)
  10114. {
  10115. if (long1 < long2)
  10116. return -1;
  10117. return 1;
  10118. }
  10119. return 0;
  10120. }
  10121. return null;
  10122. }
  10123. return NULL;
  10124. }
  10125. ;
  10126. --!AWK PUBLIC
  10127. create function DB.DBA.RDF_DIST_SER_LONG (in val any) returns any
  10128. {
  10129. if (not (isstring (val)))
  10130. {
  10131. if (__tag of rdf_box = __tag (val))
  10132. {
  10133. if (rdf_box_is_storeable (val))
  10134. return serialize (val);
  10135. return serialize (vector (rdf_box_data (val), rdf_box_type (val), rdf_box_lang (val), rdf_box_is_complete (val)));
  10136. }
  10137. return serialize (val);
  10138. }
  10139. if ('' = val)
  10140. return val;
  10141. if (val[0] < 128)
  10142. return val;
  10143. return serialize (val);
  10144. }
  10145. ;
  10146. --!AWK PUBLIC
  10147. create function DB.DBA.RDF_DIST_DESER_LONG (in strg any) returns any
  10148. {
  10149. if (not (isstring (strg)))
  10150. return strg;
  10151. if ('' = strg)
  10152. return strg;
  10153. if (strg[0] < 128)
  10154. return strg;
  10155. declare res any;
  10156. res := deserialize (strg);
  10157. if (__tag of vector <> __tag (res))
  10158. return res;
  10159. return rdf_box (res[0], res[1], res[2], 0, res[3]);
  10160. }
  10161. ;
  10162. -----
  10163. -- JSO procedures
  10164. create function DB.DBA.JSO_MAKE_INHERITANCE (in jgraph varchar, in class varchar, in rootinst varchar, in destinst varchar, in dest_iid iri_id, inout noinherits any, inout inh_stack any)
  10165. {
  10166. declare base_iid iri_id;
  10167. declare baseinst varchar;
  10168. -- dbg_obj_princ ('JSO_MAKE_INHERITANCE (', jgraph, class, rootinst, destinst, ')');
  10169. inh_stack := vector_concat (inh_stack, vector (destinst));
  10170. baseinst := null;
  10171. if (not exists (sparql
  10172. define input:storage ""
  10173. prefix virtrdf: <http://www.openlinksw.com/schemas/virtrdf#>
  10174. ask where {
  10175. graph ?:jgraph { ?:dest_iid rdf:type `iri(?:class)`
  10176. } } ) )
  10177. signal ('22023', 'JSO_MAKE_INHERITANCE has not found object <' || destinst || '> of type <' || class || '>');
  10178. /* This fails. !!!TBD: fix sparql2sql.c to preserve data about equalities, fixed values and globals when triples are moved from gp to gp
  10179. for (sparql
  10180. define input:storage ""
  10181. prefix virtrdf: <http://www.openlinksw.com/schemas/virtrdf#>
  10182. select ?srcinst
  10183. where {
  10184. graph ?:jgraph {
  10185. { {
  10186. ?destnode rdf:type `iri(?:class)` .
  10187. filter (?destnode = iri(?:destinst)) }
  10188. union
  10189. {
  10190. ?destnode rdf:type `iri(?:class)` .
  10191. ?destnode rdf:name `iri(?:destinst)` } } .
  10192. ?destnode virtrdf:inheritFrom ?srcinst .
  10193. ?srcinst rdf:type `iri(?:class)` .
  10194. } } ) do
  10195. */
  10196. for (sparql
  10197. define input:storage ""
  10198. define output:valmode "LONG"
  10199. prefix virtrdf: <http://www.openlinksw.com/schemas/virtrdf#>
  10200. select ?src_iid
  10201. where {
  10202. graph ?:jgraph { ?:dest_iid virtrdf:inheritFrom ?src_iid } } ) do
  10203. {
  10204. declare srcinst varchar;
  10205. srcinst := id_to_iri_nosignal ("src_iid");
  10206. if (baseinst is null)
  10207. {
  10208. if (not exists (sparql
  10209. define input:storage ""
  10210. prefix virtrdf: <http://www.openlinksw.com/schemas/virtrdf#>
  10211. ask where { graph ?:jgraph { ?:"src_iid" rdf:type `iri(?:class)` } } ) )
  10212. signal ('22023', 'JSO_MAKE_INHERITANCE has found that the object <' || destinst || '> has wrong virtrdf:inheritFrom <' || srcinst || '> that is not an instance of type <' || class || '>');
  10213. base_iid := "src_iid";
  10214. baseinst := srcinst;
  10215. }
  10216. else if (baseinst <> srcinst)
  10217. signal ('22023', 'JSO_MAKE_INHERITANCE has found that the object <' || destinst || '> has multiple virtrdf:inheritFrom declarations: <' || baseinst || '> and <' || srcinst || '>');
  10218. }
  10219. if (position (baseinst, inh_stack))
  10220. signal ('22023', 'JSO_MAKE_INHERITANCE has found that the object <' || baseinst || '> is recursively inherited from itself');
  10221. -- This fails. !!!TBD: fix sparql2sql.c to preserve data about equalities, fixed values and globals when triples are moved from gp to gp
  10222. -- for (sparql
  10223. -- define input:storage ""
  10224. -- prefix virtrdf: <http://www.openlinksw.com/schemas/virtrdf#>
  10225. -- select ?pred
  10226. -- where {
  10227. -- graph ?:jgraph {
  10228. -- { {
  10229. -- ?destnode rdf:type `iri(?:class)` .
  10230. -- filter (?destnode = iri(?:destinst)) }
  10231. -- union
  10232. -- {
  10233. -- ?destnode rdf:type `iri(?:class)` .
  10234. -- ?destnode rdf:name `iri(?:destinst)` } } .
  10235. -- ?destnode virtrdf:noInherit ?pred .
  10236. -- } } ) do
  10237. for (sparql
  10238. define input:storage ""
  10239. prefix virtrdf: <http://www.openlinksw.com/schemas/virtrdf#>
  10240. select ?pred
  10241. where {
  10242. graph ?:jgraph {
  10243. ?:dest_iid virtrdf:noInherit ?pred
  10244. } } ) do
  10245. {
  10246. if (baseinst is null)
  10247. signal ('22023', 'JSO_MAKE_INHERITANCE has found that the object <' || destinst || '> has set virtrdf:noInherit but has no virtrdf:inheritFrom');
  10248. dict_put (noinherits, "pred", destinst);
  10249. }
  10250. if (baseinst is null)
  10251. return;
  10252. for (select "pred_id", "predval"
  10253. from (sparql
  10254. define input:storage ""
  10255. define output:valmode "LONG"
  10256. prefix virtrdf: <http://www.openlinksw.com/schemas/virtrdf#>
  10257. select ?pred_id, ?predval
  10258. where {
  10259. graph ?:jgraph {
  10260. ?:base_iid ?pred_id ?predval
  10261. } } ) as "t00"
  10262. where not exists (sparql
  10263. define input:storage ""
  10264. prefix virtrdf: <http://www.openlinksw.com/schemas/virtrdf#>
  10265. ask where { graph ?:jgraph { ?:"t00"."pred_id" virtrdf:loadAs virtrdf:jsoTriple } } )
  10266. ) do
  10267. {
  10268. declare "pred" any;
  10269. "pred" := id_to_iri ("pred_id");
  10270. if (DB.DBA.RDF_LANGUAGE_OF_LONG ("predval", null) is not null)
  10271. signal ('22023', 'JSO_MAKE_INHERITANCE does not support language marks on objects');
  10272. if ('http://www.w3.org/1999/02/22-rdf-syntax-ns#type' = "pred")
  10273. ;
  10274. else if ('http://www.w3.org/1999/02/22-rdf-syntax-ns#name' = "pred")
  10275. ;
  10276. else if ('http://www.openlinksw.com/schemas/virtrdf#inheritFrom' = "pred")
  10277. ;
  10278. else if ('http://www.openlinksw.com/schemas/virtrdf#noInherit' = "pred")
  10279. ;
  10280. else if (dict_get (noinherits, "pred", baseinst) = baseinst) -- trick here, instead of (dict_get (noinherits, pred, null) is null) that does not handle inheritance of booleans properly.
  10281. {
  10282. jso_set (class, rootinst, "pred", __rdf_sqlval_of_obj ("predval"), isiri_id ("predval"));
  10283. dict_put (noinherits, "pred", baseinst);
  10284. }
  10285. }
  10286. DB.DBA.JSO_MAKE_INHERITANCE (jgraph, class, rootinst, baseinst, base_iid, noinherits, inh_stack);
  10287. }
  10288. ;
  10289. create function DB.DBA.JSO_LOAD_INSTANCE (in jgraph varchar, in jinst varchar, in delete_first integer, in make_new integer, in jsubj_iid iri_id := null)
  10290. {
  10291. declare jinst_iid, jgraph_iid IRI_ID;
  10292. declare jclass varchar;
  10293. declare noinherits, inh_stack, "p" any;
  10294. -- dbg_obj_princ ('JSO_LOAD_INSTANCE (', jgraph, ')');
  10295. noinherits := dict_new ();
  10296. jinst_iid := iri_ensure (jinst);
  10297. jgraph_iid := iri_ensure (jgraph);
  10298. if (jsubj_iid is null)
  10299. {
  10300. jsubj_iid := (sparql
  10301. define input:storage ""
  10302. define output:valmode "LONG"
  10303. select ?s
  10304. where { graph ?:jgraph { ?s rdf:name ?:jinst } } );
  10305. if (jsubj_iid is null)
  10306. jsubj_iid := jinst_iid;
  10307. }
  10308. jclass := (sparql
  10309. define input:storage ""
  10310. select ?t
  10311. where {
  10312. graph ?:jgraph { ?:jsubj_iid rdf:type ?t } } );
  10313. if (jclass is null)
  10314. {
  10315. if (exists (sparql
  10316. define input:storage ""
  10317. select ?x
  10318. where { graph ?:jgraph {
  10319. { ?:jinst ?x ?o }
  10320. union
  10321. { ?x rdf:name ?ji .
  10322. filter (str (?ji) = ?:jinst)
  10323. } } } ) )
  10324. signal ('22023', 'JSO_LOAD_INSTANCE can not detect the type of <' || jinst || '>');
  10325. else
  10326. signal ('22023', 'JSO_LOAD_INSTANCE can not find an object <' || jinst || '>');
  10327. }
  10328. if (delete_first)
  10329. jso_delete (jclass, jinst, 1);
  10330. if (make_new)
  10331. jso_new (jclass, jinst);
  10332. for (select "p_id", coalesce ("o2", "o1") as "o"
  10333. from (sparql
  10334. define input:storage ""
  10335. define output:valmode "LONG"
  10336. select ?p_id ?o1 ?o2
  10337. where {
  10338. graph ?:jgraph_iid {
  10339. { ?:jsubj_iid ?p_id ?o1 } optional { ?o1 rdf:name ?o2 }
  10340. } }
  10341. ) as "t00"
  10342. where not exists (sparql
  10343. define input:storage ""
  10344. prefix virtrdf: <http://www.openlinksw.com/schemas/virtrdf#>
  10345. ask where { graph ?:jgraph_iid { ?:"t00"."p_id" virtrdf:loadAs virtrdf:jsoTriple } } ) option (quietcast)
  10346. ) do
  10347. {
  10348. "p" := id_to_iri ("p_id");
  10349. if (DB.DBA.RDF_LANGUAGE_OF_LONG ("o", null) is not null)
  10350. signal ('22023', 'JSO_LOAD_INSTANCE does not support language marks on objects');
  10351. if ('http://www.w3.org/1999/02/22-rdf-syntax-ns#type' = "p")
  10352. {
  10353. if (__rdf_sqlval_of_obj ("o") <> jclass)
  10354. signal ('22023', 'JSO_LOAD_INSTANCE has found that the object <' || jinst || '> has multiple type declarations');
  10355. }
  10356. else if ('http://www.w3.org/1999/02/22-rdf-syntax-ns#name' = "p")
  10357. ;
  10358. else if ('http://www.openlinksw.com/schemas/virtrdf#inheritFrom' = "p")
  10359. ;
  10360. else if ('http://www.openlinksw.com/schemas/virtrdf#noInherit' = "p")
  10361. ;
  10362. else
  10363. {
  10364. jso_set (jclass, jinst, "p", __rdf_sqlval_of_obj ("o"), isiri_id ("o"));
  10365. dict_put (noinherits, "p", jinst);
  10366. }
  10367. }
  10368. inh_stack := vector ();
  10369. DB.DBA.JSO_MAKE_INHERITANCE (jgraph, jclass, jinst, jinst, jsubj_iid, noinherits, inh_stack);
  10370. }
  10371. ;
  10372. create procedure DB.DBA.JSO_LIST_INSTANCES_OF_GRAPH (in jgraph varchar, out instances any)
  10373. {
  10374. declare md, res, st, msg any;
  10375. st:= '00000';
  10376. exec (
  10377. 'select DB.DBA.VECTOR_AGG (
  10378. vector (
  10379. id_to_iri ("jclass"),
  10380. id_to_iri ("jinst"),
  10381. coalesce ("s", "jinst") ) )
  10382. from ( sparql
  10383. define output:valmode "LONG"
  10384. define input:storage ""
  10385. select ?jclass ?jinst ?s
  10386. where {
  10387. graph ?? {
  10388. { ?jinst rdf:type ?jclass .
  10389. filter (!isBLANK (?jinst)) }
  10390. union
  10391. { ?s rdf:type ?jclass .
  10392. ?s rdf:name ?jinst .
  10393. filter (isBLANK (?s))
  10394. } } }
  10395. ) as inst',
  10396. st, msg, vector (jgraph), 1, md, res);
  10397. if (st <> '00000') signal (st, msg);
  10398. instances := res[0][0];
  10399. }
  10400. ;
  10401. create procedure DB.DBA.CL_EXEC_AND_LOG (in txt varchar, in args any)
  10402. {
  10403. DB.DBA.CL_EXEC (txt, args);
  10404. DB.DBA.CL_EXEC ('log_text_array (?, ?)', vector (txt, args), 1);
  10405. }
  10406. ;
  10407. create function DB.DBA.JSO_LOAD_GRAPH_MEMONLY (in jgraph varchar, in pin_now integer, in instances any, in triples any)
  10408. {
  10409. declare chk any;
  10410. /* Pass 1. Deleting all obsolete instances. */
  10411. foreach (any j in instances) do
  10412. jso_delete (j[0], j[1], 1);
  10413. /* Pass 2. Creating all instances. */
  10414. foreach (any j in instances) do
  10415. jso_new (j[0], j[1]);
  10416. /* Pass 3. Loading all instances, including loading inherited values. */
  10417. foreach (any j in instances) do
  10418. DB.DBA.JSO_LOAD_INSTANCE (jgraph, j[1], 0, 0, j[2]);
  10419. /* Pass 4. Validation all instances. */
  10420. foreach (any j in instances) do
  10421. jso_validate (j[0], j[1], 1);
  10422. /* Pass 5. Pin all instances. */
  10423. if (pin_now)
  10424. {
  10425. foreach (any j in instances) do
  10426. jso_pin (j[0], j[1]);
  10427. }
  10428. /* Pass 6. Load all separate triples */
  10429. foreach (any t in triples) do
  10430. jso_triple_add (t[0], t[1], t[2]);
  10431. chk := jso_triple_get_objs (
  10432. UNAME'http://www.openlinksw.com/schemas/virtrdf#loadAs',
  10433. UNAME'http://www.openlinksw.com/schemas/virtrdf#loadAs' );
  10434. if ((1 <> length (chk)) or (cast (chk[0] as varchar) <> 'http://www.openlinksw.com/schemas/virtrdf#jsoTriple'))
  10435. signal ('22023', 'JSO_LOAD_GRAPH_MEMONLY has not found expected metadata in the graph');
  10436. }
  10437. ;
  10438. create function DB.DBA.JSO_LOAD_GRAPH (in jgraph varchar, in pin_now integer := 1)
  10439. {
  10440. declare jgraph_iid IRI_ID;
  10441. declare qry, stat, msg varchar;
  10442. declare instances, mdata, rset, triples any;
  10443. -- dbg_obj_princ ('JSO_LOAD_GRAPH (', jgraph, ')');
  10444. jgraph_iid := iri_ensure (jgraph);
  10445. DB.DBA.JSO_LIST_INSTANCES_OF_GRAPH (jgraph, instances);
  10446. qry := 'sparql
  10447. define input:storage ""
  10448. define sql:table-option "LOOP"
  10449. prefix virtrdf: <http://www.openlinksw.com/schemas/virtrdf#>
  10450. select (sql:VECTOR_AGG (bif:vector (?s, ?p, ?o)))
  10451. where { graph <' || id_to_iri (jgraph_iid) || '> { ?p virtrdf:loadAs virtrdf:jsoTriple . ?s ?p ?o } }';
  10452. stat := '00000';
  10453. exec (qry, stat, msg, vector(), 1, mdata, rset);
  10454. if (stat <> '00000')
  10455. signal (stat, msg);
  10456. triples := rset[0][0];
  10457. DB.DBA.JSO_LOAD_GRAPH_MEMONLY (jgraph, pin_now, instances, triples);
  10458. }
  10459. ;
  10460. create function DB.DBA.JSO_PIN_GRAPH_MEMONLY (in jgraph varchar, in instances any)
  10461. {
  10462. foreach (any j in instances) do
  10463. jso_pin (j[0], j[1]);
  10464. }
  10465. ;
  10466. create function DB.DBA.JSO_PIN_GRAPH (in jgraph varchar)
  10467. {
  10468. declare instances any;
  10469. DB.DBA.JSO_LIST_INSTANCES_OF_GRAPH (jgraph, instances);
  10470. DB.DBA.JSO_PIN_GRAPH_MEMONLY (jgraph, instances);
  10471. }
  10472. ;
  10473. --!AWK PUBLIC
  10474. create function DB.DBA.JSO_SYS_GRAPH () returns varchar
  10475. {
  10476. return 'http://www.openlinksw.com/schemas/virtrdf#';
  10477. }
  10478. ;
  10479. -- same as DB.DBA.JSO_LOAD_AND_PIN_SYS_GRAPH but no drop procedures
  10480. create procedure DB.DBA.JSO_LOAD_AND_PIN_SYS_GRAPH_RO (in graphiri varchar := null)
  10481. {
  10482. if (graphiri is null)
  10483. graphiri := DB.DBA.JSO_SYS_GRAPH();
  10484. if (not exists (select 1 from SYS_KEYS where KEY_TABLE = 'DB.DBA.RDF_QUAD'))
  10485. return;
  10486. DB.DBA.JSO_LOAD_GRAPH (graphiri, 0);
  10487. DB.DBA.JSO_PIN_GRAPH (graphiri);
  10488. }
  10489. ;
  10490. create procedure DB.DBA.JSO_LOAD_AND_PIN_SYS_GRAPH (in graphiri varchar := null)
  10491. {
  10492. if (graphiri is null)
  10493. graphiri := DB.DBA.JSO_SYS_GRAPH();
  10494. commit work;
  10495. DB.DBA.JSO_LOAD_GRAPH (graphiri, 0);
  10496. DB.DBA.JSO_PIN_GRAPH (graphiri);
  10497. for (select P_NAME from SYS_PROCEDURES
  10498. where (
  10499. (P_NAME > 'DB.DBA.SPARQL_DESC_DICT') and
  10500. (P_NAME < 'DB.DBA.SPARQL_DESC_DICU') and
  10501. (
  10502. (P_NAME like 'DB.DBA.SPARQL_DESC_DICT_QMV1_%') or
  10503. (P_NAME like 'DB.DBA.SPARQL_DESC_DICT_CBD_QMV1_%') or
  10504. (P_NAME like 'DB.DBA.SPARQL_DESC_DICT_OBJCBD_QMV1_%') or
  10505. (P_NAME like 'DB.DBA.SPARQL_DESC_DICT_SCBD_QMV1_%') ) )
  10506. for update) do
  10507. {
  10508. exec ('drop procedure DB.DBA."' || subseq (P_NAME, 7) || '"');
  10509. }
  10510. commit work;
  10511. }
  10512. ;
  10513. create function DB.DBA.JSO_DUMP_IRI (in v varchar, inout ses any)
  10514. {
  10515. -- 0 1 2 3 %
  10516. -- 01234567890123456789012345678901234567-
  10517. if (v like 'http://www.w3.org/2000/01/rdf-schema#%')
  10518. { http ('rdfs:' || subseq (v, 37), ses); return; }
  10519. -- 0 1 2 3 4 %
  10520. -- 01234567890123456789012345678901234567890123-
  10521. if (v like 'http://www.w3.org/1999/02/22-rdf-syntax-ns#%')
  10522. { http ('rdf:' || subseq (v, 43), ses); return; }
  10523. -- 0 1 2 %
  10524. -- 0123456789012345678901234567890-
  10525. if (v like 'http://www.w3.org/2002/07/owl#%')
  10526. { http ('owl:' || subseq (v, 30), ses); return; }
  10527. -- 0 1 2 3 %
  10528. -- 0123456789012345678901234567890123-
  10529. if (v like 'http://www.w3.org/2001/XMLSchema#%')
  10530. { http ('xsd:' || subseq (v, 33), ses); return; }
  10531. -- 0 1 2 3 4 %
  10532. -- 0123456789012345678901234567890123456789012-
  10533. if (v like 'http://www.openlinksw.com/schemas/virtrdf#%')
  10534. { http ('virtrdf:' || subseq (v, 42), ses); return; }
  10535. -- 0 1 2 3 4 %
  10536. -- 012345678901234567890123456789012345678901234567-
  10537. if (v like 'http://www.openlinksw.com/virtrdf-data-formats#%')
  10538. { http ('rdfdf:' || subseq (v, 47), ses); return; }
  10539. http ('<', ses);
  10540. http_escape (v, 12, ses, 1, 1);
  10541. http ('>', ses);
  10542. }
  10543. ;
  10544. create function DB.DBA.JSO_DUMP_FLD (in v any, inout ses any)
  10545. {
  10546. declare v_tag integer;
  10547. v_tag := __tag(v);
  10548. if (v_tag = 217)
  10549. DB.DBA.JSO_DUMP_IRI (cast (v as varchar), ses);
  10550. else if (v_tag = 243)
  10551. DB.DBA.JSO_DUMP_IRI (id_to_iri (v), ses);
  10552. else if (v_tag = 203)
  10553. http (jso_dbg_dump_rtti (v), ses);
  10554. else if (v_tag = __tag of varchar)
  10555. {
  10556. http ('"', ses);
  10557. http_escape (v, 11, ses, 1, 1);
  10558. http ('"', ses);
  10559. }
  10560. else if (isinteger (v))
  10561. http_value (v, 0, ses);
  10562. else if (v_tag = __tag of rdf_box)
  10563. DB.DBA.RDF_LONG_TO_TTL (v, ses);
  10564. else
  10565. {
  10566. http ('"', ses);
  10567. http_escape (__rdf_strsqlval (v), 11, ses, 1, 1);
  10568. http ('"^^<', ses);
  10569. http_escape (cast (__xsd_type (v) as varchar), 12, ses, 1, 1);
  10570. http ('>', ses);
  10571. }
  10572. }
  10573. ;
  10574. create function DB.DBA.JSO_VECTOR_TO_TTL (inout proplist any) returns any
  10575. {
  10576. declare prev_obj, ses any;
  10577. declare ctr, len integer;
  10578. ses := string_output ();
  10579. len := length (proplist);
  10580. gvector_sort (proplist, 1, 0, 1);
  10581. prev_obj := null;
  10582. for (ctr := 0; ctr < len; ctr := ctr+1)
  10583. {
  10584. declare obj, p, o any;
  10585. declare base IRI_ID;
  10586. obj := proplist[ctr][0];
  10587. p := proplist[ctr][1];
  10588. o := proplist[ctr][2];
  10589. if (obj = prev_obj)
  10590. http (' ;\n ', ses);
  10591. else
  10592. {
  10593. if (prev_obj is null)
  10594. http (
  10595. '@prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .
  10596. @prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> .
  10597. @prefix owl: <http://www.w3.org/2002/07/owl#> .
  10598. @prefix xsd: <http://www.w3.org/2001/XMLSchema#> .
  10599. @prefix virtrdf: <http://www.openlinksw.com/schemas/virtrdf#> .
  10600. @prefix rdfdf: <http://www.openlinksw.com/virtrdf-data-formats#> .
  10601. ', ses );
  10602. else
  10603. http (' .\n', ses);
  10604. prev_obj := obj;
  10605. DB.DBA.JSO_DUMP_FLD (obj, ses);
  10606. http ('\n ', ses);
  10607. }
  10608. DB.DBA.JSO_DUMP_FLD (p, ses);
  10609. http ('\t', ses);
  10610. DB.DBA.JSO_DUMP_FLD (o, ses);
  10611. }
  10612. if (prev_obj is not null)
  10613. http (' .\n', ses);
  10614. return ses;
  10615. }
  10616. ;
  10617. create function DB.DBA.JSO_FILTERED_PROPLIST (in only_custom integer := 0, in loading_status integer := 1, in long_valmode integer := 1) returns any
  10618. {
  10619. declare proplist, res any;
  10620. declare sys_dict, sys_inh any;
  10621. declare sys_txt, sys_vect any;
  10622. declare ctr, len integer;
  10623. declare inh_id IRI_ID;
  10624. if (loading_status = 0)
  10625. {
  10626. proplist := ((select DB.DBA.VECTOR_AGG (vector ("sub"."s", "sub"."p", "sub"."o")) from (
  10627. sparql define input:storage "" define output:valmode "LONG"
  10628. select ?s ?p ?o from <http://www.openlinksw.com/schemas/virtrdf#>
  10629. where { ?s ?p ?o } ) as "sub"));
  10630. }
  10631. else
  10632. {
  10633. proplist := vector_concat (jso_proplist (loading_status), jso_triple_list ());
  10634. }
  10635. gvector_sort (proplist, 1, 0, 1);
  10636. if (not only_custom and not long_valmode)
  10637. return proplist;
  10638. if (only_custom)
  10639. {
  10640. sys_txt := cast ( DB.DBA.XML_URI_GET (
  10641. 'http://www.openlinksw.com/sparql/virtrdf-data-formats.ttl', '' ) as varchar );
  10642. sys_dict := DB.DBA.RDF_TTL2HASH (sys_txt, '');
  10643. sys_vect := dict_list_keys (sys_dict, 0);
  10644. -- dbg_obj_princ ('Part of sys_dict is', subseq (sys_vect, 0, 10));
  10645. inh_id := iri_ensure ('http://www.openlinksw.com/schemas/virtrdf#inheritFrom');
  10646. sys_inh := dict_new (127);
  10647. foreach (any triple in sys_vect) do
  10648. {
  10649. if (triple[1] = inh_id)
  10650. dict_put (sys_inh, triple[0], triple[2]);
  10651. }
  10652. }
  10653. len := length (proplist);
  10654. vectorbld_init (res);
  10655. for (ctr := 0; ctr < len; ctr := ctr+1)
  10656. {
  10657. declare obj, p, o any;
  10658. declare obj_long, p_long, o_long any;
  10659. declare base IRI_ID;
  10660. obj := proplist[ctr][0];
  10661. p := proplist[ctr][1];
  10662. o := proplist[ctr][2];
  10663. if (217 = __tag (obj))
  10664. obj_long := iri_ensure (obj);
  10665. else
  10666. obj_long := obj;
  10667. if (217 = __tag (p))
  10668. p_long := iri_ensure (p);
  10669. else
  10670. p_long := p;
  10671. if (217 = __tag (o))
  10672. o_long := iri_ensure (o);
  10673. else
  10674. o_long := __rdf_long_of_obj (DB.DBA.RDF_MAKE_OBJ_OF_SQLVAL (o));
  10675. -- dbg_obj_princ ('key sample: ', vector (obj_long, p_long, o_long));
  10676. if (only_custom)
  10677. {
  10678. if (dict_get (sys_dict, vector (obj_long, p_long, o_long)) is not null)
  10679. goto end_of_step;
  10680. base := dict_get (sys_inh, obj_long);
  10681. if (base is not null and dict_get (sys_dict, vector (base, p_long, o_long)) is not null)
  10682. goto end_of_step;
  10683. }
  10684. if (long_valmode)
  10685. vectorbld_acc (res, vector (obj_long, p_long, o_long));
  10686. else
  10687. vectorbld_acc (res, proplist[ctr]);
  10688. end_of_step: ;
  10689. }
  10690. vectorbld_final (res);
  10691. return res;
  10692. }
  10693. ;
  10694. create function DB.DBA.JSO_DUMP_ALL (in only_custom integer := 0, in loading_status integer := 1) returns any
  10695. {
  10696. declare proplist any;
  10697. proplist := DB.DBA.JSO_FILTERED_PROPLIST (only_custom, loading_status, 0);
  10698. return DB.DBA.JSO_VECTOR_TO_TTL (proplist);
  10699. }
  10700. ;
  10701. -----
  10702. -- Metadata audit / backup / restore / recovery
  10703. create function DB.DBA.RDF_BACKUP_METADATA (in save_to_file integer := 0, in backup_name varchar := null) returns varchar
  10704. {
  10705. declare proplist any;
  10706. proplist := DB.DBA.JSO_FILTERED_PROPLIST (1, 0, 1);
  10707. if (backup_name is null)
  10708. backup_name := replace (cast (now() as varchar), ' ', 'T');
  10709. if (save_to_file)
  10710. {
  10711. declare proplist_debug any;
  10712. proplist_debug := DB.DBA.JSO_FILTERED_PROPLIST (0, 0, 1);
  10713. string_to_file (backup_name || '.ttl', '# RDF_BACKUP_METADATA #\n', -2);
  10714. string_to_file (backup_name || '.ttl', DB.DBA.JSO_VECTOR_TO_TTL (proplist), -1);
  10715. string_to_file (backup_name || '-DEBUG.ttl', '# RDF_BACKUP_METADATA - DEBUG #\n', -2);
  10716. string_to_file (backup_name || '-DEBUG.ttl', DB.DBA.JSO_VECTOR_TO_TTL (proplist_debug), -1);
  10717. return backup_name || '.ttl';
  10718. }
  10719. else
  10720. {
  10721. if (exists (sparql define input:storage "" ask where { graph `iri(?:backup_name)` { ?s ?p ?o }}))
  10722. signal ('22023', sprintf ('Can not backup RDF metadata into nonempty graph <%.300s>', backup_name));
  10723. foreach (any triple in proplist) do
  10724. {
  10725. declare s,p,o any;
  10726. s := triple[0];
  10727. p := triple[1];
  10728. o := triple[2];
  10729. sparql insert into graph iri(?:backup_name) { ?:s ?:p ?:o };
  10730. }
  10731. commit work;
  10732. }
  10733. return backup_name;
  10734. }
  10735. ;
  10736. create function DB.DBA.RDF_RESTORE_METADATA (in read_from_file integer, in backup_name varchar) returns any
  10737. {
  10738. declare graphiri_id IRI_ID;
  10739. declare proplist any;
  10740. if (read_from_file)
  10741. {
  10742. declare txt any;
  10743. txt := file_to_string (backup_name);
  10744. if (not ("LEFT" (txt, 23) = '# RDF_BACKUP_METADATA #'))
  10745. signal ('22023', sprintf ('Can not restore RDF metadata from file %.300s: file does not start with signature "# RDF_BACKUP_METADATA #"', backup_name));
  10746. proplist := dict_list_keys (DB.DBA.RDF_TTL2HASH (txt, ''), 1);
  10747. }
  10748. else
  10749. proplist := ((select DB.DBA.VECTOR_AGG (vector ("sub"."s", "sub"."p", "sub"."o")) from (
  10750. sparql define input:storage "" define output:valmode "LONG"
  10751. select ?s ?p ?o where { graph `iri(?:backup_name)` { ?s ?p ?o } } ) as "sub"));
  10752. if (0 = length (proplist))
  10753. signal ('22023', sprintf ('There are no metadata in %.200 to restore', backup_name));
  10754. graphiri_id := iri_ensure (DB.DBA.JSO_SYS_GRAPH ());
  10755. sparql define input:storage "" clear graph ?:graphiri_id;
  10756. commit work;
  10757. DB.DBA.SPARQL_RELOAD_QM_GRAPH ();
  10758. commit work;
  10759. foreach (any triple in proplist) do
  10760. {
  10761. declare sl,pl,ol any;
  10762. sl := triple[0];
  10763. pl := triple[1];
  10764. ol := triple[2];
  10765. if (pl <> iri_ensure ('http://www.openlinksw.com/schemas/virtrdf#status'))
  10766. {
  10767. -- dbg_obj_princ ('s=', sl, ' p=', pl, ' o=', ol);
  10768. sparql define input:storage "" insert into graph ?:graphiri_id { ?:sl ?:pl ?:ol };
  10769. }
  10770. }
  10771. commit work;
  10772. DB.DBA.SPARQL_RELOAD_QM_GRAPH ();
  10773. commit work;
  10774. return backup_name;
  10775. }
  10776. ;
  10777. create procedure DB.DBA.RDF_AUDIT_METADATA (in fix_bugs integer := 0, in unlocker varchar := null, in graphiri varchar := null, in call_result_names integer := 1)
  10778. {
  10779. declare chksum varchar;
  10780. declare chksum_acc any;
  10781. declare STAT, MSG varchar;
  10782. declare graphiri_id IRI_ID;
  10783. declare all_lists, prev_list, prev_subj any;
  10784. if (call_result_names)
  10785. result_names (STAT, MSG);
  10786. if (graphiri is null)
  10787. graphiri := DB.DBA.JSO_SYS_GRAPH ();
  10788. else
  10789. {
  10790. if (graphiri <> DB.DBA.JSO_SYS_GRAPH ())
  10791. result ('00000', 'Note: non-default graph IRI <' || graphiri || '> is used');
  10792. }
  10793. graphiri_id := iri_to_id (graphiri);
  10794. vectorbld_init (chksum_acc);
  10795. for (sparql define input:storage ""
  10796. select ?st ?trx where { graph ?:graphiri_id {
  10797. ?st virtrdf:qsAlterInProgress ?trx } } ) do
  10798. {
  10799. result ('00000', 'Quad storage <' || "st" || '> is flagged as being edited ' || cast ("trx" as varchar));
  10800. vectorbld_acc (chksum_acc, vector ("st", "trx"));
  10801. }
  10802. vectorbld_final (chksum_acc);
  10803. if (length (chksum_acc))
  10804. {
  10805. chksum := md5 (serialize (chksum_acc));
  10806. if ((fix_bugs = 0) or (unlocker is null) or ((chksum <> unlocker) and (unlocker <> '*')))
  10807. {
  10808. result ('42000', 'Can not process data that are being edited by someone else.');
  10809. result ('00000', 'To force tests/bugfixing, pass 1 as first argument and either ''' || chksum || ''' or ''*'' as second argument of the DB.DBA.RDF_AUDIT_METADATA() call');
  10810. return;
  10811. }
  10812. sparql define input:storage ""
  10813. delete from graph ?:graphiri_id {
  10814. ?st virtrdf:qsAlterInProgress ?trx }
  10815. where { graph ?:graphiri_id {
  10816. ?st virtrdf:qsAlterInProgress ?trx } };
  10817. }
  10818. if ((graphiri = DB.DBA.JSO_SYS_GRAPH ()) and fix_bugs)
  10819. {
  10820. declare txt1 varchar;
  10821. declare dict1, lst1 any;
  10822. result ('00000', 'Reloading built-in metadata, this might fix some errors without accurate reporting that they did exist');
  10823. txt1 := cast ( DB.DBA.XML_URI_GET (
  10824. 'http://www.openlinksw.com/sparql/virtrdf-data-formats.ttl', '' ) as varchar );
  10825. dict1 := DB.DBA.RDF_TTL2HASH (txt1, '');
  10826. lst1 := dict_list_keys (dict1, 1);
  10827. foreach (any triple in lst1) do
  10828. {
  10829. delete from DB.DBA.RDF_QUAD table option (index RDF_QUAD) where G = graphiri_id and S = triple[0] and P = triple[1];
  10830. }
  10831. DB.DBA.RDF_INSERT_TRIPLES (graphiri_id, lst1);
  10832. commit work;
  10833. result ('00000', 'Built-in metadata were reloaded');
  10834. if (fix_bugs > 1)
  10835. {
  10836. for (sparql define input:storage ""
  10837. prefix virtrdf: <http://www.openlinksw.com/schemas/virtrdf#>
  10838. select ?s from <http://www.openlinksw.com/schemas/virtrdf#> where {
  10839. ?s rdf:type virtrdf:array-of-QuadMap } ) do
  10840. {
  10841. if (DB.DBA.RDF_QM_GC_SUBTREE ("s", 3) is null)
  10842. result ('00000', 'Quad map array <' || "s" || '> is not used, removed');
  10843. }
  10844. for (sparql define input:storage ""
  10845. prefix virtrdf: <http://www.openlinksw.com/schemas/virtrdf#>
  10846. select ?s from <http://www.openlinksw.com/schemas/virtrdf#> where {
  10847. ?s rdf:type virtrdf:QuadMap } ) do
  10848. {
  10849. if (DB.DBA.RDF_QM_GC_MAPPING_SUBTREE ("s", 1) is null)
  10850. result ('00000', 'Quad map <' || "s" || '> is not used, removed');
  10851. }
  10852. for (sparql define input:storage ""
  10853. prefix virtrdf: <http://www.openlinksw.com/schemas/virtrdf#>
  10854. select ?s from <http://www.openlinksw.com/schemas/virtrdf#> where {
  10855. ?s rdf:type virtrdf:array-of-QuadMapFormat } ) do
  10856. {
  10857. if (DB.DBA.RDF_QM_GC_SUBTREE ("s", 3) is null)
  10858. result ('00000', 'Quad map format array <' || "s" || '> is not used, removed');
  10859. }
  10860. for (sparql define input:storage ""
  10861. prefix virtrdf: <http://www.openlinksw.com/schemas/virtrdf#>
  10862. select ?s from <http://www.openlinksw.com/schemas/virtrdf#> where {
  10863. ?s rdf:type virtrdf:QuadMapFormat } ) do
  10864. {
  10865. if (DB.DBA.RDF_QM_GC_SUBTREE ("s", 3) is null)
  10866. result ('00000', 'Quad map format <' || "s" || '> is not used, removed');
  10867. }
  10868. }
  10869. }
  10870. for (select * from (sparql define input:storage "" define output:valmode "LONG"
  10871. select ?lst ?p ?itm where { graph ?:graphiri_id {
  10872. ?lst ?p ?itm .
  10873. optional { ?itm a ?t } .
  10874. filter (! bound (?t) && isiri (?itm) && str(?p) > str(rdf:_) && str(?p) < str(rdf:_A))
  10875. } } ) as sub for update) do
  10876. {
  10877. result ('00000', 'List <' || id_to_iri("lst") || '> contains IRI <' || id_to_iri("itm") || '> that has no type');
  10878. if (fix_bugs)
  10879. {
  10880. sparql define input:storage ""
  10881. delete from graph ?:graphiri_id { ?:"lst" ?:"p" ?:"itm" };
  10882. }
  10883. }
  10884. vectorbld_init (all_lists);
  10885. prev_subj := #i0;
  10886. for (
  10887. select "sub"."lst", cast ("sub"."idx" as integer) as "idx", serialize ("sub"."itm") as "itmsz", "sub"."itmstr", "sub"."itmislit", "sub"."t"
  10888. from (sparql define input:storage "" define output:valmode "LONG"
  10889. select ?lst
  10890. (bif:aref (bif:sprintf_inverse (str(?p),
  10891. bif:concat (str (rdf:_), "%d"), 2 ),
  10892. 0 ) ) as ?idx
  10893. ?itm
  10894. (str(?itm)) as ?itmstr
  10895. (isliteral(?itm)) as ?itmislit
  10896. ?t
  10897. where { graph ?:graphiri_id {
  10898. ?lst ?p ?itm .
  10899. optional { ?itm a ?t } .
  10900. filter (
  10901. str(?p) > str(rdf:_) && str(?p) < str(rdf:_A))
  10902. } } ) as "sub"
  10903. order by 1, 2, 3, 4 ) do
  10904. {
  10905. if (prev_subj <> "lst")
  10906. {
  10907. if (prev_subj <> #i0)
  10908. {
  10909. vectorbld_final (prev_list);
  10910. vectorbld_acc (all_lists, vector (prev_subj, prev_list));
  10911. }
  10912. prev_subj := "lst";
  10913. vectorbld_init (prev_list);
  10914. }
  10915. vectorbld_acc (prev_list, vector ("idx", deserialize("itmsz"), "itmstr", "itmislit", "t"));
  10916. }
  10917. if (prev_subj <> #i0)
  10918. {
  10919. vectorbld_final (prev_list);
  10920. vectorbld_acc (all_lists, vector (prev_subj, prev_list));
  10921. }
  10922. vectorbld_final (all_lists);
  10923. foreach (any pair in all_lists) do
  10924. {
  10925. declare subj, items any;
  10926. declare pos, len, last_idx, list_needs_rebuild integer;
  10927. list_needs_rebuild := 0;
  10928. last_idx := 0;
  10929. subj := pair[0];
  10930. items := pair[1];
  10931. len := length (items);
  10932. last_idx := 0;
  10933. for (pos := 0; pos < len; pos := pos+1)
  10934. {
  10935. declare curr_idx integer;
  10936. curr_idx := items[pos][0];
  10937. if (curr_idx <= last_idx)
  10938. {
  10939. result ('42000', sprintf ('Item rdf:_%d is out of order in list <%s>', curr_idx, id_to_iri (subj)));
  10940. list_needs_rebuild := 1;
  10941. }
  10942. else if ((last_idx + 3) < curr_idx)
  10943. {
  10944. result ('42000', sprintf ('Items rdf:_%d to rdf:_%d are not set in list <%s>', last_idx + 1, curr_idx - 1, id_to_iri (subj)));
  10945. list_needs_rebuild := 1;
  10946. }
  10947. else
  10948. {
  10949. while ((last_idx + 1) < curr_idx)
  10950. {
  10951. result ('42000', sprintf ('Item rdf:_%d is not set in list <%s>', last_idx + 1, id_to_iri (subj)));
  10952. last_idx := last_idx + 1;
  10953. list_needs_rebuild := 1;
  10954. }
  10955. }
  10956. last_idx := curr_idx;
  10957. }
  10958. if (fix_bugs and list_needs_rebuild)
  10959. {
  10960. for (pos := 0; pos < len; pos := pos+1)
  10961. {
  10962. declare curr_idx integer;
  10963. curr_idx := items[pos][0];
  10964. sparql define input:storage ""
  10965. delete from graph ?:graphiri_id {
  10966. `iri(?:subj)` ?p ?o }
  10967. where { graph ?:graphiri_id {
  10968. `iri(?:subj)` ?p ?o .
  10969. filter (?p = iri (bif:sprintf ("%s%d", str (rdf:_), ?:curr_idx))) } };
  10970. }
  10971. for (pos := 0; pos < len; pos := pos+1)
  10972. {
  10973. declare curr_idx integer;
  10974. declare obj any;
  10975. declare objstr varchar;
  10976. declare objislit integer;
  10977. curr_idx := items[pos][0];
  10978. obj := items[pos][1];
  10979. objstr := items[pos][2];
  10980. objislit := items[pos][3];
  10981. if (objislit)
  10982. {
  10983. sparql define input:storage ""
  10984. insert into graph ?:graphiri_id {
  10985. `iri(?:subj)` `iri (bif:sprintf ("%s%d", str (rdf:_), 1 + ?:pos))` ?:obj };
  10986. }
  10987. else
  10988. {
  10989. sparql define input:storage ""
  10990. insert into graph ?:graphiri_id {
  10991. `iri(?:subj)` `iri (bif:sprintf ("%s%d", str (rdf:_), 1 + ?:pos))` `iri(?:objstr)` };
  10992. }
  10993. }
  10994. }
  10995. }
  10996. commit work;
  10997. if ((graphiri = DB.DBA.JSO_SYS_GRAPH ()) and fix_bugs)
  10998. {
  10999. whenever sqlstate '*' goto jso_load_failed;
  11000. DB.DBA.JSO_LOAD_AND_PIN_SYS_GRAPH ();
  11001. result ('00000', 'Metadata from system graph are cached in memory-resident JSOs (JavaScript Objects)');
  11002. return;
  11003. }
  11004. return;
  11005. jso_load_failed:
  11006. result (__SQL_STATE, __SQL_MESSAGE);
  11007. result ('42000', 'The previous error can not be fixed automatically. Sorry.');
  11008. return;
  11009. }
  11010. ;
  11011. -----
  11012. -- Internal routines for SPARQL macro library and quad map syntax extensions
  11013. create procedure DB.DBA.RDF_QM_CHANGE (in warninglist any)
  11014. {
  11015. declare STATE, MESSAGE varchar;
  11016. result_names (STATE, MESSAGE);
  11017. foreach (any warnings in warninglist) do
  11018. {
  11019. foreach (any warning in warnings) do
  11020. result (warning[0], warning[1]);
  11021. }
  11022. commit work;
  11023. }
  11024. ;
  11025. create procedure DB.DBA.RDF_QM_CHANGE_OPT (in cmdlist any)
  11026. {
  11027. declare cmdctr, cmdcount integer;
  11028. declare eaqs varchar;
  11029. declare STATE, MESSAGE varchar;
  11030. cmdcount := length (cmdlist);
  11031. result_names (STATE, MESSAGE);
  11032. eaqs := '';
  11033. for (cmdctr := 0; cmdctr < cmdcount; cmdctr := cmdctr + 1)
  11034. {
  11035. declare cmd, exectext, arglist, warnings,md,rs any;
  11036. declare argctr, argcount integer;
  11037. cmd := cmdlist[cmdctr];
  11038. exectext := string_output();
  11039. http ('select ', exectext);
  11040. http_value (cmd[0], 0, exectext);
  11041. http (' (', exectext);
  11042. if (length (cmd) > 2)
  11043. arglist := vector_concat (cmd[1], vector (cmd[2]));
  11044. else
  11045. arglist := cmd[1];
  11046. argcount := length (arglist);
  11047. for (argctr := 0; argctr < argcount; argctr := argctr + 1)
  11048. {
  11049. if (argctr > 0)
  11050. http (',', exectext);
  11051. http ('?', exectext);
  11052. }
  11053. http (')', exectext);
  11054. STATE := '00000';
  11055. warnings := exec (string_output_string (exectext), STATE, MESSAGE, arglist, 10000, md, rs);
  11056. -- dbg_obj_princ ('md = ', md, ' rs = ', rs, ' warnings = ', warnings, STATE, MESSAGE);
  11057. if (__tag of vector <> __tag (warnings) and __tag of vector = __tag (rs))
  11058. warnings := case (length (rs)) when 0 then null else rs[0][0] end;
  11059. -- dbg_obj_princ ('warnings = ', warnings);
  11060. if (__tag of vector = __tag (warnings))
  11061. {
  11062. foreach (any warning in warnings) do
  11063. result (warning[0], warning[1]);
  11064. }
  11065. commit work;
  11066. if (STATE <> '00000')
  11067. {
  11068. result (STATE, MESSAGE);
  11069. if ('' <> eaqs)
  11070. exec ('DB.DBA.RDF_QM_END_ALTER_QUAD_STORAGE (?)', STATE, MESSAGE, vector (eaqs));
  11071. DB.DBA.RDF_AUDIT_METADATA (1, null, null, 0);
  11072. return;
  11073. }
  11074. if (UNAME'DB.DBA.RDF_QM_BEGIN_ALTER_QUAD_STORAGE' = cmd[0])
  11075. eaqs := arglist[0];
  11076. else if (UNAME'DB.DBA.RDF_QM_END_ALTER_QUAD_STORAGE' = cmd[0])
  11077. eaqs := '';
  11078. }
  11079. result ('00000', sprintf ('%d RDF metadata manipulation operations done', cmdcount));
  11080. }
  11081. ;
  11082. create function DB.DBA.RDF_QM_APPLY_CHANGES (in deleted any, in affected any) returns any
  11083. {
  11084. declare ctr, len integer;
  11085. commit work;
  11086. DB.DBA.JSO_LOAD_AND_PIN_SYS_GRAPH ();
  11087. len := length (deleted);
  11088. for (ctr := 0; ctr < len; ctr := ctr + 2)
  11089. {
  11090. jso_delete (deleted [ctr], deleted [ctr+1], 1);
  11091. log_text ('jso_delete (?,?,1)', deleted [ctr], deleted [ctr+1]);
  11092. }
  11093. len := length (affected);
  11094. for (ctr := 0; ctr < len; ctr := ctr + 1)
  11095. {
  11096. jso_mark_affected (affected [ctr]);
  11097. log_text ('jso_mark_affected (?)', affected [ctr]);
  11098. }
  11099. return vector (vector ('00000', 'Transaction committed, SPARQL compiler re-configured'));
  11100. }
  11101. ;
  11102. create function DB.DBA.RDF_QM_ASSERT_JSO_TYPE (in inst varchar, in expected varchar, in allow_missing integer := 0) returns integer
  11103. {
  11104. declare actual varchar;
  11105. if (expected is null)
  11106. {
  11107. actual := coalesce ((sparql
  11108. define input:storage ""
  11109. prefix virtrdf: <http://www.openlinksw.com/schemas/virtrdf#>
  11110. select ?t where {
  11111. graph <http://www.openlinksw.com/schemas/virtrdf#> { `iri(?:inst)` rdf:type ?t } } ));
  11112. if (actual is not null)
  11113. signal ('22023', 'The RDF QM schema object <' || inst || '> already exists, type <' || cast (actual as varchar) || '>');
  11114. }
  11115. else
  11116. {
  11117. declare hit integer;
  11118. hit := 0;
  11119. for (sparql
  11120. define input:storage ""
  11121. prefix virtrdf: <http://www.openlinksw.com/schemas/virtrdf#>
  11122. select ?t where {
  11123. graph <http://www.openlinksw.com/schemas/virtrdf#> { `iri(?:inst)` rdf:type ?t } } ) do
  11124. {
  11125. if ("t" <> expected)
  11126. signal ('22023', 'The RDF QM schema object <' || inst || '> has type <' || cast (actual as varchar) || '>, cannot use same identifier for <' || expected || '>');
  11127. hit := 1;
  11128. }
  11129. if (not hit)
  11130. {
  11131. if (allow_missing)
  11132. return 0;
  11133. signal ('22023', 'The RDF QM schema object <' || inst || '> does not exist, should be of type <' || expected || '>');
  11134. }
  11135. }
  11136. return 1;
  11137. }
  11138. ;
  11139. create procedure DB.DBA.RDF_QM_ASSERT_STORAGE_FLAG (in storage varchar, in req_flag integer)
  11140. {
  11141. declare graphiri varchar;
  11142. graphiri := DB.DBA.JSO_SYS_GRAPH ();
  11143. DB.DBA.RDF_QM_ASSERT_JSO_TYPE (storage, 'http://www.openlinksw.com/schemas/virtrdf#QuadStorage');
  11144. for (sparql define input:storage ""
  11145. prefix rdfdf: <http://www.openlinksw.com/virtrdf-data-formats#>
  11146. select ?startdt where {
  11147. graph ?:graphiri {
  11148. `iri(?:storage)` virtrdf:qsAlterInProgress ?startdt .
  11149. } } ) do
  11150. {
  11151. if (req_flag)
  11152. return;
  11153. signal ('22023', 'The quad storage "' || storage || '" is edited by other client, started ' || cast ("startdt" as varchar));
  11154. }
  11155. if (not req_flag)
  11156. return;
  11157. signal ('22023', 'The quad storage "' || storage || '" is not flagged as being edited, cannot change it' );
  11158. }
  11159. ;
  11160. create procedure DB.DBA.RDF_QM_ASSERT_STORAGE_CONTAINS_MAPPING (in storage varchar, in qmid varchar, in must_contain integer)
  11161. {
  11162. declare graphiri varchar;
  11163. graphiri := DB.DBA.JSO_SYS_GRAPH ();
  11164. if (exists (sparql define input:storage ""
  11165. ask where {
  11166. graph ?:graphiri {
  11167. { `iri(?:storage)` virtrdf:qsDefaultMap `iri(?:qmid)` }
  11168. union
  11169. { `iri(?:storage)` virtrdf:qsUserMaps ?qmlist .
  11170. ?qmlist ?p `iri(?:qmid)` .
  11171. } } } ) )
  11172. {
  11173. if (must_contain)
  11174. return;
  11175. signal ('22023', 'The quad storage "' || storage || '" contains quad map ' || qmid );
  11176. }
  11177. if (not must_contain)
  11178. return;
  11179. signal ('22023', 'The quad storage "' || storage || '" does not contains quad map ' || qmid );
  11180. }
  11181. ;
  11182. create function DB.DBA.RDF_QM_GC_SUBTREE (in seed any, in gc_flags integer := 0) returns integer
  11183. { -- gc_flags: 0x1 = quick gc only, 0x2 = override virtrdf:isGcResistantType
  11184. declare graphiri varchar;
  11185. declare seed_id, graphiri_id, subjs, objs any;
  11186. declare o_to_s, s_to_o any;
  11187. declare subjs_of_o, objs_of_s any;
  11188. set isolation = 'serializable';
  11189. -- dbg_obj_princ ('DB.DBA.RDF_QM_GC_SUBTREE (', seed, '), ', seed, '=', id_to_iri(iri_to_id(seed)));
  11190. o_to_s := dict_new ();
  11191. s_to_o := dict_new ();
  11192. graphiri := DB.DBA.JSO_SYS_GRAPH ();
  11193. graphiri_id := iri_to_id (graphiri);
  11194. seed_id := iri_to_id (seed);
  11195. for (sparql define input:storage ""
  11196. define output:valmode "LONG"
  11197. select ?s
  11198. from <http://www.openlinksw.com/schemas/virtrdf#>
  11199. where { ?s virtrdf:item ?:seed_id } ) do
  11200. {
  11201. -- dbg_obj_princ ('DB.DBA.RDF_QM_GC_SUBTREE (', seed, ') found virtrdf:item subject ', "s");
  11202. return "s";
  11203. }
  11204. if (not bit_and (gc_flags, 2))
  11205. {
  11206. for (sparql define input:storage ""
  11207. define output:valmode "LONG"
  11208. select ?t ?n
  11209. from <http://www.openlinksw.com/schemas/virtrdf#>
  11210. where { ?:seed_id a ?t . ?t virtrdf:isGcResistantType ?n } ) do
  11211. {
  11212. -- dbg_obj_princ ('DB.DBA.RDF_QM_GC_SUBTREE (', seed, ') has gc-resistant type ', "t", ' resistance ', "n");
  11213. return "t";
  11214. }
  11215. }
  11216. for (sparql define input:storage ""
  11217. define output:valmode "LONG"
  11218. select ?s
  11219. from <http://www.openlinksw.com/schemas/virtrdf#>
  11220. where { ?s a [] ; ?p ?:seed_id } ) do
  11221. {
  11222. -- dbg_obj_princ ('DB.DBA.RDF_QM_GC_SUBTREE (', seed, ') found use case ', "s");
  11223. if (bit_and (gc_flags, 1))
  11224. return "s";
  11225. goto do_full_gc;
  11226. }
  11227. vectorbld_init (objs_of_s);
  11228. for (sparql define input:storage ""
  11229. define output:valmode "LONG"
  11230. define sql:table-option "LOOP"
  11231. select ?o
  11232. from <http://www.openlinksw.com/schemas/virtrdf#>
  11233. where { ?:seed_id a [] ; ?p ?o . ?o a [] } ) do
  11234. {
  11235. vectorbld_acc (objs_of_s, "o");
  11236. }
  11237. vectorbld_final (objs_of_s);
  11238. -- dbg_obj_princ ('DB.DBA.RDF_QM_GC_SUBTREE (', seed, ') found descendants ', objs_of_s);
  11239. delete from DB.DBA.RDF_QUAD where G = graphiri_id and S = seed_id;
  11240. sparql define input:storage ""
  11241. prefix rdfdf: <http://www.openlinksw.com/virtrdf-data-formats#>
  11242. delete from graph <http://www.openlinksw.com/schemas/virtrdf#> { ?s virtrdf:isSubClassOf ?o }
  11243. from <http://www.openlinksw.com/schemas/virtrdf#>
  11244. where { ?s virtrdf:isSubClassOf ?o . filter (?o = iri(?:seed_id)) };
  11245. commit work;
  11246. foreach (IRI_ID descendant in objs_of_s) do
  11247. {
  11248. DB.DBA.RDF_QM_GC_SUBTREE (descendant, 1);
  11249. }
  11250. -- dbg_obj_princ ('DB.DBA.RDF_QM_GC_SUBTREE (', seed, ') done in quick way');
  11251. return null;
  11252. do_full_gc:
  11253. for (sparql define input:storage ""
  11254. define output:valmode "LONG"
  11255. define sql:table-option "LOOP"
  11256. select ?s ?o
  11257. from <http://www.openlinksw.com/schemas/virtrdf#>
  11258. where { ?s a [] ; ?p ?o . ?o a [] } ) do
  11259. {
  11260. -- dbg_obj_princ ('DB.DBA.RDF_QM_GC_SUBTREE () caches ', "s", ' -> ', "o");
  11261. subjs_of_o := dict_get (o_to_s, "o", NULL);
  11262. if (subjs_of_o is null)
  11263. dict_put (o_to_s, "o", vector ("s"));
  11264. else if (0 >= position ("s", subjs_of_o))
  11265. dict_put (o_to_s, "o", vector_concat (vector ("s"), subjs_of_o));
  11266. objs_of_s := dict_get (s_to_o, "s", NULL);
  11267. if (objs_of_s is null)
  11268. dict_put (s_to_o, "s", vector ("o"));
  11269. else if (0 >= position ("o", objs_of_s))
  11270. dict_put (s_to_o, "s", vector_concat (vector ("o"), objs_of_s));
  11271. }
  11272. subjs := vector (seed_id);
  11273. again:
  11274. vectorbld_init (objs);
  11275. foreach (IRI_ID nod in subjs) do
  11276. {
  11277. -- dbg_obj_princ ('DB.DBA.RDF_QM_GC_SUBTREE () tries to delete ', nod, id_to_iri_nosignal (nod));
  11278. declare subjs_of_nod, objs_of_nod any;
  11279. subjs_of_nod := dict_get (o_to_s, nod, NULL);
  11280. if (subjs_of_nod is not null)
  11281. {
  11282. -- dbg_obj_princ ('DB.DBA.RDF_QM_GC_SUBTREE () does not delete ', nod, id_to_iri_nosignal (nod), ': side links ', subjs_of_nod);
  11283. if (nod = seed_id)
  11284. return subjs_of_nod[0];
  11285. goto nop_nod; -- see below;
  11286. }
  11287. -- sparql define input:storage ""
  11288. -- delete from graph <http://www.openlinksw.com/schemas/virtrdf#> { `iri(?:nod)` ?p ?o }
  11289. -- where { graph ?:graphiri { `iri(?:nod)` ?p ?o } };
  11290. delete from DB.DBA.RDF_QUAD where G = graphiri_id and S = nod;
  11291. objs_of_nod := dict_get (s_to_o, nod, NULL);
  11292. dict_remove (s_to_o, nod);
  11293. foreach (IRI_ID sub in objs_of_nod) do
  11294. {
  11295. declare subjs_of_sub any;
  11296. declare nod_pos integer;
  11297. subjs_of_sub := dict_get (o_to_s, sub, NULL);
  11298. nod_pos := position (nod, subjs_of_sub);
  11299. if (0 < nod_pos)
  11300. subjs_of_sub := vector_concat (subseq (subjs_of_sub, 0, nod_pos - 1), subseq (subjs_of_sub, nod_pos));
  11301. if (0 = length (subjs_of_sub))
  11302. {
  11303. -- dbg_obj_princ ('DB.DBA.RDF_QM_GC_SUBTREE () condemns ', sub, id_to_iri_nosignal (sub));
  11304. dict_remove (o_to_s, sub);
  11305. vectorbld_acc (objs, sub);
  11306. }
  11307. else
  11308. {
  11309. dict_put (o_to_s, sub, subjs_of_sub);
  11310. -- dbg_obj_princ ('DB.DBA.RDF_QM_GC_SUBTREE () stores subjects ', subjs_of_sub, ' for not condemned ', sub, id_to_iri_nosignal (sub));
  11311. }
  11312. }
  11313. nop_nod: ;
  11314. }
  11315. vectorbld_final (objs);
  11316. if (0 < length (objs))
  11317. {
  11318. -- dbg_obj_princ ('DB.DBA.RDF_QM_GC_SUBTREE () sets a new list of subjects: ', subjs);
  11319. subjs := objs;
  11320. goto again; -- see above
  11321. }
  11322. -- dbg_obj_princ ('DB.DBA.RDF_QM_GC_SUBTREE () finishes GC of ', seed);
  11323. return NULL;
  11324. }
  11325. ;
  11326. create function DB.DBA.RDF_QM_GC_MAPPING_SUBTREE (in mapname any, in gc_flags integer) returns any
  11327. {
  11328. declare gc_res, submaps any;
  11329. submaps := (select DB.DBA.VECTOR_AGG (s1."subm") from (
  11330. sparql define input:storage ""
  11331. select ?subm where {
  11332. graph <http://www.openlinksw.com/schemas/virtrdf#> {
  11333. `iri(?:mapname)` virtrdf:qmUserSubMaps ?submlist .
  11334. ?submlist ?p ?subm . filter (?p != rdf:type) . ?subm a [] } } ) as s1 );
  11335. gc_res := DB.DBA.RDF_QM_GC_SUBTREE (mapname, gc_flags);
  11336. if (gc_res is not null)
  11337. return gc_res;
  11338. commit work;
  11339. foreach (any submapname in submaps) do
  11340. {
  11341. DB.DBA.RDF_QM_GC_MAPPING_SUBTREE (submapname, gc_flags);
  11342. }
  11343. return NULL;
  11344. }
  11345. ;
  11346. create function DB.DBA.RDF_QM_DROP_MAPPING (in storage varchar, in mapname any) returns any
  11347. {
  11348. declare graphiri varchar;
  11349. declare qmid, qmgraph varchar;
  11350. declare silent integer;
  11351. qmid := get_keyword_ucase ('ID', mapname, NULL);
  11352. qmgraph := get_keyword_ucase ('GRAPH', mapname, NULL);
  11353. silent := get_keyword_ucase ('SILENT', mapname, 0);
  11354. graphiri := DB.DBA.JSO_SYS_GRAPH ();
  11355. if (qmid is null)
  11356. {
  11357. qmid := coalesce ((sparql
  11358. define input:storage ""
  11359. prefix virtrdf: <http://www.openlinksw.com/schemas/virtrdf#>
  11360. select ?s from <http://www.openlinksw.com/schemas/virtrdf#> where {
  11361. ?s rdf:type virtrdf:QuadMap .
  11362. ?s virtrdf:qmGraphRange-rvrFixedValue `iri(?:qmgraph)` .
  11363. ?s virtrdf:qmTableName "" .
  11364. } ));
  11365. if (qmid is null)
  11366. return vector (vector ('00100', 'Quad map for graph <' || qmgraph || '> is not found'));
  11367. }
  11368. else
  11369. {
  11370. if (silent and not exists ((sparql define input:storage ""
  11371. prefix rdfdf: <http://www.openlinksw.com/virtrdf-data-formats#>
  11372. select (1) where {
  11373. graph ?:graphiri {
  11374. `iri(?:qmid)` a ?t } } ) ) )
  11375. return vector (vector ('00000', 'Quad map <' || qmid || '> does not exist, the DROP statement is ignored due to SILENT option'));
  11376. }
  11377. DB.DBA.RDF_QM_ASSERT_JSO_TYPE (qmid, 'http://www.openlinksw.com/schemas/virtrdf#QuadMap');
  11378. if (storage is null)
  11379. {
  11380. declare report, storages any;
  11381. vectorbld_init (storages);
  11382. for (sparql
  11383. define input:storage ""
  11384. select ?st where {
  11385. graph <http://www.openlinksw.com/schemas/virtrdf#> {
  11386. { ?st virtrdf:qsUserMaps ?subm .
  11387. ?subm ?p `iri(?:qmid)` }
  11388. union
  11389. { ?st virtrdf:qsDefaultMap `iri(?:qmid)` }
  11390. } } ) do
  11391. {
  11392. DB.DBA.RDF_QM_ASSERT_STORAGE_FLAG ("st", 0);
  11393. vectorbld_acc (storages, cast ("st" as varchar));
  11394. }
  11395. vectorbld_final (storages);
  11396. vectorbld_init (report);
  11397. foreach (varchar alt_st in storages) do
  11398. {
  11399. -- dbg_obj_princ ('Will run DB.DBA.RDF_QM_DELETE_MAPPING_FROM_STORAGE (', alt_st, ', NULL, ', qmid, ')');
  11400. DB.DBA.RDF_QM_DELETE_MAPPING_FROM_STORAGE (alt_st, NULL, qmid);
  11401. vectorbld_acc (report, vector ('00000', 'Quad map <' || qmid || '> is no longer used in storage <' || alt_st || '>'));
  11402. }
  11403. DB.DBA.RDF_QM_GC_MAPPING_SUBTREE (qmid, 0);
  11404. vectorbld_acc (report, vector ('00000', 'Quad map <' || qmid || '> is deleted'));
  11405. vectorbld_final (report);
  11406. if (length (storages))
  11407. report := vector_concat (report, DB.DBA.RDF_QM_APPLY_CHANGES (null, storages));
  11408. return report;
  11409. }
  11410. else
  11411. {
  11412. if (not exists (sparql
  11413. define input:storage ""
  11414. select ?st where {
  11415. graph <http://www.openlinksw.com/schemas/virtrdf#> {
  11416. { ?st virtrdf:qsUserMaps ?subm .
  11417. ?subm ?p `iri(?:qmid)` }
  11418. union
  11419. { ?st virtrdf:qsDefaultMap `iri(?:qmid)` }
  11420. filter (?st = iri(?:storage))
  11421. } } ) )
  11422. {
  11423. if (silent)
  11424. return vector (vector ('00000', 'Quad map <' || qmid || '> is not used in storage <' || storage || '>, the DROP statement is ignored due to SILENT option'));
  11425. signal ('22023', 'Quad map <' || qmid || '> is not used in storage <' || storage || '>');
  11426. }
  11427. DB.DBA.RDF_QM_DELETE_MAPPING_FROM_STORAGE (storage, NULL, qmid);
  11428. DB.DBA.RDF_QM_GC_MAPPING_SUBTREE (qmid, 1);
  11429. return vector (vector ('00000', 'Quad map <' || qmid || '> is no longer used in storage <' || storage || '>'));
  11430. }
  11431. }
  11432. ;
  11433. create function DB.DBA.RDF_QM_MACROEXPAND_TEMPLATE (in iritmpl varchar) returns varchar
  11434. {
  11435. declare pos integer;
  11436. pos := strstr (iritmpl, '^{URIQADefaultHost}^');
  11437. if (pos is not null)
  11438. {
  11439. declare host varchar;
  11440. host := registry_get ('URIQADefaultHost');
  11441. if (not isstring (host))
  11442. signal ('22023', 'Can not use ^{URIQADefaultHost}^ in IRI template if there is no DefaultHost parameter in [URIQA] section of Virtuoso configuration file');
  11443. iritmpl := replace (iritmpl, '^{URIQADefaultHost}^', host);
  11444. }
  11445. pos := strstr (iritmpl, '^{DynamicLocalFormat}^');
  11446. if (pos is not null)
  11447. {
  11448. declare host varchar;
  11449. host := registry_get ('URIQADefaultHost');
  11450. if (not isstring (host))
  11451. signal ('22023', 'Can not use ^{DynamicLocalFormat}^ in IRI template if there is no DefaultHost parameter in [URIQA] section of Virtuoso configuration file');
  11452. -- if (atoi (coalesce (virtuoso_ini_item_value ('URIQA', 'DynamicLocal'), '0')))
  11453. -- signal ('22023', 'Can not use ^{DynamicLocalFormat}^ in IRI template if DynamicLocal is not set to 1 in [URIQA] section of Virtuoso configuration file');
  11454. if ((pos > 0) and (pos < 10) and strchr (subseq (iritmpl, 0, pos), ':') is not null)
  11455. signal ('22023', 'Misplaced ^{DynamicLocalFormat}^: its expansion will contain protocol prefix but the template contains one already');
  11456. if (strchr (host, ':') is not null)
  11457. iritmpl := replace (iritmpl, '^{DynamicLocalFormat}^', 'http://%{WSHostName}U:%{WSHostPort}U');
  11458. else
  11459. iritmpl := replace (iritmpl, '^{DynamicLocalFormat}^', 'http://%{WSHost}U');
  11460. }
  11461. pos := strstr (iritmpl, '^{');
  11462. if (pos is not null)
  11463. {
  11464. declare pos2 integer;
  11465. pos2 := strstr (subseq (iritmpl, pos), '^}');
  11466. if (pos2 is not null)
  11467. signal ('22023', 'The macro ' || subseq (iritmpl, pos, pos + pos2 + 2) || ' is not known, supported names are ^{URIQADefaultHost}^ and ^{DynamicLocalFormat}^');
  11468. }
  11469. return iritmpl;
  11470. }
  11471. ;
  11472. create function DB.DBA.RDF_QM_CBD_OF_IRI_CLASS (in classiri varchar) returns any
  11473. {
  11474. declare descr any;
  11475. descr := ((sparql define input:storage ""
  11476. construct {
  11477. <class> ?cp ?co .
  11478. <class> virtrdf:qmfValRange-rvrSprintffs <sprintffs> .
  11479. <sprintffs> ?sffp ?sffo .
  11480. <class> virtrdf:qmfSuperFormats <sups> .
  11481. <sups> ?supp ?supo . }
  11482. from <http://www.openlinksw.com/schemas/virtrdf#>
  11483. where {
  11484. {
  11485. `iri(?:classiri)` ?cp ?co .
  11486. filter (!(?cp in (virtrdf:qmfValRange-rvrSprintffs, virtrdf:qmfSuperFormats)))
  11487. } union {
  11488. `iri(?:classiri)` virtrdf:qmfValRange-rvrSprintffs ?sffs .
  11489. optional { ?sffs ?sffp ?sffo . }
  11490. } union {
  11491. `iri(?:classiri)` virtrdf:qmfSuperFormats ?sups .
  11492. optional { ?sups ?supp ?supo . FILTER (str(?supo) != bif:concat (str(?:classiri), '-nullable')) }
  11493. } } ) );
  11494. descr := dict_list_keys (descr, 2);
  11495. rowvector_digit_sort (descr, 0, 1);
  11496. rowvector_digit_sort (descr, 1, 1);
  11497. return descr;
  11498. }
  11499. ;
  11500. create function DB.DBA.RDF_QM_DEFINE_IRI_CLASS_FORMAT (in classiri varchar, in iritmpl varchar, in arglist any, in options any, in origclassiri varchar := null) returns any
  11501. {
  11502. declare graphiri varchar;
  11503. declare sprintffsid, superformatsid, nullablesuperformatid varchar;
  11504. declare basetype, basetypeiri varchar;
  11505. declare bij, deref integer;
  11506. declare sffs, res any;
  11507. declare argctr, arglist_len, isnotnull, sff_ctr, sff_count, bij_sff_count integer;
  11508. declare needs_arg_dtps integer;
  11509. declare arg_dtps varchar;
  11510. graphiri := DB.DBA.JSO_SYS_GRAPH ();
  11511. if (get_keyword_ucase ('DATATYPE', options) is not null or get_keyword_ucase ('LANG', options) is not null)
  11512. signal ('22023', 'IRI class <' || classiri || '> can not have DATATYPE or LANG options specified');
  11513. bij := get_keyword_ucase ('BIJECTION', options, 0);
  11514. deref := get_keyword_ucase ('DEREF', options, 0);
  11515. sffs := get_keyword_ucase ('RETURNS', options);
  11516. if (sffs is null)
  11517. sffs := vector (iritmpl); -- note that this is before macroexpand
  11518. sff_count := length (sffs);
  11519. iritmpl := DB.DBA.RDF_QM_MACROEXPAND_TEMPLATE (iritmpl);
  11520. sprintffsid := classiri || '--Sprintffs';
  11521. superformatsid := classiri || '--SuperFormats';
  11522. nullablesuperformatid := null;
  11523. res := vector ();
  11524. foreach (any arg in arglist) do
  11525. if (UNAME'in' <> arg[0])
  11526. signal ('22023', 'Only "in" parameters are now supported in argument lists of class formats, "' || arg[0] || '" is not supported in CREATE IRI CLASS <' || classiri || '>' );
  11527. arglist_len := length (arglist);
  11528. isnotnull := 1;
  11529. needs_arg_dtps := 0;
  11530. arg_dtps := '';
  11531. if (arglist_len <> 1)
  11532. {
  11533. declare type_name varchar;
  11534. declare dtp integer;
  11535. if (arglist_len = 0)
  11536. basetype := 'zeropart-uri';
  11537. else
  11538. basetype := 'multipart-uri';
  11539. for (argctr := 0; (argctr < arglist_len) and isnotnull; argctr := argctr + 1)
  11540. {
  11541. if (not (coalesce (arglist[argctr][3], 0)))
  11542. isnotnull := 0;
  11543. type_name := lower (arglist[argctr][2]);
  11544. dtp := case (type_name)
  11545. when 'integer' then __tag of integer
  11546. when 'varchar' then __tag of varchar
  11547. when 'date' then __tag of date
  11548. when 'datetime' then __tag of datetime
  11549. when 'double precision' then __tag of double precision
  11550. when 'numeric' then __tag of numeric
  11551. when 'nvarchar' then __tag of nvarchar
  11552. else 255 end;
  11553. if (type_name = 'nvarchar')
  11554. needs_arg_dtps := 1;
  11555. arg_dtps := arg_dtps || chr (bit_and (127, dtp));
  11556. }
  11557. }
  11558. else /* arglist is 1 item long */
  11559. {
  11560. basetype := lower (arglist[0][2]);
  11561. if (not (basetype in ('integer', 'varchar', 'date', /* 'datetime', 'double precision',*/ 'numeric', 'nvarchar')))
  11562. signal ('22023', 'The datatype "' || basetype || '" is not supported in CREATE IRI CLASS <' || classiri || '>' );
  11563. basetype := 'sql-' || replace (basetype, ' ', '') || '-uri';
  11564. if (not (coalesce (arglist[0][3], 0)))
  11565. isnotnull := 0;
  11566. if (basetype = 'nvarchar')
  11567. {
  11568. needs_arg_dtps := 1;
  11569. arg_dtps := chr (bit_and (127, __tag of nvarchar));
  11570. }
  11571. }
  11572. if (not isnotnull)
  11573. basetype := basetype || '-nullable';
  11574. basetypeiri := 'http://www.openlinksw.com/virtrdf-data-formats#' || basetype;
  11575. if (origclassiri is null)
  11576. {
  11577. if (isnotnull and (arglist_len > 0))
  11578. {
  11579. declare arglist_copy any;
  11580. if (classiri like '%-nullable')
  11581. signal ('22023', 'The name of non-nullable IRI class in CREATE IRI CLASS <' || classiri || '> is misleading' );
  11582. arglist_copy := arglist;
  11583. for (argctr := 0; (argctr < arglist_len); argctr := argctr + 1)
  11584. arglist_copy[argctr][3] := 0;
  11585. nullablesuperformatid := classiri || '-nullable';
  11586. res := vector_concat (res,
  11587. DB.DBA.RDF_QM_DEFINE_IRI_CLASS_FORMAT (nullablesuperformatid, iritmpl, arglist_copy, options, NULL) );
  11588. }
  11589. origclassiri := classiri;
  11590. }
  11591. if (DB.DBA.RDF_QM_ASSERT_JSO_TYPE (classiri, 'http://www.openlinksw.com/schemas/virtrdf#QuadMapFormat', 1))
  11592. {
  11593. declare side_s IRI_ID;
  11594. side_s := DB.DBA.RDF_QM_GC_SUBTREE (classiri, 2);
  11595. if (side_s is not null)
  11596. {
  11597. declare tmpname varchar;
  11598. declare old_descr, new_descr any;
  11599. tmpname := uuid();
  11600. { declare exit handler for sqlstate '*' {
  11601. signal ('22023', 'Can not change IRI class <' || classiri || '> because it is used by other quad map objects, e.g., <' || id_to_iri_nosignal (side_s) || '>; moreover, the new declaration may be invalid.'); };
  11602. DB.DBA.RDF_QM_DEFINE_IRI_CLASS_FORMAT (tmpname, iritmpl, arglist, options, classiri);
  11603. }
  11604. old_descr := DB.DBA.RDF_QM_CBD_OF_IRI_CLASS(classiri);
  11605. new_descr := DB.DBA.RDF_QM_CBD_OF_IRI_CLASS(tmpname);
  11606. -- dbg_obj_princ ('old descr is ', old_descr);
  11607. -- dbg_obj_princ ('new descr is ', new_descr);
  11608. if (md5 (serialize (old_descr)) = md5 (serialize (new_descr)))
  11609. {
  11610. sparql define input:storage ""
  11611. delete from graph <http://www.openlinksw.com/schemas/virtrdf#> { `iri(?:tmpname)` ?p ?o }
  11612. where { `iri(?:tmpname)` ?p ?o };
  11613. return vector (vector ('00000', 'Previous definition of IRI class <' || classiri || '> is identical to the new one, not touched'));
  11614. }
  11615. signal ('22023', 'Can not change IRI class <' || classiri || '> because it is used by other quad map objects, e.g., <' || id_to_iri_nosignal (side_s) || '>');
  11616. }
  11617. res := vector_concat (res, vector (vector ('00000', 'Previous definition of IRI class <' || classiri || '> has been dropped')));
  11618. }
  11619. else
  11620. res := vector ();
  11621. if (bij)
  11622. {
  11623. if (__sprintff_is_proven_unparseable (iritmpl))
  11624. signal ('22023', 'IRI class <' || classiri || '> has OPTION (BIJECTION) but its format string can not be unambiguously parsed by sprintf_inverse()');
  11625. }
  11626. else
  11627. {
  11628. if (__sprintff_is_proven_bijection (iritmpl))
  11629. bij := 1;
  11630. }
  11631. bij_sff_count := 0;
  11632. sparql define input:storage ""
  11633. prefix rdfdf: <http://www.openlinksw.com/virtrdf-data-formats#>
  11634. delete from graph <http://www.openlinksw.com/schemas/virtrdf#> { ?s ?p ?o }
  11635. from <http://www.openlinksw.com/schemas/virtrdf#>
  11636. where { ?s ?p ?o . filter (?s = iri(?:sprintffsid)) };
  11637. for (sff_ctr := 0; sff_ctr < sff_count; sff_ctr := sff_ctr + 1)
  11638. {
  11639. declare sff varchar;
  11640. sff := sffs [sff_ctr];
  11641. sff := DB.DBA.RDF_QM_MACROEXPAND_TEMPLATE (sff);
  11642. if ((not bij) and __sprintff_is_proven_bijection (sff))
  11643. bij_sff_count := bij_sff_count + 1;
  11644. sparql define input:storage ""
  11645. prefix rdfdf: <http://www.openlinksw.com/virtrdf-data-formats#>
  11646. insert in graph <http://www.openlinksw.com/schemas/virtrdf#> {
  11647. `iri(?:sprintffsid)`
  11648. `iri (bif:sprintf ("%s%d", str (rdf:_), ?:sff_ctr+1))` ?:sff };
  11649. }
  11650. if ((not bij) and (bij_sff_count = sff_count) and (bij_sff_count > 0))
  11651. bij := 1;
  11652. if (not needs_arg_dtps)
  11653. arg_dtps := NULL;
  11654. sparql define input:storage ""
  11655. prefix rdfdf: <http://www.openlinksw.com/virtrdf-data-formats#>
  11656. delete from graph <http://www.openlinksw.com/schemas/virtrdf#> { ?s ?p ?o }
  11657. from <http://www.openlinksw.com/schemas/virtrdf#>
  11658. where { ?s ?p ?o . filter (?s = iri(?:classiri)) };
  11659. sparql define input:storage ""
  11660. prefix rdfdf: <http://www.openlinksw.com/virtrdf-data-formats#>
  11661. delete from graph <http://www.openlinksw.com/schemas/virtrdf#> { ?s ?p ?o }
  11662. from <http://www.openlinksw.com/schemas/virtrdf#>
  11663. where { ?s ?p ?o . filter (?s = iri(?:superformatsid)) };
  11664. sparql define input:storage ""
  11665. prefix rdfdf: <http://www.openlinksw.com/virtrdf-data-formats#>
  11666. insert in graph <http://www.openlinksw.com/schemas/virtrdf#>
  11667. {
  11668. `iri(?:classiri)`
  11669. rdf:type virtrdf:QuadMapFormat ;
  11670. virtrdf:inheritFrom `iri(?:basetypeiri)`;
  11671. virtrdf:noInherit virtrdf:qmfName ;
  11672. virtrdf:noInherit virtrdf:qmfCustomString1 ;
  11673. virtrdf:qmfName `bif:concat (?:basetype, '-user-', ?:origclassiri)` ;
  11674. virtrdf:qmfCustomString1 ?:iritmpl ;
  11675. virtrdf:qmfColumnCount ?:arglist_len ;
  11676. virtrdf:qmfSuperFormats `iri(?:superformatsid)` ;
  11677. virtrdf:qmfIsBijection ?:bij ;
  11678. virtrdf:qmfDerefFlags ?:deref ;
  11679. virtrdf:qmfArgDtps ?:arg_dtps ;
  11680. virtrdf:qmfValRange-rvrRestrictions
  11681. virtrdf:SPART_VARR_IS_REF ,
  11682. virtrdf:SPART_VARR_IS_IRI ,
  11683. virtrdf:SPART_VARR_SPRINTFF ;
  11684. virtrdf:qmfValRange-rvrSprintffs `iri(?:sprintffsid)` ;
  11685. virtrdf:qmfValRange-rvrSprintffCount ?:sff_count .
  11686. `iri(?:sprintffsid)`
  11687. rdf:type virtrdf:array-of-string .
  11688. `iri(?:superformatsid)`
  11689. rdf:type virtrdf:array-of-QuadMapFormat };
  11690. if (isnotnull and (arglist_len > 0))
  11691. {
  11692. sparql define input:storage ""
  11693. prefix rdfdf: <http://www.openlinksw.com/virtrdf-data-formats#>
  11694. insert in graph <http://www.openlinksw.com/schemas/virtrdf#> {
  11695. `iri(?:classiri)`
  11696. virtrdf:qmfValRange-rvrRestrictions
  11697. virtrdf:SPART_VARR_NOT_NULL .
  11698. `iri(?:superformatsid)`
  11699. rdf:_1 `iri(?:nullablesuperformatid)` };
  11700. }
  11701. commit work;
  11702. return vector_concat (res, vector_concat (res, vector (vector ('00000', 'IRI class <' || classiri || '> has been defined (inherited from rdfdf:' || basetype || ')'))));
  11703. }
  11704. ;
  11705. create function DB.DBA.RDF_QM_DEFINE_IRI_CLASS_FUNCTIONS (in classiri varchar, in fheaders any, in options any, in origclassiri varchar := null) returns any
  11706. {
  11707. /*
  11708. fheaders is, say,
  11709. vector ( '
  11710. vector ( 'DB.DBA.RDF_DF_GRANTEE_ID_URI' ,
  11711. vector (
  11712. vector ( 306, 'id' , 'integer' , NULL ) ), 'varchar' , NULL ),
  11713. vector ( 'DB.DBA.RDF_DF_GRANTEE_ID_URI_INVERSE' ,
  11714. vector (
  11715. vector ( 306, 'id_iri' , 'varchar' , NULL ) ), 'integer' , NULL ) ) )
  11716. */
  11717. declare uriprint any;
  11718. declare uriprintname, uriparsename varchar;
  11719. declare arglist_len, isnotnull integer;
  11720. declare graphiri varchar;
  11721. declare superformatsid, nullablesuperformatid varchar;
  11722. declare bij, deref integer;
  11723. declare sffs any;
  11724. declare res any;
  11725. graphiri := DB.DBA.JSO_SYS_GRAPH ();
  11726. superformatsid := classiri || '--SuperFormats';
  11727. nullablesuperformatid := null;
  11728. if (get_keyword_ucase ('DATATYPE', options) is not null or get_keyword_ucase ('LANG', options) is not null)
  11729. signal ('22023', 'IRI class <' || classiri || '> can not have DATATYPE or LANG options specified');
  11730. bij := get_keyword_ucase ('BIJECTION', options, 0);
  11731. deref := get_keyword_ucase ('DEREF', options, 0);
  11732. sffs := get_keyword_ucase ('RETURNS', options);
  11733. DB.DBA.RDF_QM_ASSERT_JSO_TYPE (classiri, NULL);
  11734. DB.DBA.RDF_QM_CHECK_CLASS_FUNCTION_HEADERS (fheaders, 1, 0, 'IRI composing', 'IRI parsing', bij, deref);
  11735. uriprint := fheaders[0];
  11736. uriprintname := uriprint[0];
  11737. declare arglist, basetype, basetypeiri varchar;
  11738. arglist := uriprint[1];
  11739. arglist_len := length (arglist);
  11740. if (arglist_len <> 1)
  11741. {
  11742. if (arglist_len = 0)
  11743. basetype := 'zeropart-uri-fn-nullable';
  11744. else
  11745. basetype := 'multipart-uri-fn-nullable';
  11746. isnotnull := 0;
  11747. }
  11748. else
  11749. {
  11750. basetype := lower (arglist[0][2]);
  11751. if (not (basetype in ('integer', 'varchar', 'date', 'datetime', 'double precision', 'numeric', 'nvarchar')))
  11752. signal ('22023', 'The datatype "' || basetype || '" is not supported in CREATE IRI CLASS <' || classiri || '> USING FUNCTION' );
  11753. basetype := 'sql-' || replace (basetype, ' ', '') || '-uri-fn';
  11754. if (coalesce (arglist[0][3], 0))
  11755. isnotnull := 1;
  11756. else
  11757. {
  11758. basetype := basetype || '-nullable';
  11759. isnotnull := 0;
  11760. }
  11761. }
  11762. basetypeiri := 'http://www.openlinksw.com/virtrdf-data-formats#' || basetype;
  11763. if (origclassiri is null)
  11764. origclassiri := classiri;
  11765. if (DB.DBA.RDF_QM_ASSERT_JSO_TYPE (classiri, 'http://www.openlinksw.com/schemas/virtrdf#QuadMapFormat', 1))
  11766. {
  11767. declare side_s IRI_ID;
  11768. side_s := DB.DBA.RDF_QM_GC_SUBTREE (classiri, 2);
  11769. if (side_s is not null)
  11770. {
  11771. declare tmpname varchar;
  11772. declare old_descr, new_descr any;
  11773. tmpname := uuid();
  11774. { declare exit handler for sqlstate '*' {
  11775. signal ('22023', 'Can not change IRI class <' || classiri || '> because it is used by other quad map objects, e.g., <' || id_to_iri_nosignal (side_s) || '>; moreover, the new declaration may be invalid.'); };
  11776. DB.DBA.RDF_QM_DEFINE_IRI_CLASS_FUNCTIONS (tmpname, fheaders, options, classiri);
  11777. }
  11778. old_descr := DB.DBA.RDF_QM_CBD_OF_IRI_CLASS(classiri);
  11779. new_descr := DB.DBA.RDF_QM_CBD_OF_IRI_CLASS(tmpname);
  11780. if (md5 (serialize (old_descr)) = md5 (serialize (new_descr)))
  11781. {
  11782. sparql define input:storage ""
  11783. delete from graph <http://www.openlinksw.com/schemas/virtrdf#> { `iri(?:tmpname)` ?p ?o }
  11784. where { `iri(?:tmpname)` ?p ?o };
  11785. return vector (vector ('00000', 'Previous definition of IRI class <' || classiri || '> is identical to the new one, not touched'));
  11786. }
  11787. signal ('22023', 'Can not change class <' || classiri || '> because it is used by other quad map objects, e.g., <' || id_to_iri_nosignal (side_s) || '>');
  11788. }
  11789. res := vector (vector ('00000', 'Previous definition of class <' || classiri || '> has been dropped'));
  11790. }
  11791. else
  11792. res := vector ();
  11793. sparql define input:storage ""
  11794. prefix rdfdf: <http://www.openlinksw.com/virtrdf-data-formats#>
  11795. delete from graph <http://www.openlinksw.com/schemas/virtrdf#> { ?s ?p ?o }
  11796. from <http://www.openlinksw.com/schemas/virtrdf#>
  11797. where { ?s ?p ?o . filter (?s = iri(?:classiri)) };
  11798. sparql define input:storage ""
  11799. prefix rdfdf: <http://www.openlinksw.com/virtrdf-data-formats#>
  11800. delete from graph <http://www.openlinksw.com/schemas/virtrdf#> { ?s ?p ?o }
  11801. from <http://www.openlinksw.com/schemas/virtrdf#>
  11802. where { ?s ?p ?o . filter (?s = iri(?:superformatsid)) };
  11803. sparql define input:storage ""
  11804. prefix rdfdf: <http://www.openlinksw.com/virtrdf-data-formats#>
  11805. insert in graph <http://www.openlinksw.com/schemas/virtrdf#> {
  11806. `iri(?:classiri)`
  11807. rdf:type virtrdf:QuadMapFormat;
  11808. virtrdf:inheritFrom `iri(?:basetypeiri)`;
  11809. virtrdf:noInherit virtrdf:qmfName ;
  11810. virtrdf:noInherit virtrdf:qmfCustomString1 ;
  11811. virtrdf:qmfName `bif:concat (?:basetype, '-user-', ?:origclassiri)` ;
  11812. virtrdf:qmfColumnCount ?:arglist_len ;
  11813. virtrdf:qmfCustomString1 ?:uriprintname ;
  11814. virtrdf:qmfSuperFormats `iri(?:superformatsid)` ;
  11815. virtrdf:qmfIsBijection ?:bij ;
  11816. virtrdf:qmfDerefFlags ?:deref ;
  11817. virtrdf:qmfValRange-rvrRestrictions
  11818. virtrdf:SPART_VARR_IS_REF ,
  11819. virtrdf:SPART_VARR_IS_IRI ,
  11820. virtrdf:SPART_VARR_IRI_CALC .
  11821. `iri(?:superformatsid)`
  11822. rdf:type virtrdf:array-of-QuadMapFormat };
  11823. if (isnotnull)
  11824. {
  11825. sparql define input:storage ""
  11826. prefix rdfdf: <http://www.openlinksw.com/virtrdf-data-formats#>
  11827. insert in graph <http://www.openlinksw.com/schemas/virtrdf#> {
  11828. `iri(?:classiri)`
  11829. virtrdf:qmfValRange-rvrRestrictions
  11830. virtrdf:SPART_VARR_NOT_NULL };
  11831. }
  11832. if (sffs is not null)
  11833. {
  11834. declare sff_count, sff_ctr integer;
  11835. declare sffsid varchar;
  11836. sffsid := classiri || '--Sprintffs';
  11837. sff_count := length (sffs);
  11838. sparql define input:storage ""
  11839. prefix rdfdf: <http://www.openlinksw.com/virtrdf-data-formats#>
  11840. delete from graph <http://www.openlinksw.com/schemas/virtrdf#> { ?s ?p ?o }
  11841. from <http://www.openlinksw.com/schemas/virtrdf#>
  11842. where { ?s ?p ?o . filter (?s = iri(?:sffsid)) };
  11843. sparql define input:storage ""
  11844. prefix rdfdf: <http://www.openlinksw.com/virtrdf-data-formats#>
  11845. insert in graph <http://www.openlinksw.com/schemas/virtrdf#> {
  11846. `iri(?:classiri)`
  11847. virtrdf:qmfValRange-rvrRestrictions
  11848. virtrdf:SPART_VARR_SPRINTFF ;
  11849. virtrdf:qmfValRange-rvrSprintffs `iri(?:sffsid)` ;
  11850. virtrdf:qmfValRange-rvrSprintffCount ?:sff_count .
  11851. `iri(?:sffsid)`
  11852. rdf:type virtrdf:array-of-string };
  11853. for (sff_ctr := 0; sff_ctr < sff_count; sff_ctr := sff_ctr + 1)
  11854. {
  11855. declare sff varchar;
  11856. sff := sffs [sff_ctr];
  11857. sff := DB.DBA.RDF_QM_MACROEXPAND_TEMPLATE (sff);
  11858. sparql define input:storage ""
  11859. prefix rdfdf: <http://www.openlinksw.com/virtrdf-data-formats#>
  11860. insert in graph <http://www.openlinksw.com/schemas/virtrdf#> {
  11861. `iri(?:sffsid)`
  11862. `iri (bif:sprintf ("%s%d", str (rdf:_), ?:sff_ctr+1))` ?:sff };
  11863. }
  11864. }
  11865. commit work;
  11866. return vector_concat (res, vector (vector ('00000', 'IRI class <' || classiri || '> has been defined (inherited from rdfdf:' || basetype || ') using ' || uriprintname)));
  11867. }
  11868. ;
  11869. create function DB.DBA.RDF_QM_DEFINE_LITERAL_CLASS_FORMAT (in classiri varchar, in iritmpl varchar, in arglist any, in options any, in origclassiri varchar := null) returns any
  11870. {
  11871. declare graphiri varchar;
  11872. declare sprintffsid, superformatsid, nullablesuperformatid varchar;
  11873. declare basetype, basetypeiri varchar;
  11874. declare const_dt, dt_expn, const_lang varchar;
  11875. declare bij, deref integer;
  11876. declare sffs, res any;
  11877. declare argctr, arglist_len, isnotnull, sff_ctr, sff_count, bij_sff_count integer;
  11878. declare needs_arg_dtps integer;
  11879. declare arg_dtps varchar;
  11880. graphiri := DB.DBA.JSO_SYS_GRAPH ();
  11881. const_dt := get_keyword_ucase ('DATATYPE', options);
  11882. const_lang := get_keyword_ucase ('LANG', options);
  11883. bij := get_keyword_ucase ('BIJECTION', options, 0);
  11884. deref := get_keyword_ucase ('DEREF', options, 0);
  11885. sffs := get_keyword_ucase ('RETURNS', options);
  11886. if (sffs is null)
  11887. sffs := vector (iritmpl); -- note that this is before macroexpand
  11888. sff_count := length (sffs);
  11889. iritmpl := DB.DBA.RDF_QM_MACROEXPAND_TEMPLATE (iritmpl);
  11890. sprintffsid := classiri || '--Sprintffs';
  11891. superformatsid := classiri || '--SuperFormats';
  11892. nullablesuperformatid := null;
  11893. res := vector ();
  11894. foreach (any arg in arglist) do
  11895. if (UNAME'in' <> arg[0])
  11896. signal ('22023', 'Only "in" parameters are now supported in argument lists of class formats, "' || arg[0] || '" is not supported in CREATE IRI CLASS <' || classiri || '>' );
  11897. arglist_len := length (arglist);
  11898. isnotnull := 1;
  11899. needs_arg_dtps := 0;
  11900. arg_dtps := '';
  11901. if (arglist_len <> 1)
  11902. {
  11903. declare type_name varchar;
  11904. declare dtp integer;
  11905. if (arglist_len = 0)
  11906. basetype := 'zeropart-literal';
  11907. else
  11908. basetype := 'multipart-literal';
  11909. for (argctr := 0; (argctr < arglist_len) and isnotnull; argctr := argctr + 1)
  11910. {
  11911. if (not (coalesce (arglist[argctr][3], 0)))
  11912. isnotnull := 0;
  11913. type_name := lower (arglist[argctr][2]);
  11914. dtp := case (type_name)
  11915. when 'integer' then __tag of integer
  11916. when 'varchar' then __tag of varchar
  11917. when 'date' then __tag of date
  11918. when 'datetime' then __tag of datetime
  11919. when 'double precision' then __tag of double precision
  11920. when 'numeric' then __tag of numeric
  11921. when 'nvarchar' then __tag of nvarchar
  11922. else 255 end;
  11923. if (type_name = 'nvarchar')
  11924. needs_arg_dtps := 1;
  11925. arg_dtps := arg_dtps || chr (bit_and (127, dtp));
  11926. }
  11927. }
  11928. else /* arglist is 1 item long */
  11929. {
  11930. basetype := lower (arglist[0][2]);
  11931. if (not (basetype in ('integer', 'varchar', 'date', 'datetime', 'double precision', 'numeric', 'nvarchar')))
  11932. signal ('22023', 'The datatype "' || basetype || '" is not supported in CREATE LITERAL CLASS <' || classiri || '>' );
  11933. basetype := 'sql-' || replace (basetype, ' ', '') || '-literal';
  11934. if (not (coalesce (arglist[0][3], 0)))
  11935. isnotnull := 0;
  11936. if (basetype = 'nvarchar')
  11937. {
  11938. needs_arg_dtps := 1;
  11939. arg_dtps := chr (bit_and (127, __tag of nvarchar));
  11940. }
  11941. }
  11942. if (not isnotnull)
  11943. basetype := basetype || '-nullable';
  11944. basetypeiri := 'http://www.openlinksw.com/virtrdf-data-formats#' || basetype;
  11945. if (const_dt is not null)
  11946. dt_expn := ' ' || WS.WS.STR_SQL_APOS (const_dt);
  11947. else
  11948. dt_expn := NULL;
  11949. if (origclassiri is null)
  11950. {
  11951. if (isnotnull and (arglist_len > 0))
  11952. {
  11953. declare arglist_copy any;
  11954. if (classiri like '%-nullable')
  11955. signal ('22023', 'The name of non-nullable literal class in CREATE LITERAL CLASS <' || classiri || '> is misleading' );
  11956. arglist_copy := arglist;
  11957. for (argctr := 0; (argctr < arglist_len); argctr := argctr + 1)
  11958. arglist_copy[argctr][3] := 0;
  11959. nullablesuperformatid := classiri || '-nullable';
  11960. res := vector_concat (res,
  11961. DB.DBA.RDF_QM_DEFINE_IRI_CLASS_FORMAT (nullablesuperformatid, iritmpl, arglist_copy, options, NULL) );
  11962. }
  11963. origclassiri := classiri;
  11964. }
  11965. if (DB.DBA.RDF_QM_ASSERT_JSO_TYPE (classiri, 'http://www.openlinksw.com/schemas/virtrdf#QuadMapFormat', 1))
  11966. {
  11967. declare side_s IRI_ID;
  11968. side_s := DB.DBA.RDF_QM_GC_SUBTREE (classiri, 2);
  11969. if (side_s is not null)
  11970. {
  11971. declare tmpname varchar;
  11972. declare old_descr, new_descr any;
  11973. tmpname := uuid();
  11974. { declare exit handler for sqlstate '*' {
  11975. signal ('22023', 'Can not change literal class <' || classiri || '> because it is used by other quad map objects, e.g., <' || id_to_iri_nosignal (side_s) || '>; moreover, the new declaration may be invalid.'); };
  11976. DB.DBA.RDF_QM_DEFINE_LITERAL_CLASS_FORMAT (tmpname, iritmpl, arglist, options, classiri);
  11977. }
  11978. old_descr := DB.DBA.RDF_QM_CBD_OF_IRI_CLASS(classiri);
  11979. new_descr := DB.DBA.RDF_QM_CBD_OF_IRI_CLASS(tmpname);
  11980. if (md5 (serialize (old_descr)) = md5 (serialize (new_descr)))
  11981. {
  11982. sparql define input:storage ""
  11983. delete from graph <http://www.openlinksw.com/schemas/virtrdf#> { `iri(?:tmpname)` ?p ?o }
  11984. where { `iri(?:tmpname)` ?p ?o };
  11985. return vector (vector ('00000', 'Previous definition of literal class <' || classiri || '> is identical to the new one, not touched'));
  11986. }
  11987. signal ('22023', 'Can not change IRI class <' || classiri || '> because it is used by other quad map objects, e.g., <' || id_to_iri_nosignal (side_s) || '>');
  11988. }
  11989. res := vector_concat (res, vector (vector ('00000', 'Previous definition of IRI class <' || classiri || '> has been dropped')));
  11990. }
  11991. else
  11992. res := vector ();
  11993. if (bij)
  11994. {
  11995. if (__sprintff_is_proven_unparseable (iritmpl))
  11996. signal ('22023', 'Literal class <' || classiri || '> has OPTION (BIJECTION) but its format string can not be unambiguously parsed by sprintf_inverse()');
  11997. }
  11998. else
  11999. {
  12000. if (__sprintff_is_proven_bijection (iritmpl))
  12001. bij := 1;
  12002. }
  12003. bij_sff_count := 0;
  12004. sparql define input:storage ""
  12005. prefix rdfdf: <http://www.openlinksw.com/virtrdf-data-formats#>
  12006. delete from graph <http://www.openlinksw.com/schemas/virtrdf#> { ?s ?p ?o }
  12007. from <http://www.openlinksw.com/schemas/virtrdf#>
  12008. where { ?s ?p ?o . filter (?s = iri(?:sprintffsid)) };
  12009. for (sff_ctr := 0; sff_ctr < sff_count; sff_ctr := sff_ctr + 1)
  12010. {
  12011. declare sff varchar;
  12012. sff := sffs [sff_ctr];
  12013. sff := DB.DBA.RDF_QM_MACROEXPAND_TEMPLATE (sff);
  12014. if ((not bij) and __sprintff_is_proven_bijection (sff))
  12015. bij_sff_count := bij_sff_count + 1;
  12016. sparql define input:storage ""
  12017. prefix rdfdf: <http://www.openlinksw.com/virtrdf-data-formats#>
  12018. insert in graph <http://www.openlinksw.com/schemas/virtrdf#> {
  12019. `iri(?:sprintffsid)`
  12020. `iri (bif:sprintf ("%s%d", str (rdf:_), ?:sff_ctr+1))` ?:sff };
  12021. }
  12022. if ((not bij) and (bij_sff_count = sff_count) and (bij_sff_count > 0))
  12023. bij := 1;
  12024. if (not needs_arg_dtps)
  12025. arg_dtps := NULL;
  12026. sparql define input:storage ""
  12027. prefix rdfdf: <http://www.openlinksw.com/virtrdf-data-formats#>
  12028. delete from graph <http://www.openlinksw.com/schemas/virtrdf#> { ?s ?p ?o }
  12029. from <http://www.openlinksw.com/schemas/virtrdf#>
  12030. where { ?s ?p ?o . filter (?s = iri(?:classiri)) };
  12031. sparql define input:storage ""
  12032. prefix rdfdf: <http://www.openlinksw.com/virtrdf-data-formats#>
  12033. delete from graph <http://www.openlinksw.com/schemas/virtrdf#> { ?s ?p ?o }
  12034. from <http://www.openlinksw.com/schemas/virtrdf#>
  12035. where { ?s ?p ?o . filter (?s = iri(?:superformatsid)) };
  12036. sparql define input:storage ""
  12037. prefix rdfdf: <http://www.openlinksw.com/virtrdf-data-formats#>
  12038. insert in graph <http://www.openlinksw.com/schemas/virtrdf#>
  12039. {
  12040. `iri(?:classiri)`
  12041. rdf:type virtrdf:QuadMapFormat ;
  12042. virtrdf:inheritFrom `iri(?:basetypeiri)`;
  12043. virtrdf:noInherit virtrdf:qmfName ;
  12044. virtrdf:noInherit virtrdf:qmfCustomString1 ;
  12045. virtrdf:qmfName `bif:concat (?:basetype, '-user-', ?:origclassiri)` ;
  12046. virtrdf:qmfCustomString1 ?:iritmpl ;
  12047. virtrdf:qmfDatatypeOfShortTmpl ?:dt_expn ;
  12048. virtrdf:qmfColumnCount ?:arglist_len ;
  12049. virtrdf:qmfSuperFormats `iri(?:superformatsid)` ;
  12050. virtrdf:qmfIsBijection ?:bij ;
  12051. virtrdf:qmfDerefFlags ?:deref ;
  12052. virtrdf:qmfArgDtps ?:arg_dtps ;
  12053. virtrdf:qmfValRange-rvrRestrictions virtrdf:SPART_VARR_IS_LIT, virtrdf:SPART_VARR_IRI_CALC;
  12054. virtrdf:qmfValRange-rvrDatatype ?:const_dt ;
  12055. virtrdf:qmfValRange-rvrLanguage ?:const_lang ;
  12056. virtrdf:qmfValRange-rvrSprintffs `iri(?:sprintffsid)` ;
  12057. virtrdf:qmfValRange-rvrSprintffCount ?:sff_count .
  12058. `iri(?:sprintffsid)`
  12059. rdf:type virtrdf:array-of-string .
  12060. `iri(?:superformatsid)`
  12061. rdf:type virtrdf:array-of-QuadMapFormat };
  12062. if (const_dt is not null)
  12063. {
  12064. sparql define input:storage ""
  12065. prefix rdfdf: <http://www.openlinksw.com/virtrdf-data-formats#>
  12066. insert in graph <http://www.openlinksw.com/schemas/virtrdf#> {
  12067. `iri(?:classiri)`
  12068. virtrdf:qmfValRange-rvrRestrictions virtrdf:SPART_VARR_TYPED };
  12069. }
  12070. commit work;
  12071. return vector_concat (res, vector_concat (res, vector (vector ('00000', 'Literal class <' || classiri || '> has been defined (inherited from rdfdf:' || basetype || ')'))));
  12072. }
  12073. ;
  12074. create function DB.DBA.RDF_QM_DEFINE_LITERAL_CLASS_FUNCTIONS (in classiri varchar, in fheaders any, in options any, in origclassiri varchar := null) returns any
  12075. {
  12076. /*
  12077. fheaders is identical to DB.DBA.RDF_QM_DEFINE_IRI_CLASS_FUNCTIONS
  12078. */
  12079. declare uriprint any;
  12080. declare uriprintname, uriparsename varchar;
  12081. declare arglist_len integer;
  12082. declare superformatsid, nullablesuperformatid varchar;
  12083. declare res any;
  12084. declare const_dt, dt_expn, const_lang varchar;
  12085. declare bij, deref integer;
  12086. superformatsid := classiri || '--SuperFormats';
  12087. nullablesuperformatid := null;
  12088. const_dt := get_keyword_ucase ('DATATYPE', options);
  12089. const_lang := get_keyword_ucase ('LANG', options);
  12090. bij := get_keyword_ucase ('BIJECTION', options, 0);
  12091. deref := get_keyword_ucase ('DEREF', options, 0);
  12092. DB.DBA.RDF_QM_ASSERT_JSO_TYPE (classiri, NULL);
  12093. DB.DBA.RDF_QM_CHECK_CLASS_FUNCTION_HEADERS (fheaders, 0, 0, 'LITERAL composing', 'LITERAL parsing', bij, deref);
  12094. uriprint := fheaders[0];
  12095. uriprintname := uriprint[0];
  12096. declare arglist, basetype, basetypeiri varchar;
  12097. arglist := uriprint[1];
  12098. arglist_len := length (arglist);
  12099. if (arglist_len <> 1)
  12100. {
  12101. if (arglist_len = 0)
  12102. basetype := 'zeropart-literal-fn-nullable';
  12103. else
  12104. basetype := 'multipart-literal-fn-nullable';
  12105. }
  12106. else
  12107. {
  12108. basetype := lower (arglist[0][2]);
  12109. if (not (basetype in ('integer', 'varchar' /*, 'date', 'double precision'*/, 'nvarchar')))
  12110. signal ('22023', 'The datatype "' || basetype || '" is not supported in CREATE IRI CLASS <' || classiri || '> USING FUNCTION' );
  12111. basetype := 'sql-' || replace (basetype, ' ', '') || '-literal-fn';
  12112. if (not (coalesce (arglist[0][3], 0)))
  12113. basetype := basetype || '-nullable';
  12114. }
  12115. basetypeiri := 'http://www.openlinksw.com/virtrdf-data-formats#' || basetype;
  12116. if (const_dt is not null)
  12117. dt_expn := ' ' || WS.WS.STR_SQL_APOS (const_dt);
  12118. else
  12119. dt_expn := NULL;
  12120. if (origclassiri is null)
  12121. origclassiri := classiri;
  12122. if (DB.DBA.RDF_QM_ASSERT_JSO_TYPE (classiri, 'http://www.openlinksw.com/schemas/virtrdf#QuadMapFormat', 1))
  12123. {
  12124. declare side_s IRI_ID;
  12125. side_s := DB.DBA.RDF_QM_GC_SUBTREE (classiri, 2);
  12126. if (side_s is not null)
  12127. {
  12128. declare tmpname varchar;
  12129. declare old_descr, new_descr any;
  12130. tmpname := uuid();
  12131. { declare exit handler for sqlstate '*' {
  12132. signal ('22023', 'Can not change IRI class <' || classiri || '> because it is used by other quad map objects, e.g., <' || id_to_iri_nosignal (side_s) || '>; moreover, the new declaration may be invalid.'); };
  12133. DB.DBA.RDF_QM_DEFINE_LITERAL_CLASS_FUNCTIONS (tmpname, fheaders, options, classiri);
  12134. }
  12135. old_descr := DB.DBA.RDF_QM_CBD_OF_IRI_CLASS(classiri);
  12136. new_descr := DB.DBA.RDF_QM_CBD_OF_IRI_CLASS(tmpname);
  12137. if (md5 (serialize (old_descr)) = md5 (serialize (new_descr)))
  12138. {
  12139. sparql define input:storage ""
  12140. delete from graph <http://www.openlinksw.com/schemas/virtrdf#> { `iri(?:tmpname)` ?p ?o }
  12141. where { `iri(?:tmpname)` ?p ?o };
  12142. return vector (vector ('00000', 'Previous definition of literal class <' || classiri || '> is identical to the new one, not touched'));
  12143. }
  12144. signal ('22023', 'Can not change class <' || classiri || '> because it is used by other quad map objects, e.g., <' || id_to_iri_nosignal (side_s) || '>');
  12145. }
  12146. res := vector (vector ('00000', 'Previous definition of class <' || classiri || '> has been dropped'));
  12147. }
  12148. else
  12149. res := vector ();
  12150. sparql define input:storage ""
  12151. prefix rdfdf: <http://www.openlinksw.com/virtrdf-data-formats#>
  12152. delete from graph <http://www.openlinksw.com/schemas/virtrdf#> { ?s ?p ?o }
  12153. from <http://www.openlinksw.com/schemas/virtrdf#>
  12154. where { ?s ?p ?o . filter (?s = iri(?:classiri)) };
  12155. sparql define input:storage ""
  12156. prefix rdfdf: <http://www.openlinksw.com/virtrdf-data-formats#>
  12157. delete from graph <http://www.openlinksw.com/schemas/virtrdf#> { ?s ?p ?o }
  12158. from <http://www.openlinksw.com/schemas/virtrdf#>
  12159. where { ?s ?p ?o . filter (?s = iri(?:superformatsid)) };
  12160. sparql define input:storage ""
  12161. prefix rdfdf: <http://www.openlinksw.com/virtrdf-data-formats#>
  12162. insert in graph <http://www.openlinksw.com/schemas/virtrdf#> {
  12163. `iri(?:classiri)`
  12164. rdf:type virtrdf:QuadMapFormat ;
  12165. virtrdf:inheritFrom `iri(?:basetypeiri)` ;
  12166. virtrdf:noInherit virtrdf:qmfName ;
  12167. virtrdf:noInherit virtrdf:qmfCustomString1 ;
  12168. virtrdf:qmfName `bif:concat (?:basetype, '-user-', ?:origclassiri)` ;
  12169. virtrdf:qmfColumnCount ?:arglist_len ;
  12170. virtrdf:qmfCustomString1 ?:uriprintname ;
  12171. virtrdf:qmfDatatypeOfShortTmpl ?:dt_expn ;
  12172. virtrdf:qmfIsBijection ?:bij ;
  12173. virtrdf:qmfDerefFlags ?:deref ;
  12174. virtrdf:qmfValRange-rvrRestrictions virtrdf:SPART_VARR_IS_LIT ;
  12175. virtrdf:qmfValRange-rvrDatatype ?:const_dt ;
  12176. virtrdf:qmfValRange-rvrLanguage ?:const_lang ;
  12177. virtrdf:qmfSuperFormats `iri(?:superformatsid)` .
  12178. `iri(?:superformatsid)`
  12179. rdf:type virtrdf:array-of-QuadMapFormat };
  12180. if (const_dt is not null)
  12181. {
  12182. sparql define input:storage ""
  12183. prefix rdfdf: <http://www.openlinksw.com/virtrdf-data-formats#>
  12184. insert in graph <http://www.openlinksw.com/schemas/virtrdf#> {
  12185. `iri(?:classiri)`
  12186. virtrdf:qmfValRange-rvrRestrictions virtrdf:SPART_VARR_TYPED };
  12187. }
  12188. commit work;
  12189. return vector_concat (res, vector (vector ('00000', 'LITERAL class <' || classiri || '> has been defined (inherited from rdfdf:' || basetype || ') using ' || uriprintname)));
  12190. }
  12191. ;
  12192. create function DB.DBA.RDF_QM_DEFINE_LITERAL_CLASS_WITH_FIXED_LANG (in coltype varchar, in o_lang varchar, in is_nullable integer := 0) returns any
  12193. {
  12194. declare src_lname, res_lname, src_fmtid, res_fmtid, src_baseid, res_baseid, superformatsid, nullablesuperformatid, o_lang_str varchar;
  12195. nullablesuperformatid := null;
  12196. if (not is_nullable)
  12197. nullablesuperformatid := DB.DBA.RDF_QM_DEFINE_LITERAL_CLASS_WITH_FIXED_LANG (coltype, o_lang, 1);
  12198. src_baseid := 'http://www.openlinksw.com/virtrdf-data-formats#' || 'sql-' || replace (coltype, ' ', '') || '-fixedlang-x-any' ;
  12199. res_baseid := 'http://www.openlinksw.com/virtrdf-data-formats#' || 'sql-' || replace (coltype, ' ', '') || '-fixedlang-' || o_lang ;
  12200. src_lname := 'sql-' || replace (coltype, ' ', '') || '-fixedlang-x-any' || case when is_nullable then '-nullable' else '' end;
  12201. res_lname := 'sql-' || replace (coltype, ' ', '') || '-fixedlang-' || o_lang || case when is_nullable then '-nullable' else '' end ;
  12202. src_fmtid := 'http://www.openlinksw.com/virtrdf-data-formats#' || src_lname;
  12203. res_fmtid := 'http://www.openlinksw.com/virtrdf-data-formats#' || res_lname;
  12204. superformatsid := res_fmtid || '--SuperFormats';
  12205. if (exists (sparql define input:storage ""
  12206. prefix rdfdf: <http://www.openlinksw.com/virtrdf-data-formats#>
  12207. prefix virtrdf: <http://www.openlinksw.com/schemas/virtrdf#>
  12208. ask where { graph virtrdf: { `iri(?:res_fmtid)` a virtrdf:QuadMapFormat } } ) )
  12209. {
  12210. -- dbg_obj_princ ('DB.DBA.RDF_QM_DEFINE_LITERAL_CLASS_WITH_FIXED_LANG (', coltype, o_lang, is_nullable, ') exists');
  12211. return res_fmtid;
  12212. }
  12213. if (not exists (sparql define input:storage ""
  12214. prefix rdfdf: <http://www.openlinksw.com/virtrdf-data-formats#>
  12215. prefix virtrdf: <http://www.openlinksw.com/schemas/virtrdf#>
  12216. ask where { graph virtrdf: { `iri(?:src_fmtid)` a virtrdf:QuadMapFormat } } ) )
  12217. {
  12218. -- dbg_obj_princ ('DB.DBA.RDF_QM_DEFINE_LITERAL_CLASS_WITH_FIXED_LANG (', coltype, o_lang, is_nullable, '): ', src_fmtid, 'does not exist');
  12219. signal ('22023', 'Unable to find appropriate quad map format to make its analog for a fixed language');
  12220. }
  12221. -- dbg_obj_princ ('DB.DBA.RDF_QM_DEFINE_LITERAL_CLASS_WITH_FIXED_LANG (', coltype, o_lang, is_nullable, '): will make ', res_fmtid, ' from ', src_fmtid);
  12222. o_lang_str := WS.WS.STR_SQL_APOS (o_lang);
  12223. sparql define input:storage ""
  12224. prefix rdfdf: <http://www.openlinksw.com/virtrdf-data-formats#>
  12225. prefix virtrdf: <http://www.openlinksw.com/schemas/virtrdf#>
  12226. prefix xsd: <http://www.w3.org/2001/XMLSchema#>
  12227. with virtrdf:
  12228. delete { `iri(?:res_fmtid)` ?p ?o }
  12229. where { `iri(?:res_fmtid)` ?p ?o };
  12230. sparql define input:storage ""
  12231. prefix rdfdf: <http://www.openlinksw.com/virtrdf-data-formats#>
  12232. prefix virtrdf: <http://www.openlinksw.com/schemas/virtrdf#>
  12233. prefix xsd: <http://www.w3.org/2001/XMLSchema#>
  12234. with virtrdf:
  12235. delete { `iri(?:superformatsid)` ?p ?o }
  12236. where { `iri(?:superformatsid)` ?p ?o };
  12237. sparql define input:storage ""
  12238. prefix rdfdf: <http://www.openlinksw.com/virtrdf-data-formats#>
  12239. prefix virtrdf: <http://www.openlinksw.com/schemas/virtrdf#>
  12240. prefix xsd: <http://www.w3.org/2001/XMLSchema#>
  12241. insert in virtrdf:
  12242. {
  12243. `iri(?:res_fmtid)` ?p
  12244. `if (isref (?o) || isnumeric (?o) || datatype(?o) != xsd:string,
  12245. if (isref (?o) && (?o = iri(?:src_baseid)), iri(?:res_baseid), ?o),
  12246. bif:replace (?o, "'x-any'", ?:o_lang_str) ) ` ;
  12247. virtrdf:qmfSuperFormats `iri(?:superformatsid)` .
  12248. `iri(?:superformatsid)`
  12249. rdf:type virtrdf:array-of-QuadMapFormat ;
  12250. rdf:_1 `iri(?:nullablesuperformatid)` .
  12251. }
  12252. from virtrdf:
  12253. where
  12254. {
  12255. `iri(?:src_fmtid)` ?p ?o .
  12256. filter (?p != virtrdf:qmfSuperFormats ) };
  12257. commit work;
  12258. return res_fmtid;
  12259. }
  12260. ;
  12261. --!AWK PUBLIC
  12262. create function DB.DBA.RDF_BAD_CLASS_INV_FUNCTION (inout val any) returns any
  12263. {
  12264. return NULL;
  12265. }
  12266. ;
  12267. --!AWK PUBLIC
  12268. create function DB.DBA.SQLNAME_NOTATION_TO_NAME (in str varchar) returns varchar
  12269. {
  12270. if ('' = str)
  12271. return NULL;
  12272. if (34 = str[0])
  12273. return subseq (str, 1, length (str) - 1);
  12274. return fix_identifier_case (str);
  12275. }
  12276. ;
  12277. --!AWK PUBLIC
  12278. create function DB.DBA.SQLQNAME_NOTATION_TO_QNAME (in str varchar, in expected_part_count integer) returns varchar
  12279. {
  12280. declare part_ctr, dot_pos integer;
  12281. declare name, res varchar;
  12282. res := '';
  12283. part_ctr := 1;
  12284. next_dot:
  12285. dot_pos := strchr (str, '.');
  12286. if (dot_pos is not null)
  12287. {
  12288. if (0 = dot_pos)
  12289. {
  12290. if (2 = part_ctr)
  12291. res := res || USER || '.';
  12292. else
  12293. return NULL;
  12294. }
  12295. else
  12296. {
  12297. name := DB.DBA.SQLNAME_NOTATION_TO_NAME(subseq (str, 0, dot_pos));
  12298. if (name is null)
  12299. return NULL;
  12300. res := res || name || '.';
  12301. }
  12302. str := subseq (str, dot_pos + 1);
  12303. part_ctr := part_ctr + 1;
  12304. goto next_dot;
  12305. }
  12306. if (expected_part_count <> part_ctr)
  12307. return NULL;
  12308. name := DB.DBA.SQLNAME_NOTATION_TO_NAME (str);
  12309. if (name is null)
  12310. return NULL;
  12311. return res || name;
  12312. }
  12313. ;
  12314. create procedure DB.DBA.RDF_QM_CHECK_CLASS_FUNCTION_HEADERS (inout fheaders any, in is_iri_decl integer, in only_one_arg integer, in pdesc varchar, in invdesc varchar, in bij integer, in deref integer)
  12315. {
  12316. declare uriprint any;
  12317. declare uriprintname varchar;
  12318. declare argctr, argcount integer;
  12319. uriprint := fheaders[0];
  12320. uriprintname := uriprint[0];
  12321. argcount := length (uriprint[1]);
  12322. if (only_one_arg and (1 <> length (uriprint[1])))
  12323. signal ('22023', pdesc || ' function "' || uriprintname || '" should have exactly one argument');
  12324. if (1 = length (fheaders))
  12325. {
  12326. if (bij or deref)
  12327. {
  12328. if (0 = argcount)
  12329. signal ('22023',
  12330. sprintf ('%s function "%s" can not be used in a class with OPTION (BIJECTION) or OPTION (DEREF), because it has no arguments.',
  12331. pdesc, uriprintname ) );
  12332. signal ('22023',
  12333. sprintf ('%s function "%s" can not be used in a class with OPTION (BIJECTION) or OPTION (DEREF) without related %d inverse functions',
  12334. pdesc, uriprintname, argcount ) );
  12335. }
  12336. }
  12337. if (is_iri_decl and (uriprint[2] <> 'varchar'))
  12338. signal ('22023', pdesc || ' function "' || uriprintname || '" should return varchar, not ' || uriprint[2]);
  12339. foreach (any arg in uriprint[1]) do
  12340. if (UNAME'in' <> arg[0])
  12341. signal ('22023', 'Only "in" parameters are now supported in argument lists of ' || pdesc || ' functions, not "' || arg[0] || '"');
  12342. if (argcount <> (length (fheaders) - 1))
  12343. {
  12344. if ((1 <> length (fheaders)) or (0 = argcount))
  12345. signal ('22023',
  12346. sprintf ('%s function "%s" has %d arguments but %d inverse functions',
  12347. pdesc, uriprintname, argcount, (length (fheaders) - 1)
  12348. ) );
  12349. declare inv any;
  12350. inv := vector ('DB.DBA.RDF_BAD_CLASS_INV_FUNCTION', vector (vector ('in', 'val', 'any', 0)), 'any', 0);
  12351. fheaders := make_array (1 + argcount, 'any');
  12352. fheaders[0] := uriprint;
  12353. for (argctr := 0; argctr < argcount; argctr := argctr + 1)
  12354. {
  12355. inv[2] := uriprint[1][argctr][2];
  12356. fheaders[argctr+1] := inv;
  12357. }
  12358. }
  12359. else if (1 = argcount)
  12360. {
  12361. declare uriparsename varchar;
  12362. if (uriprintname like '%"')
  12363. uriparsename := subseq (uriprintname, 0, length (uriprintname)-1) || '_INVERSE"';
  12364. else
  12365. uriparsename := uriprintname || '_INVERSE';
  12366. if (fheaders[1][0] <> uriparsename)
  12367. signal ('22023', 'Name of ' || invdesc || ' function should be ' || uriparsename || ', not ' || fheaders[1][0] || ', other variants are not supported by the current version' );
  12368. }
  12369. else
  12370. {
  12371. for (argctr := 0; argctr < argcount; argctr := argctr + 1)
  12372. {
  12373. declare uriparsename varchar;
  12374. if (uriprintname like '%"')
  12375. uriparsename := sprintf ('%s_INV_%d"', subseq (uriprintname, 0, length (uriprintname)-1), argctr+1);
  12376. else
  12377. uriparsename := sprintf ('%s_INV_%d', uriprintname, argctr+1);
  12378. if (fheaders[argctr + 1][0] <> uriparsename)
  12379. signal ('22023', 'Name of inverse function should be ' || uriparsename || ', not ' || fheaders[argctr + 1][0] || ', other variants are not supported by the current version' );
  12380. }
  12381. }
  12382. for (argctr := 0; argctr < argcount; argctr := argctr + 1)
  12383. {
  12384. declare uriparse any;
  12385. uriparse := fheaders [argctr + 1];
  12386. if (1 <> length (uriparse[1]))
  12387. signal ('22023', invdesc || ' function ' || uriparse[0] || ' should have only one argument');
  12388. if (UNAME'in' <> uriparse[1][0][0])
  12389. signal ('22023', 'Only "in" parameters are now supported in argument lists of ' || invdesc || ' functions, not "' || uriparse[1][0][0] || '"');
  12390. if ((uriparse[1][0][2] <> uriprint[2]) and (uriparse[1][0][2] <> 'any'))
  12391. signal ('22023', invdesc || ' function "' || uriparse[0] || '" should have argument of type ' || uriprint[2] || ', not ' || uriparse[1][0][2]);
  12392. if ((uriparse[2] <> uriprint[1][argctr][2]) and (uriprint[1][argctr][2] <> 'any'))
  12393. signal ('22023', 'The return value of "' || uriparse[0] || '" and the argument #' || cast (argctr+1 as varchar) || ' of "' || uriprintname || '" should be of the same data type');
  12394. if (coalesce (uriparse[1][0][3], 0))
  12395. signal ('22023', invdesc || ' function ' || uriparse[0] || ' should have nullable argument');
  12396. }
  12397. }
  12398. ;
  12399. create function DB.DBA.RDF_QM_DEFINE_SUBCLASS (in subclassiri varchar, in superclassiri varchar) returns any
  12400. {
  12401. DB.DBA.RDF_QM_ASSERT_JSO_TYPE (subclassiri, 'http://www.openlinksw.com/schemas/virtrdf#QuadMapFormat');
  12402. DB.DBA.RDF_QM_ASSERT_JSO_TYPE (superclassiri, 'http://www.openlinksw.com/schemas/virtrdf#QuadMapFormat');
  12403. sparql define input:storage ""
  12404. prefix rdfdf: <http://www.openlinksw.com/virtrdf-data-formats#>
  12405. insert in graph <http://www.openlinksw.com/schemas/virtrdf#> {
  12406. `iri(?:subclassiri)` virtrdf:isSubclassOf `iri(?:superclassiri)` };
  12407. commit work;
  12408. return vector (vector ('00000', 'IRI class <' || subclassiri || '> is now known as a subclass of <' || superclassiri || '>'));
  12409. }
  12410. ;
  12411. create function DB.DBA.RDF_QM_DROP_CLASS (in classiri varchar, in silent integer := 0) returns any
  12412. {
  12413. declare graphiri varchar;
  12414. graphiri := DB.DBA.JSO_SYS_GRAPH ();
  12415. if (silent and not exists ((sparql define input:storage ""
  12416. prefix rdfdf: <http://www.openlinksw.com/virtrdf-data-formats#>
  12417. select (1) where {
  12418. graph ?:graphiri {
  12419. `iri(?:classiri)` a ?t } } ) ) )
  12420. return vector (vector ('00000', 'Class <' || classiri || '> does not exist, the DROP statement is ignored due to SILENT option'));
  12421. if (DB.DBA.RDF_QM_ASSERT_JSO_TYPE (classiri, 'http://www.openlinksw.com/schemas/virtrdf#QuadMapFormat', 1))
  12422. {
  12423. declare side_s IRI_ID;
  12424. side_s := DB.DBA.RDF_QM_GC_SUBTREE (classiri, 2);
  12425. if (side_s is not null)
  12426. signal ('22023', 'Can not drop class <' || classiri || '> because it is used by other quad map objects, e.g., <' || id_to_iri_nosignal (side_s) || '>');
  12427. }
  12428. commit work;
  12429. return vector (vector ('00000', 'Previous definition of class <' || classiri || '> has been dropped'));
  12430. }
  12431. ;
  12432. create function DB.DBA.RDF_QM_DROP_QUAD_STORAGE (in storage varchar, in silent integer := 0) returns any
  12433. {
  12434. declare graphiri varchar;
  12435. graphiri := DB.DBA.JSO_SYS_GRAPH ();
  12436. if (silent and not exists ((sparql define input:storage ""
  12437. prefix rdfdf: <http://www.openlinksw.com/virtrdf-data-formats#>
  12438. select (1) where {
  12439. graph ?:graphiri {
  12440. `iri(?:storage)` a ?t } } ) ) )
  12441. return vector (vector ('00000', 'Quad storage <' || storage || '> does not exist, the DROP statement is ignored due to SILENT option'));
  12442. DB.DBA.RDF_QM_ASSERT_STORAGE_FLAG (storage, 0);
  12443. DB.DBA.RDF_QM_GC_SUBTREE (storage);
  12444. sparql define input:storage ""
  12445. prefix rdfdf: <http://www.openlinksw.com/virtrdf-data-formats#>
  12446. delete from graph <http://www.openlinksw.com/schemas/virtrdf#> {
  12447. `iri(?:storage)` ?p ?o
  12448. }
  12449. where { graph ?:graphiri { `iri(?:storage)` ?p ?o } };
  12450. commit work;
  12451. return vector (vector ('00000', 'Quad storage <' || storage || '> is removed from the quad mapping schema'));
  12452. }
  12453. ;
  12454. create function DB.DBA.RDF_QM_DEFINE_QUAD_STORAGE (in storage varchar) returns any
  12455. {
  12456. declare graphiri, qsusermaps varchar;
  12457. graphiri := DB.DBA.JSO_SYS_GRAPH ();
  12458. DB.DBA.RDF_QM_ASSERT_JSO_TYPE (storage, NULL);
  12459. qsusermaps := storage || '--UserMaps';
  12460. sparql define input:storage ""
  12461. prefix rdfdf: <http://www.openlinksw.com/virtrdf-data-formats#>
  12462. delete from graph <http://www.openlinksw.com/schemas/virtrdf#> { ?s ?p ?o }
  12463. from <http://www.openlinksw.com/schemas/virtrdf#>
  12464. where { ?s ?p ?o . filter (?s = iri(?:storage)) };
  12465. sparql define input:storage ""
  12466. prefix rdfdf: <http://www.openlinksw.com/virtrdf-data-formats#>
  12467. delete from graph <http://www.openlinksw.com/schemas/virtrdf#> { ?s ?p ?o }
  12468. from <http://www.openlinksw.com/schemas/virtrdf#>
  12469. where { ?s ?p ?o . filter (?s = iri(?:qsusermaps)) };
  12470. sparql define input:storage ""
  12471. prefix rdfdf: <http://www.openlinksw.com/virtrdf-data-formats#>
  12472. insert in graph <http://www.openlinksw.com/schemas/virtrdf#> {
  12473. `iri(?:storage)`
  12474. rdf:type virtrdf:QuadStorage ;
  12475. virtrdf:qsUserMaps `iri(?:qsusermaps)` .
  12476. `iri(?:qsusermaps)`
  12477. rdf:type virtrdf:array-of-QuadMap };
  12478. commit work;
  12479. return vector (vector ('00000', 'A new empty quad storage <' || storage || '> is added to the quad mapping schema'));
  12480. }
  12481. ;
  12482. create function DB.DBA.RDF_QM_BEGIN_ALTER_QUAD_STORAGE (in storage varchar) returns any
  12483. {
  12484. declare graphiri varchar;
  12485. graphiri := DB.DBA.JSO_SYS_GRAPH ();
  12486. DB.DBA.RDF_QM_ASSERT_STORAGE_FLAG (storage, 0);
  12487. sparql define input:storage ""
  12488. prefix rdfdf: <http://www.openlinksw.com/virtrdf-data-formats#>
  12489. insert in graph <http://www.openlinksw.com/schemas/virtrdf#> {
  12490. `iri(?:storage)` virtrdf:qsAlterInProgress `bif:now NIL` };
  12491. commit work;
  12492. return vector (vector ('00000', 'Quad storage <' || storage || '> is flagged as being edited'));
  12493. }
  12494. ;
  12495. create function DB.DBA.RDF_QM_END_ALTER_QUAD_STORAGE (in storage varchar) returns any
  12496. {
  12497. declare graphiri varchar;
  12498. graphiri := DB.DBA.JSO_SYS_GRAPH ();
  12499. DB.DBA.RDF_QM_ASSERT_JSO_TYPE (storage, 'http://www.openlinksw.com/schemas/virtrdf#QuadStorage');
  12500. sparql define input:storage ""
  12501. prefix rdfdf: <http://www.openlinksw.com/virtrdf-data-formats#>
  12502. delete from graph <http://www.openlinksw.com/schemas/virtrdf#> {
  12503. `iri(?:storage)` virtrdf:qsAlterInProgress ?dtstart }
  12504. where { graph ?:graphiri {
  12505. `iri(?:storage)` virtrdf:qsAlterInProgress ?dtstart } };
  12506. commit work;
  12507. return vector (vector ('00000', 'Quad storage <' || storage || '> is unflagged and can be edited by other transactions'));
  12508. }
  12509. ;
  12510. create function DB.DBA.RDF_QM_STORE_ATABLES (in qmvid varchar, in atablesid varchar, inout atables any)
  12511. {
  12512. declare atablectr, atablecount integer;
  12513. atablecount := length (atables);
  12514. for (atablectr := 0; atablectr < atablecount; atablectr := atablectr + 1)
  12515. {
  12516. declare pair any;
  12517. declare qtable, alias, inner_id varchar;
  12518. pair := atables [atablectr];
  12519. alias := pair[0];
  12520. qtable := pair[1];
  12521. if (starts_with (qtable, '/*[sqlquery[*/'))
  12522. {
  12523. qtable := '(' || qtable || ')';
  12524. inner_id := qmvid || '-atable-' || alias || '-sql-query';
  12525. }
  12526. else
  12527. inner_id := qmvid || '-atable-' || alias || '-' || qtable;
  12528. sparql define input:storage ""
  12529. prefix rdfdf: <http://www.openlinksw.com/virtrdf-data-formats#>
  12530. delete from graph <http://www.openlinksw.com/schemas/virtrdf#> { ?s ?p ?o }
  12531. from <http://www.openlinksw.com/schemas/virtrdf#>
  12532. where { ?s ?p ?o . filter (?s = iri(?:inner_id)) };
  12533. sparql define input:storage ""
  12534. prefix rdfdf: <http://www.openlinksw.com/virtrdf-data-formats#>
  12535. insert in graph <http://www.openlinksw.com/schemas/virtrdf#> {
  12536. `iri(?:atablesid)`
  12537. `iri (bif:sprintf ("%s%d", str (rdf:_), ?:atablectr+1))` `iri(?:inner_id)` .
  12538. `iri(?:inner_id)`
  12539. rdf:type virtrdf:QuadMapATable ;
  12540. virtrdf:qmvaAlias ?:alias ;
  12541. virtrdf:qmvaTableName ?:qtable };
  12542. }
  12543. }
  12544. ;
  12545. create function DB.DBA.RDF_QM_FT_USAGE (in ft_type varchar, in ft_alias varchar, in ft_aliased_col any, in sqlcols any, in conds any, in options any := null)
  12546. {
  12547. declare ft_tbl, ft_col, ftid, ftcondsid varchar;
  12548. declare condctr, condcount, ft_isxml integer;
  12549. ft_tbl := ft_aliased_col[0];
  12550. ft_col := ft_aliased_col[2];
  12551. ft_isxml := case (isnull (ft_type)) when 0 then 1 else null end;
  12552. if (ft_alias <> ft_aliased_col[1])
  12553. signal ('22023', sprintf ('"TEXT LITERAL %I.%I" should be at the end of "FROM ... AS %I" declaration', ft_aliased_col[1], ft_aliased_col, ft_alias));
  12554. condcount := length (conds);
  12555. ftid := 'sys:ft-' || md5 (serialize (vector (ft_alias, ft_tbl, ft_col, conds, options)));
  12556. if (condcount > 0)
  12557. ftcondsid := ftid || '-conds';
  12558. else
  12559. ftcondsid := NULL;
  12560. /* Trick to avoid repeating re-declarations */
  12561. if (exists (sparql define input:storage ""
  12562. prefix rdfdf: <http://www.openlinksw.com/virtrdf-data-formats#>
  12563. ask where {
  12564. graph <http://www.openlinksw.com/schemas/virtrdf#> {
  12565. ?:ftid
  12566. rdf:type virtrdf:QuadMapFText ;
  12567. virtrdf:qmvftAlias ?:ft_alias ;
  12568. virtrdf:qmvftTableName ?:ft_tbl ;
  12569. virtrdf:qmvftColumnName ?:ft_col ;
  12570. virtrdf:qmvftConds `iri(?:ftcondsid)` } } ) )
  12571. return ftid;
  12572. if (ftcondsid is not null)
  12573. DB.DBA.RDF_QM_GC_SUBTREE (ftcondsid);
  12574. sparql define input:storage ""
  12575. prefix rdfdf: <http://www.openlinksw.com/virtrdf-data-formats#>
  12576. delete from graph <http://www.openlinksw.com/schemas/virtrdf#> { ?s ?p ?o }
  12577. from <http://www.openlinksw.com/schemas/virtrdf#>
  12578. where { ?s ?p ?o . filter (?s = iri(?:ftid)) };
  12579. sparql define input:storage ""
  12580. prefix rdfdf: <http://www.openlinksw.com/virtrdf-data-formats#>
  12581. delete from graph <http://www.openlinksw.com/schemas/virtrdf#> { ?s ?p ?o }
  12582. from <http://www.openlinksw.com/schemas/virtrdf#>
  12583. where { ?s ?p ?o . filter (?s = iri(?:ftcondsid)) };
  12584. sparql define input:storage ""
  12585. prefix rdfdf: <http://www.openlinksw.com/virtrdf-data-formats#>
  12586. insert in graph <http://www.openlinksw.com/schemas/virtrdf#> {
  12587. `iri(?:ftid)`
  12588. rdf:type virtrdf:QuadMapFText ;
  12589. virtrdf:qmvftAlias ?:ft_alias ;
  12590. virtrdf:qmvftTableName ?:ft_tbl ;
  12591. virtrdf:qmvftColumnName ?:ft_col ;
  12592. virtrdf:qmvftXmlIndex ?:ft_isxml ;
  12593. virtrdf:qmvftConds `iri(?:ftcondsid)` .
  12594. `iri(?:ftcondsid)`
  12595. rdf:type virtrdf:array-of-string };
  12596. for (condctr := 0; condctr < condcount; condctr := condctr + 1)
  12597. {
  12598. declare sqlcond varchar;
  12599. sqlcond := conds [condctr];
  12600. sparql define input:storage ""
  12601. prefix rdfdf: <http://www.openlinksw.com/virtrdf-data-formats#>
  12602. insert in graph <http://www.openlinksw.com/schemas/virtrdf#> {
  12603. `iri(?:ftcondsid)`
  12604. `iri (bif:sprintf ("%s%d", str (rdf:_), ?:condctr+1))` ?:sqlcond };
  12605. }
  12606. return ftid;
  12607. }
  12608. ;
  12609. create function DB.DBA.RDF_QM_CHECK_COLUMNS_FORM_KEY (in sqlcols any) returns integer
  12610. {
  12611. declare alias, tbl varchar;
  12612. declare colctr, colcount integer;
  12613. colcount := length (sqlcols);
  12614. if (0 = colcount)
  12615. return 0;
  12616. tbl := sqlcols[0][0];
  12617. alias := sqlcols[0][1];
  12618. for (colctr := 1; colctr < colcount; colctr := colctr + 1)
  12619. {
  12620. if ((sqlcols[colctr][0] <> tbl) or (sqlcols[colctr][1] <> alias))
  12621. return 0;
  12622. }
  12623. for (select KEY_ID, KEY_N_SIGNIFICANT from DB.DBA.SYS_KEYS where (KEY_TABLE = tbl) and KEY_IS_UNIQUE) do
  12624. {
  12625. declare keycolnames any;
  12626. if (KEY_N_SIGNIFICANT > colcount)
  12627. goto no_match;
  12628. for (select "COLUMN" as COL
  12629. from DB.DBA.SYS_KEY_PARTS join DB.DBA.SYS_COLS on (KP_COL = COL_ID)
  12630. where KP_KEY_ID = KEY_ID and KP_NTH < KEY_N_SIGNIFICANT ) do
  12631. {
  12632. for (colctr := 0; colctr < colcount; colctr := colctr + 1)
  12633. {
  12634. if (sqlcols[colctr][2] = COL)
  12635. goto col_ok;
  12636. }
  12637. goto no_match;
  12638. col_ok: ;
  12639. }
  12640. return 1;
  12641. no_match: ;
  12642. }
  12643. return 0;
  12644. }
  12645. ;
  12646. registry_set ('DB.DBA.RDF_QM_PEDANTIC_GC', '')
  12647. ;
  12648. create function DB.DBA.RDF_QM_DEFINE_MAP_VALUE (in qmv any, in fldname varchar, inout tablename varchar, in o_dt any := null, in o_lang any := null) returns varchar
  12649. {
  12650. /* iqi qmv: vector ( UNAME'http://www.openlinksw.com/schemas/oplsioc#user_iri' ,
  12651. vector ( vector ('alias1', 'DB.DBA.SYS_USERS')),
  12652. vector ( vector ('DB.DBA.SYS_USERS', 'alias1', 'U_ID') ),
  12653. vector ('^{alias1.}^.U+IS_ROLE = 0'),
  12654. NULL
  12655. ) */
  12656. declare atables, sqlcols, conds, items_for_pedantic_gc any;
  12657. declare ftextid varchar;
  12658. declare qry_metas any;
  12659. declare atablectr, atablecount integer;
  12660. declare colctr, colcount, fmtcolcount integer;
  12661. declare condctr, condcount integer;
  12662. declare columnsformkey integer;
  12663. declare fmtid, iriclassid, qmvid, qmvatablesid, qmvcolsid, qmvcondsid varchar;
  12664. -- dbg_obj_princ ('DB.DBA.RDF_QM_DEFINE_MAP_VALUE (', qmv, fldname, tablename, ')');
  12665. fmtid := qmv[0];
  12666. atables := qmv[1];
  12667. sqlcols := qmv[2];
  12668. conds := qmv[3];
  12669. ftextid := qmv[4];
  12670. qry_metas := null;
  12671. atablecount := length (atables);
  12672. colcount := length (sqlcols);
  12673. condcount := length (conds);
  12674. items_for_pedantic_gc := NULL;
  12675. if (fmtid <> UNAME'literal')
  12676. {
  12677. DB.DBA.RDF_QM_ASSERT_JSO_TYPE (fmtid, 'http://www.openlinksw.com/schemas/virtrdf#QuadMapFormat');
  12678. if (o_dt is not null)
  12679. signal ('22023', 'Only default literal class can have DATATYPE clause in the mapping, <' || fmtid || '> can not');
  12680. if (o_lang is not null)
  12681. signal ('22023', 'Only default literal class can have LANG clause in the mapping, <' || fmtid || '> can not');
  12682. fmtcolcount := ((sparql define input:storage ""
  12683. select ?cc from <http://www.openlinksw.com/schemas/virtrdf#>
  12684. where { `iri(?:fmtid)` virtrdf:qmfColumnCount ?cc } ) );
  12685. if (fmtcolcount <> colcount)
  12686. signal ('22023', 'Number of columns of quad map value does not match number of arguments of format <' || fmtid || '>');
  12687. }
  12688. for (colctr := 0; colctr < colcount; colctr := colctr + 1)
  12689. {
  12690. declare sqlcol any;
  12691. declare alias_msg_txt, final_tblname, final_colname varchar;
  12692. sqlcol := sqlcols [colctr];
  12693. final_colname := DB.DBA.SQLNAME_NOTATION_TO_NAME (sqlcol[2]);
  12694. if (sqlcol[1] is not null)
  12695. alias_msg_txt := ' (alias ' || sqlcol[1] || ')';
  12696. else
  12697. alias_msg_txt := ' (without alias)';
  12698. if (starts_with (sqlcol[0], '/*[sqlquery[*/'))
  12699. {
  12700. declare qry varchar;
  12701. declare qry_colcount, qry_colctr integer;
  12702. declare qry_mdata any;
  12703. qry := sqlcol[0];
  12704. if (qry_metas is null)
  12705. qry_metas := dict_new (5);
  12706. qry_mdata := dict_get (qry_metas, qry, null);
  12707. if (qry_mdata is null)
  12708. {
  12709. declare stat, msg varchar;
  12710. declare exec_metas any;
  12711. stat := '00000';
  12712. exec_metadata (sqlcol[0], stat, msg, exec_metas);
  12713. if (stat <> '00000')
  12714. signal ('22023', 'The compilation of SQLQUERY' || alias_msg_txt || ' results in Error ' || stat || ': ' || msg);
  12715. if (exec_metas[1] <> 1)
  12716. signal ('R2RML', 'Dangerous DML in SQLQUERY' || alias_msg_txt);
  12717. exec_metas := exec_metas[0];
  12718. qry_colcount := length (exec_metas);
  12719. qry_mdata := make_array (qry_colcount*2, 'any');
  12720. for (qry_colctr := 0; qry_colctr < qry_colcount; qry_colctr := qry_colctr + 1)
  12721. {
  12722. qry_mdata[qry_colctr*2] := exec_metas[qry_colctr][0];
  12723. qry_mdata[qry_colctr*2+1] := exec_metas[qry_colctr];
  12724. }
  12725. dict_put (qry_metas, qry, qry_mdata);
  12726. -- dbg_obj_princ ('DB.DBA.RDF_QM_DEFINE_MAP_VALUE(): storing metadata ', qry_mdata, ' for ', qry);
  12727. }
  12728. -- dbg_obj_princ ('DB.DBA.RDF_QM_DEFINE_MAP_VALUE(): final_colname = ', final_colname);
  12729. if (get_keyword (final_colname, qry_mdata) is null)
  12730. signal ('22023', 'The result of SQLQUERY' || alias_msg_txt || ' does not contain column ' || sqlcol[2] || ', please check spelling and character case');
  12731. }
  12732. else
  12733. {
  12734. final_tblname := DB.DBA.SQLQNAME_NOTATION_TO_QNAME (sqlcol[0], 3);
  12735. if (not exists (select top 1 1 from DB.DBA.TABLE_COLS where "TABLE" = final_tblname))
  12736. signal ('22023', 'No table ' || sqlcol[0] || alias_msg_txt || ' in database, please check spelling and character case');
  12737. if (not exists (select top 1 1 from DB.DBA.TABLE_COLS where "TABLE" = final_tblname and "COLUMN" = final_colname))
  12738. signal ('22023', 'No column ' || sqlcol[2] || ' in table ' || sqlcol[0] || alias_msg_txt || ' in database, please check spelling and character case');
  12739. }
  12740. if (tablename is null)
  12741. tablename := sqlcol[0];
  12742. else if (tablename <> sqlcol[0])
  12743. tablename := '';
  12744. }
  12745. if (tablename is null)
  12746. tablename := '';
  12747. if (fmtid = UNAME'literal')
  12748. {
  12749. declare sqlcol any;
  12750. declare final_tblname, final_colname varchar;
  12751. declare coldtp, colnullable integer;
  12752. declare coltype varchar;
  12753. sqlcol := sqlcols [0];
  12754. final_colname := DB.DBA.SQLNAME_NOTATION_TO_NAME (sqlcol[2]);
  12755. if (starts_with (sqlcol[0], '/*[sqlquery[*/'))
  12756. {
  12757. declare col_mdata any;
  12758. col_mdata := get_keyword (final_colname, dict_get (qry_metas, sqlcol[0], null));
  12759. coldtp := col_mdata[1];
  12760. colnullable := col_mdata[4];
  12761. }
  12762. else
  12763. {
  12764. final_tblname := DB.DBA.SQLQNAME_NOTATION_TO_QNAME (sqlcol[0], 3);
  12765. select COL_DTP, coalesce (COL_NULLABLE, 1) into coldtp, colnullable
  12766. from DB.DBA.TABLE_COLS where "TABLE" = final_tblname and "COLUMN" = final_colname;
  12767. }
  12768. coltype := case (coldtp)
  12769. when __tag of long varchar then 'longvarchar'
  12770. when __tag of timestamp then 'datetime' -- timestamp
  12771. when __tag of date then 'date'
  12772. when __tag of time then 'time'
  12773. when __tag of long varbinary then 'longvarbinary'
  12774. when __tag of varbinary then 'longvarbinary'
  12775. when 188 then 'integer'
  12776. when __tag of integer then 'integer'
  12777. when __tag of varchar then 'varchar'
  12778. when __tag of real then 'double precision' -- actually single precision float
  12779. when __tag of double precision then 'double precision'
  12780. when 192 then 'varchar' -- actually character
  12781. when __tag of datetime then 'datetime'
  12782. when __tag of numeric then 'numeric'
  12783. when __tag of nvarchar then 'nvarchar'
  12784. when __tag of long nvarchar then 'longnvarchar'
  12785. when __tag of bigint then 'integer'
  12786. else NULL end;
  12787. if (coltype is null)
  12788. signal ('22023', 'The datatype of column "' || sqlcols[0][2] ||
  12789. '" of table "' || sqlcols[0][0] || '" (COL_DTP=' || cast (coldtp as varchar) ||
  12790. ') can not be mapped to an RDF literal in current version of Virtuoso' );
  12791. if (o_lang is not null and not (coltype in ('varchar', 'long varchar', 'nvarchar', 'long nvarchar')))
  12792. signal ('22023', 'The datatype of column "' || sqlcols[0][2] ||
  12793. '" of table "' || sqlcols[0][0] || '" (COL_DTP=' || cast (coldtp as varchar) ||
  12794. ') conflicts with LANG clause, only strings may have language' );
  12795. if (o_dt is not null and not (coltype in ('varchar', 'long varchar', 'nvarchar', 'long nvarchar')))
  12796. signal ('22023', 'Current version of Virtuoso does not support DATATYPE clause for columns other than varchar/nvarchar; the column "' || sqlcols[0][2] ||
  12797. '" of table "' || sqlcols[0][0] || '" has COL_DTP=' || cast (coldtp as varchar) );
  12798. fmtid := 'http://www.openlinksw.com/virtrdf-data-formats#sql-' || replace (coltype, ' ', '');
  12799. if (o_dt is not null)
  12800. {
  12801. if (__tag (o_dt) = __tag of vector)
  12802. {
  12803. if (o_dt[1] <> sqlcols[0][1])
  12804. signal ('22023', 'The alias in DATATYPE clause and the alias in object column should be the same');
  12805. fmtid := fmtid || '-dt';
  12806. sqlcols := vector_concat (sqlcols, vector (o_dt));
  12807. colcount := colcount + 1;
  12808. }
  12809. else
  12810. fmtid := DB.DBA.RDF_QM_DEFINE_LITERAL_CLASS_WITH_FIXED_DT (coltype, o_dt);
  12811. }
  12812. if (o_lang is not null)
  12813. {
  12814. if (__tag (o_lang) = __tag of vector)
  12815. {
  12816. if (o_lang[1] <> sqlcols[0][1])
  12817. signal ('22023', 'The alias in LANG clause and the alias in object column should be the same');
  12818. fmtid := fmtid || '-lang';
  12819. sqlcols := vector_concat (sqlcols, vector (o_lang));
  12820. colcount := colcount + 1;
  12821. }
  12822. else
  12823. fmtid := DB.DBA.RDF_QM_DEFINE_LITERAL_CLASS_WITH_FIXED_LANG (coltype, o_lang);
  12824. }
  12825. if (colnullable)
  12826. fmtid := fmtid || '-nullable';
  12827. iriclassid := null;
  12828. }
  12829. else
  12830. {
  12831. if (exists (sparql define input:storage ""
  12832. ask where {
  12833. graph <http://www.openlinksw.com/schemas/virtrdf#> { `iri (?:fmtid)` virtrdf:qmfValRange-rvrRestrictions virtrdf:SPART_VARR_IS_REF } } ) )
  12834. iriclassid := fmtid;
  12835. else
  12836. iriclassid := null;
  12837. }
  12838. qmvid := 'sys:qmv-' || md5 (serialize (vector (fmtid, sqlcols)));
  12839. qmvatablesid := qmvid || '-atables';
  12840. qmvcolsid := qmvid || '-cols';
  12841. qmvcondsid := qmvid || '-conds';
  12842. /* Trick to avoid repeating re-declarations */
  12843. if (exists (sparql define input:storage ""
  12844. prefix rdfdf: <http://www.openlinksw.com/virtrdf-data-formats#>
  12845. ask where {
  12846. graph <http://www.openlinksw.com/schemas/virtrdf#> {
  12847. ?:qmvid
  12848. rdf:type virtrdf:QuadMapValue ;
  12849. virtrdf:qmvATables `iri(?:qmvatablesid)` ;
  12850. virtrdf:qmvColumns `iri(?:qmvcolsid)` ;
  12851. virtrdf:qmvConds `iri(?:qmvcondsid)` ;
  12852. virtrdf:qmvFormat `iri(?:fmtid)` . } } ) )
  12853. return qmvid;
  12854. /* Create everything if qmv has not been found */
  12855. if (registry_get ('DB.DBA.RDF_QM_PEDANTIC_GC') <> '')
  12856. {
  12857. vectorbld_init (items_for_pedantic_gc);
  12858. for (sparql define input:storage ""
  12859. prefix rdfdf: <http://www.openlinksw.com/virtrdf-data-formats#>
  12860. select ?atable where { graph <http://www.openlinksw.com/schemas/virtrdf#> {
  12861. `iri(?:qmvatablesid)` ?p ?atable . filter (?p != rdf:type) } } ) do {
  12862. vectorbld_acc (items_for_pedantic_gc, "atable");
  12863. }
  12864. for (sparql define input:storage ""
  12865. prefix rdfdf: <http://www.openlinksw.com/virtrdf-data-formats#>
  12866. select ?col where { graph <http://www.openlinksw.com/schemas/virtrdf#> {
  12867. `iri(?:qmvcolsid)` ?p ?col . filter (?p != rdf:type) } } ) do {
  12868. vectorbld_acc (items_for_pedantic_gc, "col");
  12869. }
  12870. vectorbld_final (items_for_pedantic_gc);
  12871. }
  12872. sparql define input:storage ""
  12873. prefix rdfdf: <http://www.openlinksw.com/virtrdf-data-formats#>
  12874. delete from graph <http://www.openlinksw.com/schemas/virtrdf#> {
  12875. `iri(?:qmvid)` ?p ?o . }
  12876. where { graph <http://www.openlinksw.com/schemas/virtrdf#> {
  12877. `iri(?:qmvid)` ?p ?o .
  12878. } };
  12879. sparql define input:storage ""
  12880. prefix rdfdf: <http://www.openlinksw.com/virtrdf-data-formats#>
  12881. delete from graph <http://www.openlinksw.com/schemas/virtrdf#> {
  12882. `iri(?:qmvatablesid)` ?p ?o }
  12883. where { graph <http://www.openlinksw.com/schemas/virtrdf#> {
  12884. `iri(?:qmvatablesid)` ?p ?o .
  12885. } };
  12886. sparql define input:storage ""
  12887. prefix rdfdf: <http://www.openlinksw.com/virtrdf-data-formats#>
  12888. delete from graph <http://www.openlinksw.com/schemas/virtrdf#> {
  12889. `iri(?:qmvcolsid)` ?p ?o }
  12890. where { graph <http://www.openlinksw.com/schemas/virtrdf#> {
  12891. `iri(?:qmvcolsid)` ?p ?o .
  12892. } };
  12893. sparql define input:storage ""
  12894. prefix rdfdf: <http://www.openlinksw.com/virtrdf-data-formats#>
  12895. delete from graph <http://www.openlinksw.com/schemas/virtrdf#> {
  12896. `iri(?:qmvcondsid)` ?p ?o }
  12897. where { graph <http://www.openlinksw.com/schemas/virtrdf#> {
  12898. `iri(?:qmvcondsid)` ?p ?o .
  12899. } };
  12900. if (items_for_pedantic_gc is not null)
  12901. {
  12902. foreach (any i in items_for_pedantic_gc) do
  12903. {
  12904. DB.DBA.RDF_QM_GC_SUBTREE (i);
  12905. }
  12906. }
  12907. if (0 = atablecount)
  12908. qmvatablesid := NULL;
  12909. if (0 = condcount)
  12910. qmvcondsid := NULL;
  12911. columnsformkey := DB.DBA.RDF_QM_CHECK_COLUMNS_FORM_KEY (sqlcols);
  12912. sparql define input:storage ""
  12913. prefix rdfdf: <http://www.openlinksw.com/virtrdf-data-formats#>
  12914. insert in graph <http://www.openlinksw.com/schemas/virtrdf#> {
  12915. `iri(?:qmvid)`
  12916. rdf:type virtrdf:QuadMapValue ;
  12917. virtrdf:qmvTableName ?:tablename ;
  12918. virtrdf:qmvATables `iri(?:qmvatablesid)` ;
  12919. virtrdf:qmvColumns `iri(?:qmvcolsid)` ;
  12920. virtrdf:qmvConds `iri(?:qmvcondsid)` ;
  12921. virtrdf:qmvFormat `iri(?:fmtid)` ;
  12922. virtrdf:qmvFText `iri(?:ftextid)` ;
  12923. virtrdf:qmvIriClass `iri(?:iriclassid)` ;
  12924. virtrdf:qmvColumnsFormKey ?:columnsformkey .
  12925. `iri(?:qmvatablesid)`
  12926. rdf:type virtrdf:array-of-QuadMapATable .
  12927. `iri(?:qmvcolsid)`
  12928. rdf:type virtrdf:array-of-QuadMapColumn .
  12929. `iri(?:qmvcondsid)`
  12930. rdf:type virtrdf:array-of-string };
  12931. DB.DBA.RDF_QM_STORE_ATABLES (qmvid, qmvatablesid, atables);
  12932. for (colctr := 0; colctr < colcount; colctr := colctr + 1)
  12933. {
  12934. declare sqlcol any;
  12935. declare qtable, alias, colname, inner_id varchar;
  12936. sqlcol := sqlcols [colctr];
  12937. alias := sqlcol[1];
  12938. colname := sqlcol[2];
  12939. inner_id := qmvid || '-col-' || alias || '-' || colname;
  12940. sparql define input:storage ""
  12941. prefix rdfdf: <http://www.openlinksw.com/virtrdf-data-formats#>
  12942. delete from graph <http://www.openlinksw.com/schemas/virtrdf#> { ?s ?p ?o }
  12943. from <http://www.openlinksw.com/schemas/virtrdf#>
  12944. where { ?s ?p ?o . filter (?s = iri(?:inner_id)) };
  12945. sparql define input:storage ""
  12946. prefix rdfdf: <http://www.openlinksw.com/virtrdf-data-formats#>
  12947. insert in graph <http://www.openlinksw.com/schemas/virtrdf#> {
  12948. `iri(?:qmvcolsid)`
  12949. `iri (bif:sprintf ("%s%d", str (rdf:_), ?:colctr+1))` `iri(?:inner_id)` .
  12950. `iri(?:inner_id)`
  12951. rdf:type virtrdf:QuadMapColumn ;
  12952. virtrdf:qmvcAlias ?:alias ;
  12953. virtrdf:qmvcColumnName ?:colname };
  12954. }
  12955. for (condctr := 0; condctr < condcount; condctr := condctr + 1)
  12956. {
  12957. declare sqlcond varchar;
  12958. sqlcond := conds [condctr];
  12959. sparql define input:storage ""
  12960. prefix rdfdf: <http://www.openlinksw.com/virtrdf-data-formats#>
  12961. insert in graph <http://www.openlinksw.com/schemas/virtrdf#> {
  12962. `iri(?:qmvcondsid)`
  12963. `iri (bif:sprintf ("%s%d", str (rdf:_), ?:condctr+1))` ?:sqlcond };
  12964. }
  12965. return qmvid;
  12966. }
  12967. ;
  12968. create procedure DB.DBA.RDF_QM_NORMALIZE_QMV (
  12969. inout qmv any, inout qmvfix any, inout qmvid any,
  12970. in can_be_literal integer, in fldname varchar, inout tablename varchar, in o_dt any := null, in o_lang any := null )
  12971. {
  12972. -- dbg_obj_princ ('DB.DBA.RDF_QM_NORMALIZE_QMV (', qmv, ' ..., ..., ', can_be_literal, fldname, ')');
  12973. qmvid := qmvfix := NULL;
  12974. if ((__tag of vector = __tag (qmv)) and (5 = length (qmv)))
  12975. qmvid := DB.DBA.RDF_QM_DEFINE_MAP_VALUE (qmv, fldname, tablename, o_dt, o_lang);
  12976. else if (217 = __tag (qmv))
  12977. qmvfix := iri_to_id (qmv);
  12978. else if (qmv is not null and not can_be_literal)
  12979. signal ('22023', sprintf ('Quad map declaration can not specify a literal (non-IRI) constant for its %s (tag %d, length %d)',
  12980. fldname, __tag (qmv), length (qmv) ) );
  12981. else if (__tag of vector = __tag (qmv))
  12982. signal ('22023', sprintf ('Quad map declaration contains constant %s of unsupported type (tag %d, length %d)',
  12983. fldname, __tag (qmv), length (qmv) ) );
  12984. else
  12985. qmvfix := qmv;
  12986. -- dbg_obj_princ ('DB.DBA.RDF_QM_NORMALIZE_QMV has found ', fldname, tablename);
  12987. }
  12988. ;
  12989. create function DB.DBA.RDF_QM_DEFINE_MAPPING (in storage varchar,
  12990. in qmrawid varchar, in qmid varchar, in qmparentid varchar,
  12991. in qmv_g any, in qmv_s any, in qmv_p any, in qmv_o any, in o_dt any, in o_lang any,
  12992. in is_real integer, in atables any, in conds any, in opts any ) returns any
  12993. {
  12994. declare old_actual_type varchar;
  12995. declare tablename, qmvid_g, qmvid_s, qmvid_p, qmvid_o varchar;
  12996. declare qmvfix_g, qmvfix_s, qmvfix_p, qmvfix_o, qmvfix_o_typed, qmvfix_o_dt any;
  12997. declare qm_exclusive, qm_soft_exclusive, qm_empty, qm_is_default, qmusersubmapsid, atablesid, qmcondsid varchar;
  12998. declare qm_order, atablectr, atablecount, condctr, condcount integer;
  12999. -- dbg_obj_princ ('DB.DBA.RDF_QM_DEFINE_MAPPING (', storage, qmrawid, qmid, qmparentid, qmv_g, qmv_s, qmv_p, qmv_o, is_real, atables, conds, opts, ')');
  13000. DB.DBA.RDF_QM_ASSERT_STORAGE_FLAG (storage, 1);
  13001. -- DB.DBA.RDF_QM_ASSERT_JSO_TYPE (qmid, NULL);
  13002. old_actual_type := coalesce ((sparql define input:storage ""
  13003. prefix virtrdf: <http://www.openlinksw.com/schemas/virtrdf#>
  13004. select ?t where {
  13005. graph <http://www.openlinksw.com/schemas/virtrdf#> {
  13006. `iri(?:qmid)` rdf:type ?t } } ));
  13007. if (old_actual_type is not null)
  13008. {
  13009. declare old_lstiri, old_side_use varchar;
  13010. if (old_actual_type <> 'http://www.openlinksw.com/schemas/virtrdf#QuadMap')
  13011. signal ('22023', 'The RDF QM schema object <' || qmid || '> already exists, type <' || old_actual_type || '>');
  13012. old_lstiri := (sparql define input:storage ""
  13013. select ?lst where { graph <http://www.openlinksw.com/schemas/virtrdf#> {
  13014. `iri(?:storage)` virtrdf:qsUserMaps ?lst } } );
  13015. old_side_use := coalesce ((sparql define input:storage ""
  13016. select ?s where {
  13017. graph <http://www.openlinksw.com/schemas/virtrdf#> {
  13018. ?s ?p `iri(?:qmid)` filter ((?s != iri(?:storage)) && (?s != iri(?:old_lstiri))) } } ) );
  13019. if (old_side_use is not null)
  13020. signal ('22023', 'Can not re-create the RDF Quad Mapping <' || qmid || '> because it is referenced by <' || old_side_use || '>');
  13021. DB.DBA.RDF_QM_DELETE_MAPPING_FROM_STORAGE (storage, NULL, qmid);
  13022. DB.DBA.RDF_QM_GC_SUBTREE (qmid);
  13023. }
  13024. if (qmparentid is not null)
  13025. DB.DBA.RDF_QM_ASSERT_JSO_TYPE (qmparentid, 'http://www.openlinksw.com/schemas/virtrdf#QuadMap');
  13026. DB.DBA.RDF_QM_ASSERT_STORAGE_CONTAINS_MAPPING (storage, qmid, 0);
  13027. tablename := NULL;
  13028. DB.DBA.RDF_QM_NORMALIZE_QMV (qmv_g, qmvfix_g, qmvid_g, 0, 'graph', tablename);
  13029. DB.DBA.RDF_QM_NORMALIZE_QMV (qmv_s, qmvfix_s, qmvid_s, 0, 'subject', tablename);
  13030. DB.DBA.RDF_QM_NORMALIZE_QMV (qmv_p, qmvfix_p, qmvid_p, 0, 'predicate', tablename);
  13031. DB.DBA.RDF_QM_NORMALIZE_QMV (qmv_o, qmvfix_o, qmvid_o, 1, 'object', tablename, o_dt, o_lang);
  13032. if (get_keyword_ucase ('EXCLUSIVE', opts))
  13033. qm_exclusive := 'http://www.openlinksw.com/schemas/virtrdf#SPART_QM_EXCLUSIVE';
  13034. else
  13035. qm_exclusive := NULL;
  13036. if (get_keyword_ucase ('OK_FOR_ANY_QUAD', opts))
  13037. qm_is_default := 'http://www.openlinksw.com/schemas/virtrdf#SPART_QM_OK_FOR_ANY_QUAD';
  13038. else
  13039. qm_is_default := NULL;
  13040. if (get_keyword_ucase ('SOFT_EXCLUSIVE', opts))
  13041. qm_soft_exclusive := 'http://www.openlinksw.com/schemas/virtrdf#SPART_QM_SOFT_EXCLUSIVE';
  13042. else
  13043. qm_soft_exclusive := NULL;
  13044. if (not is_real)
  13045. {
  13046. qm_empty := 'http://www.openlinksw.com/schemas/virtrdf#SPART_QM_EMPTY';
  13047. }
  13048. else
  13049. {
  13050. qm_empty := NULL;
  13051. if (tablename is null)
  13052. {
  13053. tablename := 'DB.DBA.SYS_IDONLY_ONE';
  13054. if (0 < length (conds))
  13055. signal ('22023', 'Quad Mapping <' || qmid || '> has four constants and no one quad map value; it does not access tables so it can not have WHERE conditions');
  13056. }
  13057. }
  13058. if ('' = tablename)
  13059. tablename := NULL;
  13060. qm_order := get_keyword_ucase ('ORDER', opts);
  13061. if (not is_real)
  13062. {
  13063. qmusersubmapsid := qmid || '--UserSubMaps';
  13064. atablesid := NULL;
  13065. qmcondsid := NULL;
  13066. }
  13067. else
  13068. {
  13069. qmusersubmapsid := NULL;
  13070. atablesid := qmid || '--ATables';
  13071. qmcondsid := qmid || '--Conds';
  13072. }
  13073. if (qm_is_default is not null)
  13074. {
  13075. if (qm_order is not null)
  13076. signal ('22023', 'ORDER option is not applicable to default quad map');
  13077. if (qmparentid is not null)
  13078. signal ('22023', 'A default quad map can not be a sub-map of other quad map');
  13079. }
  13080. sparql define input:storage ""
  13081. prefix rdfdf: <http://www.openlinksw.com/virtrdf-data-formats#>
  13082. delete from graph <http://www.openlinksw.com/schemas/virtrdf#> {
  13083. `iri(?:atablesid)` ?p ?o }
  13084. where { graph <http://www.openlinksw.com/schemas/virtrdf#> {
  13085. `iri(?:atablesid)` ?p ?o .
  13086. } };
  13087. sparql define input:storage ""
  13088. prefix rdfdf: <http://www.openlinksw.com/virtrdf-data-formats#>
  13089. delete from graph <http://www.openlinksw.com/schemas/virtrdf#> {
  13090. `iri(?:qmcondsid)` ?p ?o }
  13091. where { graph <http://www.openlinksw.com/schemas/virtrdf#> {
  13092. `iri(?:qmcondsid)` ?p ?o .
  13093. } };
  13094. atablecount := length (atables);
  13095. condcount := length (conds);
  13096. if (0 = atablecount)
  13097. atablesid := NULL;
  13098. if (0 = condcount)
  13099. qmcondsid := NULL;
  13100. sparql define input:storage ""
  13101. prefix rdfdf: <http://www.openlinksw.com/virtrdf-data-formats#>
  13102. delete from graph <http://www.openlinksw.com/schemas/virtrdf#> { ?s ?p ?o }
  13103. from <http://www.openlinksw.com/schemas/virtrdf#>
  13104. where { ?s ?p ?o . filter (?s = iri(?:qmid)) };
  13105. sparql define input:storage ""
  13106. prefix rdfdf: <http://www.openlinksw.com/virtrdf-data-formats#>
  13107. delete from graph <http://www.openlinksw.com/schemas/virtrdf#> { ?s ?p ?o }
  13108. from <http://www.openlinksw.com/schemas/virtrdf#>
  13109. where { ?s ?p ?o . filter (?s = iri(?:atablesid)) };
  13110. sparql define input:storage ""
  13111. prefix rdfdf: <http://www.openlinksw.com/virtrdf-data-formats#>
  13112. delete from graph <http://www.openlinksw.com/schemas/virtrdf#> { ?s ?p ?o }
  13113. from <http://www.openlinksw.com/schemas/virtrdf#>
  13114. where { ?s ?p ?o . filter (?s = iri(?:qmcondsid)) };
  13115. sparql define input:storage ""
  13116. prefix rdfdf: <http://www.openlinksw.com/virtrdf-data-formats#>
  13117. delete from graph <http://www.openlinksw.com/schemas/virtrdf#> { ?s ?p ?o }
  13118. from <http://www.openlinksw.com/schemas/virtrdf#>
  13119. where { ?s ?p ?o . filter (?s = iri(?:qmusersubmapsid)) };
  13120. -- This did not work for some reason:
  13121. -- `iri(?:qmid)`
  13122. -- virtrdf:qmObjectRange-rvrRestrictions
  13123. -- `if (((bif:isnotnull(datatype(?:qmvfix_o)) && (datatype(?:qmvfix_o) != xsd:string)) || bound(?:o_dt)), virtrdf:SPART_VARR_TYPED, ?:NULL)` ;
  13124. -- virtrdf:qmObjectRange-rvrDatatype
  13125. -- `if (bound (?:o_dt), ?:o_dt, if ((bif:isnotnull(datatype(?:qmvfix_o)) && (datatype(?:qmvfix_o) != xsd:string)), datatype (?:qmvfix_o), ?:NULL))` ;
  13126. -- ... so it's replaced with SQL
  13127. qmvfix_o_typed := 0;
  13128. if (o_dt is not null)
  13129. {
  13130. qmvfix_o_typed := 1;
  13131. qmvfix_o_dt := o_dt;
  13132. }
  13133. else if (isstring (qmvfix_o) || iswidestring (qmvfix_o))
  13134. {
  13135. qmvfix_o_typed := 0;
  13136. qmvfix_o_dt := NULL;
  13137. }
  13138. else
  13139. {
  13140. qmvfix_o_typed := 1;
  13141. qmvfix_o_dt := __xsd_type (qmvfix_o);
  13142. }
  13143. sparql define input:storage ""
  13144. prefix rdfdf: <http://www.openlinksw.com/virtrdf-data-formats#>
  13145. insert in graph <http://www.openlinksw.com/schemas/virtrdf#> {
  13146. `iri(?:qmid)`
  13147. rdf:type virtrdf:QuadMap ;
  13148. virtrdf:qmGraphRange-rvrFixedValue ?:qmvfix_g ;
  13149. virtrdf:qmGraphRange-rvrRestrictions
  13150. `if (bound(?:qmvfix_g), virtrdf:SPART_VARR_NOT_NULL, ?:NULL)` ,
  13151. `if (bound(?:qmvfix_g), virtrdf:SPART_VARR_FIXED, ?:NULL)` ,
  13152. `if (bound(?:qmvfix_g), virtrdf:SPART_VARR_IS_REF, ?:NULL)` ,
  13153. `if (bound(?:qmvfix_g), virtrdf:SPART_VARR_IS_IRI, ?:NULL)` ;
  13154. virtrdf:qmGraphMap `iri(?:qmvid_g)` ;
  13155. virtrdf:qmSubjectRange-rvrFixedValue ?:qmvfix_s ;
  13156. virtrdf:qmSubjectRange-rvrRestrictions
  13157. `if (bound(?:qmvfix_s), virtrdf:SPART_VARR_NOT_NULL, ?:NULL)` ,
  13158. `if (bound(?:qmvfix_s), virtrdf:SPART_VARR_FIXED, ?:NULL)` ,
  13159. `if (bound(?:qmvfix_s), virtrdf:SPART_VARR_IS_REF, ?:NULL)` ,
  13160. `if (bound(?:qmvfix_s), virtrdf:SPART_VARR_IS_IRI, ?:NULL)` ;
  13161. virtrdf:qmSubjectMap `iri(?:qmvid_s)` ;
  13162. virtrdf:qmPredicateRange-rvrFixedValue ?:qmvfix_p ;
  13163. virtrdf:qmPredicateRange-rvrRestrictions
  13164. `if (bound(?:qmvfix_p), virtrdf:SPART_VARR_NOT_NULL, ?:NULL)` ,
  13165. `if (bound(?:qmvfix_p), virtrdf:SPART_VARR_FIXED, ?:NULL)` ,
  13166. `if (bound(?:qmvfix_p), virtrdf:SPART_VARR_IS_REF, ?:NULL)` ,
  13167. `if (bound(?:qmvfix_p), virtrdf:SPART_VARR_IS_IRI, ?:NULL)` ;
  13168. virtrdf:qmPredicateMap `iri(?:qmvid_p)` ;
  13169. virtrdf:qmObjectRange-rvrFixedValue ?:qmvfix_o ;
  13170. virtrdf:qmObjectRange-rvrRestrictions
  13171. `if (bound(?:qmvfix_o), virtrdf:SPART_VARR_NOT_NULL, ?:NULL)` ,
  13172. `if (bound(?:qmvfix_o), virtrdf:SPART_VARR_FIXED, ?:NULL)` ,
  13173. `if (bound(?:qmvfix_o), if (isREF(?:qmvfix_o), virtrdf:SPART_VARR_IS_REF, virtrdf:SPART_VARR_IS_LIT), ?:NULL)` ,
  13174. `if (isIRI(?:qmvfix_o), virtrdf:SPART_VARR_IS_IRI, ?:NULL)` ,
  13175. `if (?:qmvfix_o_typed, virtrdf:SPART_VARR_TYPED, ?:NULL)` ;
  13176. virtrdf:qmObjectRange-rvrDatatype ?:qmvfix_o_dt ;
  13177. virtrdf:qmObjectRange-rvrLanguage `if (<bif:length> (lang (?:qmvfix_o)), lang (?:qmvfix_o), ?:NULL)` ;
  13178. virtrdf:qmObjectMap `iri(?:qmvid_o)` ;
  13179. virtrdf:qmTableName ?:tablename ;
  13180. virtrdf:qmATables `iri(?:atablesid)` ;
  13181. virtrdf:qmConds `iri(?:qmcondsid)` ;
  13182. virtrdf:qmUserSubMaps `iri(?:qmusersubmapsid)` ;
  13183. virtrdf:qmMatchingFlags `iri(?:qm_exclusive)` ;
  13184. virtrdf:qmMatchingFlags `iri(?:qm_empty)` ;
  13185. virtrdf:qmMatchingFlags `iri(?:qm_is_default)` ;
  13186. virtrdf:qmMatchingFlags `iri(?:qm_soft_exclusive)` ;
  13187. virtrdf:qmPriorityOrder ?:qm_order .
  13188. `iri(?:atablesid)`
  13189. rdf:type virtrdf:array-of-QuadMapATable .
  13190. `iri(?:qmcondsid)`
  13191. rdf:type virtrdf:array-of-string .
  13192. `iri(?:qmusersubmapsid)`
  13193. rdf:type virtrdf:array-of-QuadMap };
  13194. DB.DBA.RDF_QM_STORE_ATABLES (qmid, atablesid, atables);
  13195. for (condctr := 0; condctr < condcount; condctr := condctr + 1)
  13196. {
  13197. declare sqlcond varchar;
  13198. sqlcond := conds [condctr];
  13199. sparql define input:storage ""
  13200. prefix rdfdf: <http://www.openlinksw.com/virtrdf-data-formats#>
  13201. insert in graph <http://www.openlinksw.com/schemas/virtrdf#> {
  13202. `iri(?:qmcondsid)`
  13203. `iri (bif:sprintf ("%s%d", str (rdf:_), ?:condctr+1))` ?:sqlcond };
  13204. }
  13205. DB.DBA.RDF_ADD_qmAliasesKeyrefdByQuad (qmid);
  13206. commit work;
  13207. if (qm_is_default is not null)
  13208. DB.DBA.RDF_QM_SET_DEFAULT_MAPPING (storage, qmid);
  13209. else
  13210. DB.DBA.RDF_QM_ADD_MAPPING_TO_STORAGE (storage, qmparentid, qmid, qm_order);
  13211. commit work;
  13212. return vector (vector ('00000', 'Quad map <' || qmid || '> has been created and added to the <' || storage || '>'));
  13213. }
  13214. ;
  13215. create function DB.DBA.RDF_QM_ATTACH_MAPPING (in storage varchar, in source varchar, in opts any) returns any
  13216. {
  13217. declare graphiri varchar;
  13218. declare qmid, qmgraph varchar;
  13219. declare qm_order, qm_is_default integer;
  13220. graphiri := DB.DBA.JSO_SYS_GRAPH ();
  13221. qmid := get_keyword_ucase ('ID', opts, NULL);
  13222. qmgraph := get_keyword_ucase ('GRAPH', opts, NULL);
  13223. DB.DBA.RDF_QM_ASSERT_STORAGE_FLAG (storage, 1);
  13224. DB.DBA.RDF_QM_ASSERT_STORAGE_FLAG (source, 0);
  13225. if (qmid is null)
  13226. {
  13227. qmid := coalesce ((sparql define input:storage ""
  13228. prefix virtrdf: <http://www.openlinksw.com/schemas/virtrdf#>
  13229. select ?s where {
  13230. graph ?:graphiri {
  13231. ?s rdf:type virtrdf:QuadMap .
  13232. ?s virtrdf:qmGraphRange-rvrFixedValue `iri(?:qmgraph)` .
  13233. ?s virtrdf:qmMatchingFlags virtrdf:SPART_QM_EMPTY .
  13234. } } ));
  13235. if (qmid is null)
  13236. return vector (vector ('00100', 'Quad map for graph <' || qmgraph || '> is not found'));
  13237. }
  13238. qm_order := coalesce ((sparql define input:storage ""
  13239. select ?o where { graph ?:graphiri {
  13240. `iri(?:qmid)` virtrdf:qmPriorityOrder ?o } } ) );
  13241. if (exists (sparql define input:storage ""
  13242. ask where { graph ?:graphiri {
  13243. `iri(?:qmid)` virtrdf:qmMatchingFlags virtrdf:SPART_QM_OK_FOR_ANY_QUAD } } ) )
  13244. qm_is_default := 1;
  13245. else
  13246. qm_is_default := 0;
  13247. DB.DBA.RDF_QM_ASSERT_STORAGE_CONTAINS_MAPPING (storage, qmid, 0);
  13248. DB.DBA.RDF_QM_ASSERT_STORAGE_CONTAINS_MAPPING (source, qmid, 1);
  13249. DB.DBA.RDF_QM_ASSERT_JSO_TYPE (qmid, 'http://www.openlinksw.com/schemas/virtrdf#QuadMap');
  13250. if (qm_is_default)
  13251. DB.DBA.RDF_QM_SET_DEFAULT_MAPPING (storage, qmid);
  13252. else
  13253. DB.DBA.RDF_QM_ADD_MAPPING_TO_STORAGE (storage, NULL, qmid, NULL /* !!!TBD: place real value instead of constant NULL */);
  13254. commit work;
  13255. return vector (vector ('00000', 'Quad map <' || qmid || '> is added to the storage <' || storage || '>'));
  13256. }
  13257. ;
  13258. create procedure DB.DBA.RDF_QM_ADD_MAPPING_TO_STORAGE (in storage varchar, in qmparent varchar, in qmid varchar, in qmorder integer)
  13259. {
  13260. declare graphiri, lstiri varchar;
  13261. declare iris_and_orders any;
  13262. declare ctr, qmid_is_printed integer;
  13263. -- dbg_obj_princ ('DB.DBA.RDF_QM_ADD_MAPPING_TO_STORAGE (', storage, qmparent, qmid, qmorder, ')');
  13264. graphiri := DB.DBA.JSO_SYS_GRAPH ();
  13265. if (qmparent is not null)
  13266. lstiri := (sparql define input:storage ""
  13267. select ?lst where { graph ?:graphiri {
  13268. `iri(?:qmparent)` virtrdf:qmUserSubMaps ?lst } } );
  13269. else
  13270. lstiri := (sparql define input:storage ""
  13271. select ?lst where { graph ?:graphiri {
  13272. `iri(?:storage)` virtrdf:qsUserMaps ?lst } } );
  13273. -- dbg_obj_princ ('DB.DBA.RDF_QM_ADD_MAPPING_TO_STORAGE: storage=', storage, ', qmparent=', qmparent, ', lstiri=', lstiri);
  13274. if (qmorder is null)
  13275. qmorder := 1999;
  13276. iris_and_orders := (
  13277. select DB.DBA.VECTOR_AGG (vector (sub."id", sub."p", sub."ord1"))
  13278. from (
  13279. select sp."id", sp."p", sp."ord1"
  13280. from (
  13281. sparql define input:storage ""
  13282. select ?id ?p
  13283. (bif:coalesce (?ord,
  13284. 1000 + bif:aref (
  13285. bif:sprintf_inverse (
  13286. str(?p),
  13287. bif:concat (str (rdf:_), "%d"),
  13288. 2),
  13289. 0 ) ) ) as ?ord1
  13290. where { graph ?:graphiri {
  13291. `iri(?:lstiri)` ?p ?id .
  13292. filter (! bif:isnull (bif:aref (
  13293. bif:sprintf_inverse (
  13294. str(?p),
  13295. bif:concat (str (rdf:_), "%d"),
  13296. 2),
  13297. 0 ) ) ) .
  13298. optional {?id virtrdf:qmPriorityOrder ?ord} } } ) as sp
  13299. order by 3, 2, 1 ) as sub );
  13300. -- dbg_obj_princ ('DB.DBA.RDF_QM_ADD_MAPPING_TO_STORAGE: found ', iris_and_orders);
  13301. foreach (any itm in iris_and_orders) do
  13302. {
  13303. declare id, p varchar;
  13304. id := itm[0];
  13305. p := itm[1];
  13306. sparql define input:storage ""
  13307. delete from graph <http://www.openlinksw.com/schemas/virtrdf#> {
  13308. `iri(?:lstiri)` `iri(?:p)` `iri(?:id)` };
  13309. }
  13310. ctr := 1;
  13311. qmid_is_printed := 0;
  13312. foreach (any itm in iris_and_orders) do
  13313. {
  13314. declare id varchar;
  13315. declare ord integer;
  13316. id := itm[0];
  13317. ord := itm[2];
  13318. if (ord > qmorder)
  13319. {
  13320. sparql define input:storage ""
  13321. insert in graph <http://www.openlinksw.com/schemas/virtrdf#> {
  13322. `iri(?:lstiri)`
  13323. `iri(bif:sprintf("%s%d", str(rdf:_), ?:ctr))`
  13324. `iri(?:qmid)` };
  13325. -- dbg_obj_princ ('DB.DBA.RDF_QM_ADD_MAPPING_TO_STORAGE: qmid is printed: ', ctr);
  13326. ctr := ctr + 1;
  13327. qmid_is_printed := 1;
  13328. }
  13329. sparql define input:storage ""
  13330. insert in graph <http://www.openlinksw.com/schemas/virtrdf#> {
  13331. `iri(?:lstiri)`
  13332. `iri(bif:sprintf("%s%d", str(rdf:_), ?:ctr))`
  13333. `iri(?:id)` };
  13334. ctr := ctr + 1;
  13335. }
  13336. if (not qmid_is_printed)
  13337. {
  13338. sparql define input:storage ""
  13339. insert in graph <http://www.openlinksw.com/schemas/virtrdf#> {
  13340. `iri(?:lstiri)`
  13341. `iri(bif:sprintf("%s%d", str(rdf:_), ?:ctr))`
  13342. `iri(?:qmid)` };
  13343. -- dbg_obj_princ ('DB.DBA.RDF_QM_ADD_MAPPING_TO_STORAGE: qmid is printed: ', ctr);
  13344. ctr := ctr + 1;
  13345. }
  13346. }
  13347. ;
  13348. create procedure DB.DBA.RDF_QM_DELETE_MAPPING_FROM_STORAGE (in storage varchar, in qmparent varchar, in qmid varchar)
  13349. {
  13350. declare graphiri, lstiri varchar;
  13351. declare iris_and_orders any;
  13352. declare ctr integer;
  13353. -- dbg_obj_princ ('DB.DBA.RDF_QM_DELETE_MAPPING_FROM_STORAGE (', storage, qmparent, qmid, ')');
  13354. qmid := iri_to_id (qmid, 0, NULL);
  13355. graphiri := DB.DBA.JSO_SYS_GRAPH ();
  13356. if (qmparent is not null)
  13357. lstiri := (sparql define input:storage ""
  13358. select ?lst where { graph ?:graphiri {
  13359. `iri(?:qmparent)` virtrdf:qmUserSubMaps ?lst } } );
  13360. else
  13361. lstiri := (sparql define input:storage ""
  13362. select ?lst where { graph ?:graphiri {
  13363. `iri(?:storage)` virtrdf:qsUserMaps ?lst } } );
  13364. -- dbg_obj_princ ('DB.DBA.RDF_QM_DELETE_MAPPING_FROM_STORAGE: storage=', storage, ', qmparent=', qmparent, ', lstiri=', lstiri);
  13365. iris_and_orders := (
  13366. select DB.DBA.VECTOR_AGG (vector (sub."id", sub."p", sub."ord1"))
  13367. from (
  13368. select sp."id", sp."p", sp."ord1"
  13369. from (
  13370. sparql define input:storage ""
  13371. select ?id ?p
  13372. (bif:coalesce (?ord,
  13373. 1000 + bif:aref (
  13374. bif:sprintf_inverse (
  13375. str(?p),
  13376. bif:concat (str (rdf:_), "%d"),
  13377. 2),
  13378. 0 ) ) ) as ?ord1
  13379. where { graph ?:graphiri {
  13380. `iri(?:lstiri)` ?p ?id .
  13381. filter (! bif:isnull (bif:aref (
  13382. bif:sprintf_inverse (
  13383. str(?p),
  13384. bif:concat (str (rdf:_), "%d"),
  13385. 2),
  13386. 0 ) ) ) .
  13387. optional {?id virtrdf:qmPriorityOrder ?ord} } } ) as sp
  13388. order by 3, 2, 1 ) as sub );
  13389. -- dbg_obj_princ ('DB.DBA.RDF_QM_DELETE_MAPPING_FROM_STORAGE: found ', iris_and_orders);
  13390. foreach (any itm in iris_and_orders) do
  13391. {
  13392. declare id, p varchar;
  13393. id := itm[0];
  13394. p := itm[1];
  13395. sparql define input:storage ""
  13396. delete from graph <http://www.openlinksw.com/schemas/virtrdf#> {
  13397. `iri(?:lstiri)` `iri(?:p)` `iri(?:id)` . };
  13398. }
  13399. ctr := 1;
  13400. foreach (any itm in iris_and_orders) do
  13401. {
  13402. declare id varchar;
  13403. declare ord integer;
  13404. id := itm[0];
  13405. ord := itm[2];
  13406. if (iri_to_id (id, 0, 0) <> qmid)
  13407. {
  13408. sparql define input:storage ""
  13409. insert in graph <http://www.openlinksw.com/schemas/virtrdf#> {
  13410. `iri(?:lstiri)`
  13411. `iri(bif:sprintf("%s%d", str(rdf:_), ?:ctr))`
  13412. `iri(?:id)` . };
  13413. -- dbg_obj_princ ('DB.DBA.RDF_QM_DELETE_MAPPING_FROM_STORAGE: reinsert ', itm, ' in rdf:_', ctr);
  13414. ctr := ctr + 1;
  13415. }
  13416. else
  13417. {
  13418. -- dbg_obj_princ ('DB.DBA.RDF_QM_DELETE_MAPPING_FROM_STORAGE: skipping ', qmid);
  13419. ;
  13420. }
  13421. }
  13422. }
  13423. ;
  13424. create procedure DB.DBA.RDF_QM_SET_DEFAULT_MAPPING (in storage varchar, in qmid varchar)
  13425. {
  13426. declare graphiri, old_qmid varchar;
  13427. -- dbg_obj_princ ('DB.DBA.RDF_QM_SET_DEFAULT_MAPPING (', storage, qmid, ')');
  13428. graphiri := DB.DBA.JSO_SYS_GRAPH ();
  13429. old_qmid := coalesce ((sparql define input:storage ""
  13430. select ?qm where { graph ?:graphiri {
  13431. `iri(?:storage)` virtrdf:qsDefaultMap ?qm } } ) );
  13432. if (old_qmid is not null)
  13433. {
  13434. if (cast (old_qmid as varchar) = cast (qmid as varchar))
  13435. return;
  13436. signal ('22023', 'Quad map storage <' || storage || '> has set a default quad map <' || old_qmid || '>, drop it before adding <' || qmid || '>');
  13437. }
  13438. sparql define input:storage ""
  13439. insert in graph <http://www.openlinksw.com/schemas/virtrdf#> { `iri(?:storage)` virtrdf:qsDefaultMap `iri(?:qmid)` . };
  13440. commit work;
  13441. }
  13442. ;
  13443. create function DB.DBA.RDF_SML_DROP (in smliri varchar, in silent integer, in compose_report integer := 1) returns any
  13444. {
  13445. declare report, affected any;
  13446. report := '';
  13447. vectorbld_init (affected);
  13448. for (sparql define input:storage ""
  13449. select ?storageiri
  13450. from virtrdf:
  13451. where { ?storageiri virtrdf:qsMacroLibrary `iri(?:smliri)` } ) do
  13452. {
  13453. report := report || 'SPARQL macro library <' || smliri || '> has been detached from quad storage <' || "storageiri" || '>\n';
  13454. vectorbld_acc (affected, "storageiri");
  13455. }
  13456. vectorbld_final (affected);
  13457. sparql define input:storage ""
  13458. delete from virtrdf:
  13459. { ?storageiri virtrdf:qsMacroLibrary `iri(?:smliri)` }
  13460. from virtrdf:
  13461. where { ?storageiri virtrdf:qsMacroLibrary `iri(?:smliri)` };
  13462. commit work;
  13463. if (not exists (
  13464. sparql define input:storage ""
  13465. select 1 from virtrdf: where { `iri(?:smliri)` ?p ?o } ) )
  13466. {
  13467. DB.DBA.RDF_QM_APPLY_CHANGES (null, affected);
  13468. if (silent)
  13469. {
  13470. if (compose_report)
  13471. return report || 'SPARQL macro library <' || smliri || '> does not exists, nothing to delete';
  13472. else
  13473. return 0;
  13474. }
  13475. else
  13476. signal ('22023', 'SPARQL macro library <' || smliri || '> does not exists, nothing to delete');
  13477. }
  13478. DB.DBA.RDF_QM_ASSERT_JSO_TYPE (smliri, 'http://www.openlinksw.com/schemas/virtrdf#SparqlMacroLibrary');
  13479. sparql define input:storage ""
  13480. delete from graph virtrdf: {
  13481. `iri(?:smliri)` ?p ?o }
  13482. from virtrdf:
  13483. where { `iri(?:smliri)` ?p ?o };
  13484. DB.DBA.RDF_QM_APPLY_CHANGES (vector ('http://www.openlinksw.com/schemas/virtrdf#SparqlMacroLibrary', smliri), affected);
  13485. if (compose_report)
  13486. return report || 'SPARQL macro library <' || smliri || '> has been deleted';
  13487. else
  13488. return 1;
  13489. }
  13490. ;
  13491. create function DB.DBA.RDF_SML_CREATE (in smliri varchar, in txt varchar) returns any
  13492. {
  13493. declare stat, msg, smliri_copy varchar;
  13494. declare mdata, rset, affected any;
  13495. DB.DBA.RDF_QM_ASSERT_JSO_TYPE (smliri, 'http://www.openlinksw.com/schemas/virtrdf#SparqlMacroLibrary', 1);
  13496. stat := '00000';
  13497. if (__tag (txt) = __tag of nvarchar)
  13498. txt := charset_recode (txt, '_WIDE_', 'UTF-8');
  13499. exec ('sparql define input:macro-lib-ignore-create "yes" define input:disable-storage-macro-lib "yes" ' || txt, stat, msg, null, 1, mdata, rset);
  13500. if (stat <> '00000')
  13501. signal (stat, msg);
  13502. if (length (rset))
  13503. signal ('SPAR0', 'Assertion failed: the validation query of macro library should return nothing');
  13504. vectorbld_init (affected);
  13505. for (sparql define input:storage ""
  13506. select ?storageiri
  13507. from virtrdf:
  13508. where { ?storageiri virtrdf:qsMacroLibrary `iri(?:smliri)` } ) do
  13509. {
  13510. vectorbld_acc (affected, "storageiri");
  13511. }
  13512. smliri_copy := smliri;
  13513. vectorbld_acc (affected, smliri_copy);
  13514. vectorbld_final (affected);
  13515. sparql define input:storage ""
  13516. delete from graph <http://www.openlinksw.com/schemas/virtrdf#> {
  13517. `iri(?:smliri)` ?p ?o }
  13518. from <http://www.openlinksw.com/schemas/virtrdf#>
  13519. where { `iri(?:smliri)` ?p ?o };
  13520. commit work;
  13521. sparql define input:storage ""
  13522. insert in graph <http://www.openlinksw.com/schemas/virtrdf#> {
  13523. `iri(?:smliri)` a virtrdf:SparqlMacroLibrary ; virtrdf:smlSourceText ?:txt };
  13524. DB.DBA.RDF_QM_APPLY_CHANGES (null, affected);
  13525. return 'SPARQL macro library <' || smliri || '> has been (re)created';
  13526. }
  13527. ;
  13528. create function DB.DBA.RDF_QM_DETACH_MACRO_LIBRARY (in storageiri varchar, in args any) returns any
  13529. {
  13530. declare expected_smliri varchar;
  13531. declare old_ctr, expected_found integer;
  13532. declare silent, report any;
  13533. expected_smliri := get_keyword_ucase ('ID', args, NULL);
  13534. silent := get_keyword_ucase ('SILENT', args, 0);
  13535. expected_found := 0;
  13536. old_ctr := 0;
  13537. vectorbld_init (report);
  13538. for (sparql define input:storage ""
  13539. select ?oldsmliri
  13540. from virtrdf:
  13541. where { ?storageiri virtrdf:qsMacroLibrary ?oldsmliri } ) do
  13542. {
  13543. if (expected_smliri is not null and cast (expected_smliri as nvarchar) <> cast ("oldsmliri" as nvarchar))
  13544. {
  13545. if (silent)
  13546. vectorbld_acc (report, vector ('00100', 'The SPARQL macro library to detach from <' || storageiri || '> is <' || expected_smliri || '> but actually attached one is <' || "oldsmliri" || '>, nothing to do'));
  13547. else
  13548. signal ('22023', 'The SPARQL macro library to detach from <' || storageiri || '> is <' || expected_smliri || '> but actually attached one is <' || "oldsmliri" || '>');
  13549. }
  13550. else
  13551. {
  13552. if (expected_smliri is not null)
  13553. expected_found := 1;
  13554. vectorbld_acc (report, vector ('00000', 'SPARQL macro library <' || "oldsmliri" || '> has been detached from quad storage <' || storageiri || '>'));
  13555. }
  13556. old_ctr := old_ctr + 1;
  13557. }
  13558. if (expected_smliri is not null)
  13559. {
  13560. sparql define input:storage ""
  13561. delete from virtrdf:
  13562. { ?storageiri virtrdf:qsMacroLibrary ?smliri }
  13563. from virtrdf:
  13564. where { ?storageiri virtrdf:qsMacroLibrary ?smliri };
  13565. }
  13566. else
  13567. {
  13568. sparql define input:storage ""
  13569. delete from virtrdf:
  13570. { ?storageiri virtrdf:qsMacroLibrary ?smliri }
  13571. from virtrdf:
  13572. where { ?storageiri virtrdf:qsMacroLibrary ?smliri };
  13573. }
  13574. commit work;
  13575. if (old_ctr > 1)
  13576. vectorbld_acc (report, vector ('00100', 'Note that there was a configuration error: more than one macro library was attached to the quad storage <' || storageiri || '>'));
  13577. else if (old_ctr = 0)
  13578. {
  13579. if (silent)
  13580. vectorbld_acc (report, vector ('00100', 'No one SPARQL macro library is attached to the quad storage <' || storageiri || '>, nothing to detach'));
  13581. else
  13582. signal ('22023', 'No one SPARQL macro library is attached to the quad storage <' || storageiri || '>, nothing to detach');
  13583. }
  13584. vectorbld_final (report);
  13585. -- dbg_obj_princ ('DB.DBA.RDF_QM_DETACH_MACRO_LIBRARY (', storageiri, args, ') returns ', report);
  13586. return report;
  13587. }
  13588. ;
  13589. create function DB.DBA.RDF_QM_ATTACH_MACRO_LIBRARY (in storageiri varchar, in args any) returns any
  13590. {
  13591. declare smliri varchar;
  13592. smliri := get_keyword_ucase ('ID', args, NULL);
  13593. DB.DBA.RDF_QM_ASSERT_JSO_TYPE (storageiri, 'http://www.openlinksw.com/schemas/virtrdf#QuadStorage');
  13594. DB.DBA.RDF_QM_ASSERT_JSO_TYPE (smliri, 'http://www.openlinksw.com/schemas/virtrdf#SparqlMacroLibrary');
  13595. declare report any;
  13596. vectorbld_init (report);
  13597. for (sparql define input:storage ""
  13598. select ?oldsmliri
  13599. from virtrdf:
  13600. where { ?storageiri virtrdf:qsMacroLibrary ?oldsmliri } ) do
  13601. {
  13602. vectorbld_acc (report, vector ('00000', 'SPARQL macro library <' || "oldsmliri" || '> has been detached from quad storage <' || storageiri || '>'));
  13603. }
  13604. sparql define input:storage ""
  13605. delete from virtrdf:
  13606. { ?storageiri virtrdf:qsMacroLibrary ?oldsmliri }
  13607. from virtrdf:
  13608. where { ?storageiri virtrdf:qsMacroLibrary ?oldsmliri };
  13609. commit work;
  13610. sparql define input:storage ""
  13611. prefix rdfdf: <http://www.openlinksw.com/virtrdf-data-formats#>
  13612. insert in graph virtrdf: {
  13613. `iri(?:storageiri)` virtrdf:qsMacroLibrary `iri(?:smliri)` };
  13614. vectorbld_acc (report, vector ('00000', 'SPARQL macro library <' || smliri || '> has been attached to quad storage <' || storageiri || '>'));
  13615. vectorbld_final (report);
  13616. return report;
  13617. }
  13618. ;
  13619. create procedure DB.DBA.RDF_ADD_qmAliasesKeyrefdByQuad (in qm_iri varchar)
  13620. {
  13621. declare kr_iri varchar;
  13622. declare good_ctr, all_ctr integer;
  13623. kr_iri := qm_iri || '--qmAliasesKeyrefdByQuad';
  13624. sparql define input:storage "" delete from virtrdf: { `iri(?:kr_iri)` ?p ?o } from virtrdf: where { `iri(?:kr_iri)` ?p ?o };
  13625. sparql define input:storage "" insert in virtrdf: { `iri(?:qm_iri)` virtrdf:qmAliasesKeyrefdByQuad `iri(?:kr_iri)` . `iri(?:kr_iri)` a virtrdf:array-of-string };
  13626. good_ctr := 0;
  13627. all_ctr := 0;
  13628. for ( sparql define input:storage ""
  13629. select ?alias ?tbl (sql:VECTOR_AGG (str(?col))) as ?cols
  13630. from virtrdf:
  13631. where {
  13632. `iri(?:qm_iri)` a virtrdf:QuadMap ;
  13633. ?fld_p ?qmv .
  13634. filter (?fld_p in (virtrdf:qmGraphMap , virtrdf:qmSubjectMap , virtrdf:qmPredicateMap , virtrdf:qmObjectMap))
  13635. ?qmv a virtrdf:QuadMapValue ;
  13636. virtrdf:qmvATables [
  13637. ?qmvat_p [ a virtrdf:QuadMapATable ;
  13638. virtrdf:qmvaAlias ?alias ;
  13639. virtrdf:qmvaTableName ?tbl ] ] ;
  13640. virtrdf:qmvColumns [
  13641. ?qmvc_p [ a virtrdf:QuadMapColumn ;
  13642. virtrdf:qmvcAlias ?alias ;
  13643. virtrdf:qmvcColumnName ?col ] ] ;
  13644. virtrdf:qmvFormat [ a virtrdf:QuadMapFormat ;
  13645. virtrdf:qmfIsBijection ?bij ] .
  13646. filter (?bij != 0)
  13647. } ) do
  13648. {
  13649. -- dbg_obj_princ ('Quad map ', "qm_iri", ' has alias ', "alias", ' of table ', "tbl", ' with cols ', "cols");
  13650. all_ctr := all_ctr + 1;
  13651. for (select KEY_ID, KEY_N_SIGNIFICANT from DB.DBA.SYS_KEYS where KEY_TABLE = "tbl" and KEY_IS_UNIQUE) do
  13652. {
  13653. for (select "COLUMN" from DB.DBA.SYS_KEY_PARTS, DB.DBA.SYS_COLS
  13654. where KP_KEY_ID = KEY_ID and KP_NTH < KEY_N_SIGNIFICANT and COL_ID = KP_COL ) do
  13655. {
  13656. if (not position ("COLUMN", "cols"))
  13657. {
  13658. -- dbg_obj_princ ("COLUMN", ' not in ', "cols");
  13659. goto wrong_key;
  13660. }
  13661. }
  13662. good_ctr := good_ctr + 1;
  13663. -- dbg_obj_princ ('Quad map ', qm_iri, ' can identify source rows in alias ', "alias", ' of table ', "tbl");
  13664. sparql define input:storage "" insert in virtrdf: { `iri(?:kr_iri)` `iri(bif:sprintf("%s%d", str(rdf:_), ?:good_ctr))` ?:"alias" };
  13665. goto right_key;
  13666. wrong_key: ;
  13667. }
  13668. right_key: ;
  13669. }
  13670. -- dbg_obj_princ ('Quad map ', qm_iri, ' can identify source rows in ', good_ctr, ' of ', all_ctr, ' its aliases with bijections.');
  13671. }
  13672. ;
  13673. create procedure DB.DBA.RDF_UPGRADE_QUAD_MAP (in qm_iri varchar)
  13674. {
  13675. declare keyrefd any;
  13676. if (not exists (sparql define input:storage "" select (1) from virtrdf: where { `iri(?:qm_iri)` a virtrdf:QuadMap }))
  13677. signal ('RDFxx', sprintf ('Quad map <%s> does not exist, nothing to upgrade', qm_iri));
  13678. if (not exists (sparql define input:storage "" select (1) from virtrdf: where { `iri(?:qm_iri)` virtrdf:qmAliasesKeyrefdByQuad ?keyrefs }))
  13679. DB.DBA.RDF_ADD_qmAliasesKeyrefdByQuad (qm_iri);
  13680. }
  13681. ;
  13682. create procedure DB.DBA.RDF_UPGRADE_METADATA ()
  13683. {
  13684. for (sparql define input:storage "" select ?qm_iri from virtrdf: where { ?qm_iri a virtrdf:QuadMap }) do
  13685. {
  13686. DB.DBA.RDF_UPGRADE_QUAD_MAP ("qm_iri");
  13687. }
  13688. commit work;
  13689. }
  13690. ;
  13691. -----
  13692. -- RDF parallel load
  13693. create procedure DB.DBA.TTLP_EV_TRIPLE_W (
  13694. in g_iid IRI_ID, in s_uri varchar, in p_uri varchar,
  13695. in o_uri varchar, in env any )
  13696. {
  13697. -- dbg_obj_princ ('DB.DBA.TTLP_EV_TRIPLE_W (', g_iid, s_uri, p_uri, o_uri, env, ')');
  13698. declare log_mode integer;
  13699. declare s_iid, p_iid, o_iid IRI_ID;
  13700. log_mode := env[0];
  13701. if (isstring (registry_get ('DB.DBA.RDF_REPL')))
  13702. repl_publish ('__rdf_repl', '__rdf_repl.log');
  13703. if (log_mode = 1)
  13704. {
  13705. whenever sqlstate '40001' goto deadlock_1;
  13706. again_1:
  13707. log_enable (1, 1);
  13708. s_iid := iri_to_id (s_uri);
  13709. p_iid := iri_to_id (p_uri);
  13710. o_iid := iri_to_id (o_uri);
  13711. commit work;
  13712. log_enable (0, 1);
  13713. insert soft DB.DBA.RDF_QUAD (G,S,P,O)
  13714. values (g_iid, s_iid, p_iid, o_iid);
  13715. commit work;
  13716. -- dbg_obj_princ ('DB.DBA.TTLP_EV_TRIPLE_W (', g_iid, s_uri, p_uri, o_uri, env, ') done /1');
  13717. return;
  13718. }
  13719. if (log_mode = 0)
  13720. {
  13721. whenever sqlstate '40001' goto deadlock_0;
  13722. again_0:
  13723. log_enable (0, 1);
  13724. s_iid := iri_to_id (s_uri);
  13725. p_iid := iri_to_id (p_uri);
  13726. o_iid := iri_to_id (o_uri);
  13727. commit work;
  13728. insert soft DB.DBA.RDF_QUAD (G,S,P,O) values (g_iid, s_iid, p_iid, o_iid);
  13729. commit work;
  13730. -- dbg_obj_princ ('DB.DBA.TTLP_EV_TRIPLE_W (', g_iid, s_uri, p_uri, o_uri, env, ') done /0');
  13731. return;
  13732. }
  13733. whenever sqlstate '40001' goto deadlock_2;
  13734. again_2:
  13735. log_enable (1, 1);
  13736. s_iid := iri_to_id (s_uri);
  13737. p_iid := iri_to_id (p_uri);
  13738. o_iid := iri_to_id (o_uri);
  13739. commit work;
  13740. insert soft DB.DBA.RDF_QUAD (G,S,P,O) values (g_iid, s_iid, p_iid, o_iid);
  13741. commit work;
  13742. -- dbg_obj_princ ('DB.DBA.TTLP_EV_TRIPLE_W (', g_iid, s_uri, p_uri, o_uri, env, ') done /2');
  13743. return;
  13744. deadlock_0:
  13745. rollback work;
  13746. goto again_0;
  13747. deadlock_1:
  13748. rollback work;
  13749. goto again_1;
  13750. deadlock_2:
  13751. rollback work;
  13752. goto again_2;
  13753. }
  13754. ;
  13755. create procedure DB.DBA.TTLP_EV_TRIPLE_L_W (
  13756. in g_iid IRI_ID, in s_uri varchar, in p_uri varchar,
  13757. in o_val any, in o_type any, in o_lang any, in env any )
  13758. {
  13759. -- dbg_obj_princ ('DB.DBA.TTLP_EV_TRIPLE_L_W (', g_iid, s_uri, p_uri, o_val, o_type, o_lang, env, ')');
  13760. declare log_mode integer;
  13761. declare ro_id_dict any;
  13762. log_mode := env[0];
  13763. ro_id_dict := env[1];
  13764. declare s_iid, p_iid IRI_ID;
  13765. if (isstring (o_type))
  13766. {
  13767. declare parsed any;
  13768. parsed := __xqf_str_parse_to_rdf_box (o_val, o_type, isstring (o_val));
  13769. if (parsed is not null)
  13770. {
  13771. if (__tag of rdf_box = __tag (parsed))
  13772. {
  13773. if (256 = rdf_box_type (parsed))
  13774. db..rdf_geo_add (parsed);
  13775. else
  13776. rdf_box_set_type (parsed,
  13777. DB.DBA.RDF_TWOBYTE_OF_DATATYPE (iri_to_id (o_type)));
  13778. parsed := DB.DBA.RDF_OBJ_ADD (257, parsed, 257, ro_id_dict);
  13779. -- dbg_obj_princ ('rdf_box_type is set to ', rdf_box_type (parsed));
  13780. }
  13781. o_val := parsed;
  13782. }
  13783. }
  13784. whenever sqlstate '40001' goto deadlck;
  13785. again:
  13786. if (log_mode = 0)
  13787. log_enable (0, 1);
  13788. else
  13789. log_enable (1, 1);
  13790. s_iid := iri_to_id (s_uri);
  13791. p_iid := iri_to_id (p_uri);
  13792. if (isstring (o_val) or (__tag of XML = __tag (o_val)))
  13793. {
  13794. if (isstring (o_type) or isstring (o_lang))
  13795. {
  13796. if (not isstring (o_type))
  13797. o_type := null;
  13798. if (not isstring (o_lang))
  13799. o_lang := null;
  13800. o_val := DB.DBA.RDF_MAKE_OBJ_OF_TYPEDSQLVAL_FT (o_val,
  13801. iri_to_id (o_type),
  13802. o_lang, g_iid, p_iid, ro_id_dict );
  13803. }
  13804. else
  13805. o_val := DB.DBA.RDF_MAKE_OBJ_OF_SQLVAL_FT (o_val, g_iid, p_iid, ro_id_dict);
  13806. }
  13807. else if (__tag of rdf_box = __tag (o_val))
  13808. {
  13809. if (__tag of varchar = rdf_box_data_tag (o_val) and __rdf_obj_ft_rule_check (g_iid, p_iid))
  13810. o_val := DB.DBA.RDF_OBJ_ADD (257, o_val, 257, ro_id_dict);
  13811. else if (0 < rdf_box_needs_digest (o_val))
  13812. o_val := DB.DBA.RDF_OBJ_ADD (257, o_val, 257);
  13813. }
  13814. -- dbg_obj_princ ('final o_val = ', o_val);
  13815. if (log_mode <= 1)
  13816. log_enable (0, 1);
  13817. insert soft DB.DBA.RDF_QUAD (G,S,P,O)
  13818. values (g_iid, s_iid, p_iid, o_val);
  13819. -- dbg_obj_princ ('DB.DBA.TTLP_EV_TRIPLE_L_W (', g_iid, s_uri, p_uri, o_val, o_type, o_lang, env, ') done');
  13820. commit work;
  13821. return;
  13822. deadlck:
  13823. rollback work;
  13824. goto again;
  13825. }
  13826. ;
  13827. create procedure DB.DBA.TTLP_EV_NEW_GRAPH_A (inout g varchar, inout g_iid IRI_ID, inout app_env any) {
  13828. -- dbg_obj_princ ('DB.DBA.TTLP_EV_NEW_GRAPH_A(', g, g_iid, app_env, ')');
  13829. if (__rdf_obj_ft_rule_count_in_graph (g_iid))
  13830. app_env[2][1] := dict_new (app_env[3]);
  13831. else
  13832. app_env[2][1] := null;
  13833. if (__rdf_graph_is_in_enabled_repl (g_iid))
  13834. app_env[4] := g;
  13835. else
  13836. app_env[4] := null;
  13837. }
  13838. ;
  13839. create procedure DB.DBA.TTLP_EV_TRIPLE_A (
  13840. inout g_iid IRI_ID, inout s_uri varchar, inout p_uri varchar,
  13841. inout o_uri varchar,
  13842. inout app_env any )
  13843. {
  13844. -- dbg_obj_princ ('DB.DBA.TTLP_EV_TRIPLE_A (', g_iid, s_uri, p_uri, o_uri, app_env, ')');
  13845. if (app_env[4] is not null)
  13846. __rdf_repl_quad (84, app_env[4], iri_canonicalize (s_uri), iri_canonicalize (p_uri), iri_canonicalize (o_uri));
  13847. app_env[1] := aq_request (
  13848. app_env[0], 'DB.DBA.TTLP_EV_TRIPLE_W',
  13849. vector (g_iid, s_uri, p_uri, o_uri, app_env[2]) );
  13850. if (mod (app_env[1], 100000) = 0)
  13851. {
  13852. declare ro_id_dict any;
  13853. ro_id_dict := app_env[2][1];
  13854. if (ro_id_dict is not null)
  13855. DB.DBA.RDF_OBJ_ADD_KEYWORD_FOR_GRAPH (g_iid, ro_id_dict);
  13856. commit work;
  13857. aq_wait_all (app_env[0]);
  13858. }
  13859. }
  13860. ;
  13861. create procedure DB.DBA.TTLP_EV_TRIPLE_L_A (
  13862. inout g_iid IRI_ID, inout s_uri varchar, inout p_uri varchar,
  13863. inout o_val any, inout o_type varchar, inout o_lang varchar,
  13864. inout app_env any )
  13865. {
  13866. -- dbg_obj_princ ('DB.DBA.TTLP_EV_TRIPLE_L_A (', g_iid, s_uri, p_uri, o_val, o_type, o_lang, app_env, ')');
  13867. if (app_env[4] is not null)
  13868. {
  13869. if (isstring (o_type))
  13870. __rdf_repl_quad (81, app_env[4], iri_canonicalize (s_uri), iri_canonicalize (p_uri), o_val, iri_canonicalize (o_type), NULL);
  13871. else if (isstring (o_lang))
  13872. __rdf_repl_quad (82, app_env[4], iri_canonicalize (s_uri), iri_canonicalize (p_uri), o_val, null, o_lang);
  13873. else
  13874. __rdf_repl_quad (80, app_env[4], iri_canonicalize (s_uri), iri_canonicalize (p_uri), o_val);
  13875. }
  13876. if (__tag of XML = __tag (o_val))
  13877. {
  13878. DB.DBA.TTLP_EV_TRIPLE_L_W (g_iid, s_uri, p_uri, o_val, o_type, o_lang, app_env[2]);
  13879. return;
  13880. }
  13881. app_env[1] := aq_request (
  13882. app_env[0], 'DB.DBA.TTLP_EV_TRIPLE_L_W',
  13883. vector (g_iid, s_uri, p_uri, o_val, o_type, o_lang, app_env[2]) );
  13884. if (mod (app_env[1], 100000) = 0)
  13885. {
  13886. declare ro_id_dict any;
  13887. ro_id_dict := app_env[2][1];
  13888. if (ro_id_dict is not null)
  13889. DB.DBA.RDF_OBJ_ADD_KEYWORD_FOR_GRAPH (g_iid, ro_id_dict);
  13890. commit work;
  13891. aq_wait_all (app_env[0]);
  13892. }
  13893. }
  13894. ;
  13895. create procedure DB.DBA.TTLP_EV_COMMIT_A (
  13896. inout graph_iri varchar, inout app_env any )
  13897. {
  13898. -- dbg_obj_princ ('DB.DBA.TTLP_EV_COMMIT_A (', graph_iri, app_env, ')');
  13899. commit work;
  13900. aq_wait_all (app_env[0]);
  13901. commit work;
  13902. DB.DBA.TTLP_EV_COMMIT (graph_iri, app_env[2]);
  13903. commit work;
  13904. }
  13905. ;
  13906. -- for replication should not use AQ
  13907. create procedure DB.DBA.TTLP_EV_TRIPLE_R (
  13908. inout g_iid IRI_ID, inout s_uri varchar, inout p_uri varchar,
  13909. inout o_uri varchar,
  13910. inout app_env any )
  13911. {
  13912. -- dbg_obj_princ ('DB.DBA.TTLP_EV_TRIPLE_A (', g_iid, s_uri, p_uri, o_uri, app_env, ')');
  13913. if (app_env[4] is not null)
  13914. __rdf_repl_quad (84, app_env[4], iri_canonicalize (s_uri), iri_canonicalize (p_uri), iri_canonicalize (o_uri));
  13915. commit work;
  13916. app_env[1] := coalesce (app_env[1], 0) + 1;
  13917. DB.DBA.TTLP_EV_TRIPLE_W (g_iid, s_uri, p_uri, o_uri, app_env[2]);
  13918. if (mod (app_env[1], 100000) = 0)
  13919. {
  13920. declare ro_id_dict any;
  13921. ro_id_dict := app_env[2][1];
  13922. if (ro_id_dict is not null)
  13923. DB.DBA.RDF_OBJ_ADD_KEYWORD_FOR_GRAPH (g_iid, ro_id_dict);
  13924. }
  13925. }
  13926. ;
  13927. create procedure DB.DBA.TTLP_EV_TRIPLE_L_R (
  13928. inout g_iid IRI_ID, inout s_uri varchar, inout p_uri varchar,
  13929. inout o_val any, inout o_type varchar, inout o_lang varchar,
  13930. inout app_env any )
  13931. {
  13932. -- dbg_obj_princ ('DB.DBA.TTLP_EV_TRIPLE_L_A (', g_iid, s_uri, p_uri, o_val, o_type, o_lang, app_env, ')');
  13933. if (app_env[4] is not null)
  13934. {
  13935. if (isstring (o_type))
  13936. __rdf_repl_quad (81, app_env[4], iri_canonicalize (s_uri), iri_canonicalize (p_uri), o_val, iri_canonicalize (o_type), NULL);
  13937. else if (isstring (o_lang))
  13938. __rdf_repl_quad (82, app_env[4], iri_canonicalize (s_uri), iri_canonicalize (p_uri), o_val, null, o_lang);
  13939. else
  13940. __rdf_repl_quad (80, app_env[4], iri_canonicalize (s_uri), iri_canonicalize (p_uri), o_val);
  13941. }
  13942. commit work;
  13943. if (__tag of XML = __tag (o_val))
  13944. {
  13945. DB.DBA.TTLP_EV_TRIPLE_L_W (g_iid, s_uri, p_uri, o_val, o_type, o_lang, app_env[2]);
  13946. return;
  13947. }
  13948. app_env[1] := coalesce (app_env[1], 0) + 1;
  13949. DB.DBA.TTLP_EV_TRIPLE_L_W (g_iid, s_uri, p_uri, o_val, o_type, o_lang, app_env[2]);
  13950. if (mod (app_env[1], 100000) = 0)
  13951. {
  13952. declare ro_id_dict any;
  13953. ro_id_dict := app_env[2][1];
  13954. if (ro_id_dict is not null)
  13955. DB.DBA.RDF_OBJ_ADD_KEYWORD_FOR_GRAPH (g_iid, ro_id_dict);
  13956. }
  13957. }
  13958. ;
  13959. create procedure DB.DBA.TTLP_EV_COMMIT_R (
  13960. inout graph_iri varchar, inout app_env any )
  13961. {
  13962. -- dbg_obj_princ ('DB.DBA.TTLP_EV_COMMIT_A (', graph_iri, app_env, ')');
  13963. DB.DBA.TTLP_EV_COMMIT (graph_iri, app_env[2]);
  13964. }
  13965. ;
  13966. create function DB.DBA.TTLP_MT (in strg varchar, in base varchar, in graph varchar := null, in flags integer := 0,
  13967. in log_mode integer := 2, in threads integer := 3, in transactional int := 0)
  13968. {
  13969. declare app_env any;
  13970. if (graph = '')
  13971. signal ('22023', 'Empty string is not a valid graph IRI in DB.DBA.TTLP_MT()');
  13972. else if (graph is null)
  13973. {
  13974. graph := base;
  13975. if ((graph is null) or (graph = ''))
  13976. signal ('22023', 'DB.DBA.TTLP_MT() requires a valid IRI as a base argument if graph is not specified');
  13977. }
  13978. DB.DBA.TTLP_V (strg, base, graph, flags, threads, transactional, log_mode);
  13979. }
  13980. ;
  13981. create function DB.DBA.TTLP_MT_LOCAL_FILE (in filename varchar, in base varchar, in graph varchar := null, in flags integer := 0,
  13982. in log_mode integer := 2, in threads integer := 3, in transactional int := 0)
  13983. {
  13984. signal ('DEPRE', 'TTLP_MT_LOCAL_FILE deprecated. Use TTLP');
  13985. }
  13986. ;
  13987. create function DB.DBA.RDF_LOAD_RDFXML_MT (in strg varchar, in base varchar, in graph varchar,
  13988. in log_mode integer := 2, in threads integer := 3, in transactional int := 0)
  13989. {
  13990. declare ro_id_dict, app_env any;
  13991. if (graph = '')
  13992. signal ('22023', 'Empty string is not a valid graph IRI in DB.DBA.RDF_LOAD_RDFXML_MT()');
  13993. else if (graph is null)
  13994. {
  13995. graph := base;
  13996. if ((graph is null) or (graph = ''))
  13997. signal ('22023', 'DB.DBA.RDF_LOAD_RDFXML_MT() requires a valid IRI as a base argument if graph is not specified');
  13998. }
  13999. if (transactional = 0)
  14000. {
  14001. if (log_mode = 1 or log_mode = 0)
  14002. log_mode := log_mode + 2;
  14003. }
  14004. DB.DBA.RDF_LOAD_RDFXML (strg, base, graph);
  14005. return graph;
  14006. }
  14007. ;
  14008. -----
  14009. -- Free text index on DB.DBA.RDF_OBJ
  14010. create function DB.DBA.VT_DECODE_KEYWORD_ITM (inout vtdata varchar, inout ofs integer)
  14011. {
  14012. declare res integer;
  14013. if ((5 <> vtdata[ofs]) or (0 <> vtdata[ofs+5]))
  14014. signal ('23023', 'Invalid VT_WORD data in DB.DBA.VT_DECODE_KEYWORD_ITM');
  14015. res := (((vtdata[ofs+1] * 256) + vtdata[ofs+2]) * 256 + vtdata[ofs+3]) * 256 + vtdata[ofs+4];
  14016. ofs := ofs + 6;
  14017. return res;
  14018. }
  14019. ;
  14020. create procedure DB.DBA.VT_ENCODE_KEYWORD_ITM (in id integer, inout ses any)
  14021. {
  14022. declare strg varchar;
  14023. strg := '012345';
  14024. strg[5] := 0;
  14025. strg[4] := bit_and (id, 255); id := bit_shift (id, -8);
  14026. strg[3] := bit_and (id, 255); id := bit_shift (id, -8);
  14027. strg[2] := bit_and (id, 255); id := bit_shift (id, -8);
  14028. strg[1] := bit_and (id, 255); if (id > 255) signal ('22023', 'Abnormally big document id in DB.DBA.VT_ENCODE_KEYWORD_ITM');
  14029. strg[0] := 5;
  14030. http (strg, ses);
  14031. }
  14032. ;
  14033. create function DB.DBA.VT_COMPOSE_KEYWORD_INDEX_LINES (
  14034. inout carry_d_id integer, -- Smallest doc id of carry
  14035. inout carry_d_id_2 integer, -- largest doc id of carry
  14036. inout carry_data varchar, -- carry as ready-to-insert varchar data
  14037. in old_d_id integer, -- last read VT_D_ID, NULL when not found
  14038. in old_d_id_2 integer, -- last read VT_D_ID_2, NULL when not found
  14039. in old_data varchar, -- last read VT_DATA, NULL when not found
  14040. inout ro_id_offset integer, -- offset of first not-yet-used new id
  14041. inout new_ro_ids any ) -- array of all new ids
  14042. returns any -- returns vector of vector (d_id, d_id_2, data) of everything before or at current
  14043. {
  14044. declare res_acc, mix_ses any;
  14045. declare old_data_ofs, old_data_len, old_curr_id, mix_id integer;
  14046. declare new_ro_id_idx, new_ro_ids_count, mix_d_id, mix_d_id_2, mix_count integer;
  14047. -- dbg_obj_princ ('DB.DBA.VT_COMPOSE_KEYWORD_INDEX_LINES (', carry_d_id, carry_d_id_2, length (carry_data), ' bytes,', old_d_id, old_d_id_2, length (old_data), ' bytes,', ro_id_offset, length (new_ro_ids), ' items)');
  14048. vectorbld_init (res_acc);
  14049. mix_ses := string_output();
  14050. if (carry_data <> '')
  14051. {
  14052. mix_d_id := carry_d_id;
  14053. mix_d_id_2 := carry_d_id_2;
  14054. http (carry_data, mix_ses);
  14055. mix_count := length (carry_data) / 6;
  14056. }
  14057. else
  14058. {
  14059. mix_d_id := null;
  14060. mix_d_id_2 := null;
  14061. mix_count := 0;
  14062. }
  14063. old_data_ofs := 0;
  14064. if (old_data is null)
  14065. old_curr_id := null;
  14066. else
  14067. old_curr_id := DB.DBA.VT_DECODE_KEYWORD_ITM (old_data, old_data_ofs);
  14068. old_data_len := length (old_data);
  14069. new_ro_ids_count := length (new_ro_ids);
  14070. new_ro_id_idx := ro_id_offset;
  14071. if (new_ro_id_idx < new_ro_ids_count)
  14072. mix_id := new_ro_ids [new_ro_id_idx];
  14073. else
  14074. mix_id := null;
  14075. -- dbg_obj_princ ('DB.DBA.VT_COMPOSE_KEYWORD_INDEX_LINES starts/1: ', mix_d_id, old_curr_id, mix_id);
  14076. mix_d_id := __min_notnull (mix_d_id, old_curr_id, mix_id);
  14077. -- dbg_obj_princ ('DB.DBA.VT_COMPOSE_KEYWORD_INDEX_LINES starts/2: ', mix_d_id);
  14078. next_mix:
  14079. if (old_curr_id is null)
  14080. {
  14081. if ((new_ro_id_idx >= new_ro_ids_count) or (new_ro_ids [new_ro_id_idx] > old_d_id_2))
  14082. goto complete;
  14083. mix_id := new_ro_ids [new_ro_id_idx];
  14084. new_ro_id_idx := new_ro_id_idx + 1;
  14085. }
  14086. else
  14087. {
  14088. if ((new_ro_id_idx >= new_ro_ids_count) or (new_ro_ids [new_ro_id_idx] >= old_curr_id))
  14089. {
  14090. if ((new_ro_id_idx < new_ro_ids_count) and (new_ro_ids [new_ro_id_idx] = old_curr_id))
  14091. new_ro_id_idx := new_ro_id_idx + 1;
  14092. mix_id := old_curr_id;
  14093. if (old_data_ofs >= old_data_len)
  14094. old_curr_id := null;
  14095. else
  14096. old_curr_id := DB.DBA.VT_DECODE_KEYWORD_ITM (old_data, old_data_ofs);
  14097. }
  14098. else
  14099. {
  14100. mix_id := new_ro_ids [new_ro_id_idx];
  14101. new_ro_id_idx := new_ro_id_idx + 1;
  14102. }
  14103. }
  14104. if ((mix_count > 180) or ((mix_d_id_2 / 10000) <> (mix_id / 10000)))
  14105. {
  14106. -- dbg_obj_princ ('DB.DBA._COMPOSE_KEYWORD_INDEX_LINES completed a row from ', mix_d_id, ' to ', mix_d_id_2);
  14107. vectorbld_acc (res_acc, vector (mix_d_id, mix_d_id_2, string_output_string (mix_ses)));
  14108. mix_ses := string_output ();
  14109. mix_d_id := mix_id;
  14110. mix_count := 0;
  14111. }
  14112. DB.DBA.VT_ENCODE_KEYWORD_ITM (mix_id, mix_ses);
  14113. mix_d_id_2 := mix_id;
  14114. mix_count := mix_count + 1;
  14115. goto next_mix;
  14116. complete:
  14117. ro_id_offset := new_ro_id_idx;
  14118. if (mix_count > 150)
  14119. {
  14120. -- dbg_obj_princ ('DB.DBA._COMPOSE_KEYWORD_INDEX_LINES completed (last) row from ', mix_d_id, ' to ', mix_d_id_2);
  14121. vectorbld_acc (res_acc, vector (mix_d_id, mix_d_id_2, string_output_string (mix_ses)));
  14122. carry_data := '';
  14123. carry_d_id := carry_d_id_2 := null;
  14124. }
  14125. else
  14126. {
  14127. carry_data := string_output_string (mix_ses);
  14128. carry_d_id := mix_d_id;
  14129. carry_d_id_2 := mix_d_id_2;
  14130. }
  14131. vectorbld_final (res_acc);
  14132. -- dbg_obj_princ ('DB.DBA._COMPOSE_KEYWORD_INDEX_LINES completed, carry ', carry_d_id, carry_d_id_2, length (carry_data), ' bytes, res ', res_acc);
  14133. return res_acc;
  14134. }
  14135. ;
  14136. --!AWK PUBLIC
  14137. create function DB.DBA.RDF_OBJ_PATCH_CONTAINS_BY_GRAPH (in phrase varchar, in graph_iri varchar)
  14138. {
  14139. declare graph_keyword any;
  14140. whenever sqlstate '*' goto err;
  14141. graph_keyword := iri_to_id (graph_iri, 0, 0);
  14142. if (isinteger (graph_keyword))
  14143. goto err;
  14144. if (not sys_stat ('rdf_query_graph_keywords'))
  14145. return sprintf ('[__enc "UTF-8"] %s', phrase);
  14146. graph_keyword := WS.WS.STR_SQL_APOS (rdf_graph_keyword (graph_keyword));
  14147. return sprintf ('[__enc "UTF-8"] ^%s AND (%s)', graph_keyword, phrase);
  14148. err:
  14149. return '^"#nosuch"';
  14150. }
  14151. ;
  14152. --!AWK PUBLIC
  14153. create function DB.DBA.RDF_OBJ_PATCH_CONTAINS_BY_MANY_GRAPHS (in phrase varchar, in graph_iris any)
  14154. {
  14155. declare isfirst, gctr, gcount integer;
  14156. declare ses, graph_keyword any;
  14157. if (not sys_stat ('rdf_query_graph_keywords'))
  14158. return sprintf ('[__enc "UTF-8"] %s', phrase);
  14159. whenever sqlstate '*' goto err;
  14160. gcount := length (graph_iris);
  14161. ses := string_output ();
  14162. isfirst := 1;
  14163. for (gctr := 0; gctr < gcount; gctr := gctr + 1)
  14164. {
  14165. graph_keyword := iri_to_id (graph_iris[gctr], 0, 0);
  14166. if (not isinteger (graph_keyword))
  14167. {
  14168. if (isfirst)
  14169. {
  14170. http ('^', ses);
  14171. isfirst := 0;
  14172. }
  14173. else
  14174. http (' OR ^', ses);
  14175. http (WS.WS.STR_SQL_APOS (rdf_graph_keyword (graph_keyword)), ses);
  14176. }
  14177. }
  14178. if (not isfirst)
  14179. return sprintf ('[__enc "UTF-8"] (%s) AND (%s)', string_output_string (ses), phrase);
  14180. err:
  14181. return '^"#nosuch"';
  14182. }
  14183. ;
  14184. create procedure DB.DBA.RDF_OBJ_ADD_KEYWORD_FOR_GRAPH (in graph_iid IRI_ID, inout ro_id_dict any array, in daq any array := 0)
  14185. {
  14186. declare ro_id_offset, ro_ids_count integer;
  14187. declare new_ro_ids, vtb any;
  14188. declare gwordump varchar;
  14189. declare n_w, n_ins, n_upd, n_next integer;
  14190. if (not sys_stat ('rdf_create_graph_keywords'))
  14191. {
  14192. dict_zap (ro_id_dict, 2);
  14193. return;
  14194. }
  14195. next_batch:
  14196. new_ro_ids := dict_destructive_list_rnd_keys (ro_id_dict, 500000);
  14197. ro_ids_count := length (new_ro_ids);
  14198. if (0 = ro_ids_count)
  14199. return;
  14200. gwordump := ' ' || rdf_graph_keyword (graph_iid);
  14201. gwordump[0] := length (gwordump) - 1;
  14202. gvector_digit_sort (new_ro_ids, 1, 0, 1);
  14203. if (0 = sys_stat ('cl_run_local_only'))
  14204. {
  14205. commit work;
  14206. cl_g_words (new_ro_ids, gwordump, daq);
  14207. goto next_batch;
  14208. }
  14209. vtb := vt_batch (__min (__max (ro_ids_count, 31), 500000));
  14210. commit work;
  14211. whenever sqlstate '40001' goto retry_add;
  14212. again:
  14213. for (ro_id_offset := 0; ro_id_offset < ro_ids_count; ro_id_offset := ro_id_offset + 1)
  14214. {
  14215. vt_batch_d_id (vtb, new_ro_ids[ro_id_offset]);
  14216. vt_batch_feed_wordump (vtb, gwordump, 0);
  14217. }
  14218. if (0 = sys_stat ('cl_run_local_only'))
  14219. {
  14220. declare is_local_daq int;
  14221. if (0 = daq)
  14222. {
  14223. daq := daq (1);
  14224. is_local_daq := 1;
  14225. }
  14226. cl_g_text_index (vtb, daq);
  14227. if (is_local_daq)
  14228. {
  14229. while (daq_next (daq));
  14230. commit work;
  14231. goto next_batch;
  14232. }
  14233. }
  14234. else
  14235. "DB"."DBA"."VT_BATCH_PROCESS_DB_DBA_RDF_OBJ" (vtb, null);
  14236. commit work;
  14237. goto next_batch;
  14238. retry_add:
  14239. rollback work;
  14240. goto again;
  14241. }
  14242. ;
  14243. create procedure DB.DBA.RDF_OBJ_ADD_KEYWORD_FOR_GRAPH_OLD (in graph_iid IRI_ID, inout ro_id_dict any)
  14244. {
  14245. declare start_vt_d_id, aligned_start_vt_d_id, uncommited_ro_id_offset, ro_id_offset, ro_ids_count integer;
  14246. declare old_d_id, old_d_id_2, carry_d_id, carry_d_id_2 integer;
  14247. declare old_data, carry_data varchar;
  14248. declare split_ctr, split_len integer;
  14249. declare dbg_smallest_d_id, dbg_largest_d_id, dbg_prev_d_id, dbg_prev_d_id_2 integer;
  14250. declare split any;
  14251. declare cr cursor for (
  14252. select VT_D_ID, VT_D_ID_2, coalesce (VT_DATA, cast (VT_LONG_DATA as varchar)) from RDF_OBJ_RO_FLAGS_WORDS
  14253. where (VT_WORD = cast (graph_iid as varchar)) and (VT_D_ID >= aligned_start_vt_d_id) and VT_D_ID_2 >= start_vt_d_id for update);
  14254. declare new_ro_ids any;
  14255. -- dbg_obj_princ ('DB.DBA.RDF_OBJ_ADD_KEYWORD_FOR_GRAPH (', graph_iid, ro_id_dict, ')');
  14256. new_ro_ids := dict_list_keys (ro_id_dict, 2);
  14257. ro_ids_count := length (new_ro_ids);
  14258. if (0 = ro_ids_count)
  14259. return;
  14260. gvector_digit_sort (new_ro_ids, 1, 0, 1);
  14261. -- debug begin
  14262. dbg_smallest_d_id := new_ro_ids[0];
  14263. dbg_largest_d_id := new_ro_ids[length (new_ro_ids) - 1];
  14264. dbg_prev_d_id := 0;
  14265. dbg_prev_d_id_2 := 0;
  14266. -- debug end
  14267. commit work;
  14268. whenever sqlstate '40001' goto retry_add;
  14269. uncommited_ro_id_offset := 0;
  14270. again:
  14271. ro_id_offset := uncommited_ro_id_offset;
  14272. start_vt_d_id := new_ro_ids[ro_id_offset];
  14273. aligned_start_vt_d_id := ((start_vt_d_id / 10000) * 10000);
  14274. carry_d_id := 0;
  14275. carry_d_id_2 := 0;
  14276. carry_data := '';
  14277. set isolation = 'serializable';
  14278. whenever not found goto no_more_olds;
  14279. open cr (prefetch 1);
  14280. next_split:
  14281. fetch cr into old_d_id, old_d_id_2, old_data;
  14282. split := DB.DBA.VT_COMPOSE_KEYWORD_INDEX_LINES (carry_d_id, carry_d_id_2, carry_data, old_d_id, old_d_id_2, old_data, ro_id_offset, new_ro_ids);
  14283. split_len := length (split);
  14284. split_ctr := 0;
  14285. if ((split_len > 0) and (split[split_len-1][0] = old_d_id))
  14286. {
  14287. if ((old_d_id_2 = split[split_len-1][1]) and (old_data = split[split_len-1][2]))
  14288. { ; }
  14289. else
  14290. update RDF_OBJ_RO_FLAGS_WORDS set VT_D_ID_2 = split[split_len-1][1], VT_DATA = split[split_len-1][2], VT_LONG_DATA = null
  14291. where current of cr;
  14292. split_len := split_len - 1;
  14293. }
  14294. if (split_len > 0)
  14295. {
  14296. delete from RDF_OBJ_RO_FLAGS_WORDS
  14297. where (VT_WORD = cast (graph_iid as varchar)) and (VT_D_ID >= split[0][0]) and (VT_D_ID_2 <= split[split_len-1][1]);
  14298. }
  14299. for (split_ctr := 0; split_ctr < split_len; split_ctr := split_ctr+1)
  14300. {
  14301. insert replacing RDF_OBJ_RO_FLAGS_WORDS (VT_WORD, VT_D_ID, VT_D_ID_2, VT_DATA)
  14302. values (cast (graph_iid as varchar), split[split_ctr][0], split[split_ctr][1], split[split_ctr][2]);
  14303. }
  14304. if (carry_data = '')
  14305. {
  14306. commit work;
  14307. uncommited_ro_id_offset := ro_id_offset;
  14308. if (ro_id_offset >= ro_ids_count)
  14309. {
  14310. start_vt_d_id := 1024 * 65536 * 65536 * 65536; -- well, a big number
  14311. goto no_more_olds;
  14312. }
  14313. start_vt_d_id := new_ro_ids[uncommited_ro_id_offset];
  14314. aligned_start_vt_d_id := ((start_vt_d_id / 10000) * 10000);
  14315. close cr;
  14316. open cr (prefetch 1);
  14317. }
  14318. goto next_split;
  14319. no_more_olds:
  14320. split := DB.DBA.VT_COMPOSE_KEYWORD_INDEX_LINES (carry_d_id, carry_d_id_2, carry_data, null, null, null, ro_id_offset, new_ro_ids);
  14321. split_len := length (split);
  14322. split_ctr := 0;
  14323. if (split_len > 0)
  14324. {
  14325. delete from RDF_OBJ_RO_FLAGS_WORDS
  14326. where (VT_WORD = cast (graph_iid as varchar)) and (VT_D_ID >= split[0][0]) and (VT_D_ID_2 <= split[split_len-1][1]);
  14327. }
  14328. for (split_ctr := 0; split_ctr < split_len; split_ctr := split_ctr+1)
  14329. {
  14330. insert replacing RDF_OBJ_RO_FLAGS_WORDS (VT_WORD, VT_D_ID, VT_D_ID_2, VT_DATA)
  14331. values (cast (graph_iid as varchar), split[split_ctr][0], split[split_ctr][1], split[split_ctr][2]);
  14332. }
  14333. if (length (carry_data) <> 0)
  14334. {
  14335. insert replacing RDF_OBJ_RO_FLAGS_WORDS (VT_WORD, VT_D_ID, VT_D_ID_2, VT_DATA)
  14336. values (cast (graph_iid as varchar), carry_d_id, carry_d_id_2, carry_data);
  14337. }
  14338. commit work;
  14339. -- debug begin
  14340. -- for (
  14341. -- select VT_WORD, VT_D_ID, VT_D_ID_2, coalesce (VT_DATA, cast (VT_LONG_DATA as varchar)) as vtd from RDF_OBJ_RO_FLAGS_WORDS
  14342. -- where (VT_WORD = cast (graph_iid as varchar))
  14343. -- and (VT_D_ID >= ((dbg_smallest_d_id / 10000) * 10000))
  14344. -- and (VT_D_ID_2 >= (((dbg_largest_d_id + 9999) / 10000) * 10000)) ) do
  14345. -- {
  14346. -- if (VT_D_ID > VT_D_ID_2)
  14347. -- {
  14348. -- -- dbg_obj_princ ('FT BUG: misordered bounds: ', VT_WORD, VT_D_ID, VT_D_ID_2);
  14349. -- raw_exit ();
  14350. -- ;
  14351. -- }
  14352. -- if (VT_D_ID <= dbg_prev_d_id_2)
  14353. -- {
  14354. -- -- dbg_obj_princ ('FT BUG: overlapping ranges: ', VT_WORD, VT_D_ID, VT_D_ID_2, '; prev is ', dbg_prev_d_id, dbg_prev_d_id_2);
  14355. -- raw_exit ();
  14356. -- ;
  14357. -- }
  14358. -- }
  14359. return;
  14360. retry_add:
  14361. close cr;
  14362. rollback work;
  14363. goto again;
  14364. }
  14365. ;
  14366. create procedure DB.DBA.RDF_OBJ_FT_INS_ALL (in this_box_only integer := 0)
  14367. {
  14368. declare id, f integer;
  14369. if (not this_box_only)
  14370. {
  14371. cl_exec ('DB.DBA.RDF_OBJ_FT_INS_ALL (1)');
  14372. return;
  14373. }
  14374. set triggers off;
  14375. declare c1 cursor for select RO_ID, RO_FLAGS from DB.DBA.RDF_OBJ where not (bit_and (RO_FLAGS, 1)) and RO_VAL > '' and RO_VAL < '\xFF\xFF\xFF\xFF\xFF\xFF' and isstring (RO_VAL) and RO_LONG is null for update option (no cluster);
  14376. start_c1:
  14377. open c1;
  14378. whenever sqlstate '42000' goto deadl_c1;
  14379. whenever not found goto done_c1;
  14380. again_c1:
  14381. fetch c1 into id, f;
  14382. update DB.DBA.RDF_OBJ set RO_FLAGS = bit_or (RO_FLAGS, 1) where current of c1;
  14383. insert into VTLOG_DB_DBA_RDF_OBJ option (no cluster) (VTLOG_RO_ID, SNAPTIME, DMLTYPE) values (id, curdatetime (), 'I');
  14384. commit work;
  14385. goto again_c1;
  14386. done_c1:
  14387. close c1;
  14388. declare c2 cursor for select RO_ID, RO_FLAGS from DB.DBA.RDF_OBJ where not (bit_and (RO_FLAGS, 1)) and RO_LONG is not NULL for update option (no cluster);
  14389. start_c2:
  14390. open c2;
  14391. whenever sqlstate '42000' goto deadl_c2;
  14392. whenever not found goto done_c2;
  14393. again_c2:
  14394. fetch c2 into id, f;
  14395. update DB.DBA.RDF_OBJ set RO_FLAGS = bit_or (RO_FLAGS, 1) where current of c2;
  14396. insert into VTLOG_DB_DBA_RDF_OBJ option (no cluster) (VTLOG_RO_ID, SNAPTIME, DMLTYPE) values (id, curdatetime (), 'I');
  14397. commit work;
  14398. goto again_c2;
  14399. done_c2:
  14400. close c2;
  14401. start_g:
  14402. whenever sqlstate '42000' goto deadl_g;
  14403. for (select distinct G as curr_g FROm DB.DBA.RDF_QUAD table option (index RDF_QUAD_GS, index_only) option (no cluster)) do
  14404. {
  14405. declare ro_id_dict any;
  14406. ro_id_dict := dict_new (100000);
  14407. for (select distinct rdf_box_ro_id (O) as o_id from DB.DBA.RDF_QUAD join DB.DBA.RDF_OBJ on (RO_ID = rdf_box_ro_id (O))
  14408. where G = curr_g
  14409. and 0 = bit_and (RO_FLAGS, 1) and __tag (coalesce (RO_LONG, RO_VAL)) in (__tag of varchar, __tag of XML) ) do
  14410. {
  14411. update DB.DBA.RDF_OBJ set RO_FLAGS = bit_or (RO_FLAGS, 1) where RO_ID = o_id;
  14412. insert soft DB.DBA.VTLOG_DB_DBA_RDF_OBJ option (no cluster) (VTLOG_RO_ID, SNAPTIME, DMLTYPE) values (o_id, curdatetime (), 'I');
  14413. --insert soft rdf_ft (rf_id, rf_o) values (id, obj);
  14414. dict_put (ro_id_dict, o_id, 1);
  14415. commit work;
  14416. if (dict_size (ro_id_dict) > 100000)
  14417. DB.DBA.RDF_OBJ_ADD_KEYWORD_FOR_GRAPH (curr_g, ro_id_dict);
  14418. }
  14419. DB.DBA.RDF_OBJ_ADD_KEYWORD_FOR_GRAPH (curr_g, ro_id_dict);
  14420. commit work;
  14421. }
  14422. return;
  14423. deadl_c1:
  14424. rollback work;
  14425. close c1;
  14426. goto start_c1;
  14427. deadl_c2:
  14428. rollback work;
  14429. close c2;
  14430. goto start_c2;
  14431. deadl_g:
  14432. rollback work;
  14433. goto start_g;
  14434. }
  14435. ;
  14436. create function DB.DBA.RDF_OBJ_FT_RULE_ADD (in rule_g varchar, in rule_p varchar, in reason varchar) returns integer
  14437. {
  14438. declare rule_g_iid, rule_p_iid IRI_ID;
  14439. declare ro_id_dict any;
  14440. if (0 = sys_stat ('cl_run_local_only'))
  14441. signal ('42000', 'DB.DBA.RDF_OBJ_FT_RULE_ADD() is not available in cluster. Do DB.DBA.CL_TEXT_INDEX (1) to enable text index on all future RDF loads on cluster.');
  14442. set triggers off;
  14443. if (rule_g is null)
  14444. rule_g := '';
  14445. if (rule_p is null)
  14446. rule_p := '';
  14447. rule_g_iid := case (rule_g) when '' then null else iri_to_id (rule_g) end;
  14448. rule_p_iid := case (rule_p) when '' then null else iri_to_id (rule_p) end;
  14449. if (reason is null)
  14450. signal ('RDFXX', 'DB.DBA.RDF_OBJ_FT_RULE_ADD() expects string as argument 3');
  14451. if (exists (
  14452. select top 1 1 from DB.DBA.RDF_OBJ_FT_RULES
  14453. where ROFR_G = rule_g and ROFR_P = rule_p and ROFR_REASON = reason))
  14454. return 0;
  14455. if (not exists (
  14456. select top 1 1 from DB.DBA.RDF_OBJ_FT_RULES
  14457. where (ROFR_G = rule_g or ROFR_G = '') and (ROFR_P = rule_p or ROFR_P = '') ) )
  14458. {
  14459. -- dbg_obj_princ ('DB.DBA.RDF_OBJ_FT_RULE_ADD: need scan');
  14460. commit work;
  14461. exec ('checkpoint');
  14462. __atomic (1);
  14463. declare exit handler for sqlstate '*' {
  14464. __atomic (0);
  14465. signal (__SQL_STATE, __SQL_MESSAGE); };
  14466. if ((rule_g <> '') and (rule_p <> ''))
  14467. {
  14468. ro_id_dict := dict_new (100000);
  14469. for (select distinct rdf_box_ro_id (O) as id from DB.DBA.RDF_QUAD join DB.DBA.RDF_OBJ on (RO_ID = rdf_box_ro_id (O))
  14470. where G=rule_g_iid and P=rule_p_iid
  14471. and 0 = bit_and (RO_FLAGS, 1) and __tag(coalesce (RO_LONG, RO_VAL)) in (__tag of varchar, __tag of XML) ) do
  14472. {
  14473. update DB.DBA.RDF_OBJ set RO_FLAGS = bit_or (RO_FLAGS, 1) where RO_ID = id;
  14474. insert soft DB.DBA.VTLOG_DB_DBA_RDF_OBJ option (no cluster) (VTLOG_RO_ID, SNAPTIME, DMLTYPE) values (id, curdatetime (), 'I');
  14475. --insert soft rdf_ft (rf_id, rf_o) values (id, obj);
  14476. dict_put (ro_id_dict, id, 1);
  14477. commit work;
  14478. if (dict_size (ro_id_dict) > 100000)
  14479. DB.DBA.RDF_OBJ_ADD_KEYWORD_FOR_GRAPH (rule_g_iid, ro_id_dict);
  14480. }
  14481. DB.DBA.RDF_OBJ_ADD_KEYWORD_FOR_GRAPH (rule_g_iid, ro_id_dict);
  14482. }
  14483. else if (rule_g <> '')
  14484. {
  14485. ro_id_dict := dict_new (100000);
  14486. for (select distinct rdf_box_ro_id (O) as id from DB.DBA.RDF_QUAD join DB.DBA.RDF_OBJ on (RO_ID = rdf_box_ro_id (O))
  14487. where G=rule_g_iid
  14488. and 0 = bit_and (RO_FLAGS, 1) and __tag(coalesce (RO_LONG, RO_VAL)) in (__tag of varchar, __tag of XML) ) do
  14489. {
  14490. update DB.DBA.RDF_OBJ set RO_FLAGS = bit_or (RO_FLAGS, 1) where RO_ID = id;
  14491. insert soft DB.DBA.VTLOG_DB_DBA_RDF_OBJ option (no cluster) (VTLOG_RO_ID, SNAPTIME, DMLTYPE) values (id, curdatetime (), 'I');
  14492. --insert soft rdf_ft (rf_id, rf_o) values (id, obj);
  14493. dict_put (ro_id_dict, id, 1);
  14494. commit work;
  14495. if (dict_size (ro_id_dict) > 100000)
  14496. DB.DBA.RDF_OBJ_ADD_KEYWORD_FOR_GRAPH (rule_g_iid, ro_id_dict);
  14497. }
  14498. DB.DBA.RDF_OBJ_ADD_KEYWORD_FOR_GRAPH (rule_g_iid, ro_id_dict);
  14499. }
  14500. else if (rule_p <> '')
  14501. {
  14502. declare old_g IRI_ID;
  14503. old_g := #i0;
  14504. ro_id_dict := dict_new (100000);
  14505. for (select G as curr_g, S as curr_s from DB.DBA.RDF_QUAD table option (index RDF_QUAD_GS, index_only)) do
  14506. {
  14507. for (select distinct rdf_box_ro_id (O) as id from DB.DBA.RDF_QUAD join DB.DBA.RDF_OBJ on (RO_ID = rdf_box_ro_id (O))
  14508. where G = curr_g and P = rule_p_iid
  14509. and 0 = bit_and (RO_FLAGS, 1) and __tag(coalesce (RO_LONG, RO_VAL)) in (__tag of varchar, __tag of XML) ) do
  14510. {
  14511. if (curr_g <> old_g)
  14512. {
  14513. DB.DBA.RDF_OBJ_ADD_KEYWORD_FOR_GRAPH (old_g, ro_id_dict);
  14514. old_g := curr_g;
  14515. }
  14516. update DB.DBA.RDF_OBJ set RO_FLAGS = bit_or (RO_FLAGS, 1) where RO_ID = id;
  14517. insert soft DB.DBA.VTLOG_DB_DBA_RDF_OBJ option (no cluster) (VTLOG_RO_ID, SNAPTIME, DMLTYPE) values (id, curdatetime (), 'I');
  14518. --insert soft rdf_ft (rf_id, rf_o) values (id, obj);
  14519. dict_put (ro_id_dict, id, 1);
  14520. commit work;
  14521. if (dict_size (ro_id_dict) > 100000)
  14522. DB.DBA.RDF_OBJ_ADD_KEYWORD_FOR_GRAPH (curr_g, ro_id_dict);
  14523. }
  14524. }
  14525. DB.DBA.RDF_OBJ_ADD_KEYWORD_FOR_GRAPH (old_g, ro_id_dict);
  14526. commit work;
  14527. }
  14528. else
  14529. DB.DBA.RDF_OBJ_FT_INS_ALL ();
  14530. __atomic (0);
  14531. exec ('checkpoint');
  14532. }
  14533. insert into DB.DBA.RDF_OBJ_FT_RULES (ROFR_G, ROFR_P, ROFR_REASON) values (rule_g, rule_p, reason);
  14534. commit work;
  14535. __rdf_obj_ft_rule_add (rule_g_iid, rule_p_iid, reason);
  14536. return 1;
  14537. }
  14538. ;
  14539. create function DB.DBA.RDF_OBJ_FT_RULE_DEL (in rule_g varchar, in rule_p varchar, in reason varchar) returns integer
  14540. {
  14541. declare rule_g_iid, rule_p_iid IRI_ID;
  14542. if (rule_g is null)
  14543. rule_g := '';
  14544. if (rule_p is null)
  14545. rule_p := '';
  14546. rule_g_iid := case (rule_g) when '' then null else iri_to_id (rule_g) end;
  14547. rule_p_iid := case (rule_p) when '' then null else iri_to_id (rule_p) end;
  14548. if (reason is null)
  14549. signal ('RDFXX', 'DB.DBA.RDF_OBJ_FT_RULE_DEL() expects string as argument 3');
  14550. if (not exists (
  14551. select top 1 1 from DB.DBA.RDF_OBJ_FT_RULES
  14552. where ROFR_G = rule_g and ROFR_P = rule_p and ROFR_REASON = reason))
  14553. return 0;
  14554. delete from DB.DBA.RDF_OBJ_FT_RULES where ROFR_G = rule_g and ROFR_P = rule_p and ROFR_REASON = reason;
  14555. commit work;
  14556. __rdf_obj_ft_rule_del (rule_g_iid, rule_p_iid, reason);
  14557. return 1;
  14558. }
  14559. ;
  14560. create procedure DB.DBA.RDF_OBJ_FT_RECOVER ()
  14561. {
  14562. declare stat, msg, STRG varchar;
  14563. declare metas, rset any;
  14564. result_names (STRG);
  14565. if (((0 = sys_stat ('cl_run_local_only')) and (1 = cast (registry_get ('cl_rdf_text_index') as integer)))
  14566. or exists (select 1 from DB.DBA.RDF_OBJ_FT_RULES where ROFR_G = '' and ROFR_P = '') )
  14567. {
  14568. result ('One of rules requires total indexing, so the rest of rules will not require any selective processing...');
  14569. DB.DBA.RDF_OBJ_FT_INS_ALL ();
  14570. }
  14571. else
  14572. {
  14573. exec ('
  14574. select ROFR_G, ROFR_P, MAX (ROFR_REASON), COUNT (1), MIN (ROFR_REASON)
  14575. from DB.DBA.RDF_OBJ_FT_RULES
  14576. group by ROFR_G, ROFR_P
  14577. order by (1024 * length (ROFR_G) + 1024 * length (ROFR_P))',
  14578. stat, msg, vector (), 100000, metas, rset);
  14579. foreach (any ftrule in rset) do
  14580. {
  14581. result (sprintf ('Temporary drop of rule "%s" for graph <%s> predicate <%s>...', ftrule[2], ftrule[0], ftrule[1]));
  14582. { whenever sqlstate '*' goto add_back;
  14583. DB.DBA.RDF_OBJ_FT_RULE_DEL (ftrule[0], ftrule[1], ftrule[2]);
  14584. result ('... done'); }
  14585. add_back:
  14586. result (sprintf ('Restoring rule "%s" for graph <%s> predicate <%s>...', ftrule[2], ftrule[0], ftrule[1]));
  14587. { whenever sqlstate '*' goto restored;
  14588. DB.DBA.RDF_OBJ_FT_RULE_ADD (ftrule[0], ftrule[1], ftrule[2]);
  14589. result ('... done'); }
  14590. restored:
  14591. if (ftrule[3] > 1)
  14592. result (sprintf ('No need to re-apply additional %d rules for this graph and predicate, e.g., rule "%s"', ftrule[4]));
  14593. }
  14594. }
  14595. result ('Now starting incremental update of free-text index...');
  14596. VT_INC_INDEX_DB_DBA_RDF_OBJ();
  14597. result ('... done');
  14598. }
  14599. ;
  14600. -----
  14601. -- Security
  14602. create table DB.DBA.RDF_GRAPH_GROUP (
  14603. RGG_IID IRI_ID not null primary key,
  14604. RGG_IRI varchar not null,
  14605. RGG_MEMBER_PATTERN varchar,
  14606. RGG_COMMENT varchar
  14607. )
  14608. alter index RDF_GRAPH_GROUP on DB.DBA.RDF_GRAPH_GROUP partition cluster replicated
  14609. create index RDF_GRAPH_GROUP_IRI on DB.DBA.RDF_GRAPH_GROUP (RGG_IRI) partition cluster replicated
  14610. ;
  14611. create table DB.DBA.RDF_GRAPH_GROUP_MEMBER (
  14612. RGGM_GROUP_IID IRI_ID not null,
  14613. RGGM_MEMBER_IID IRI_ID not null,
  14614. primary key (RGGM_GROUP_IID, RGGM_MEMBER_IID)
  14615. )
  14616. alter index RDF_GRAPH_GROUP_MEMBER on DB.DBA.RDF_GRAPH_GROUP_MEMBER partition cluster replicated
  14617. ;
  14618. create table DB.DBA.RDF_GRAPH_USER (
  14619. RGU_GRAPH_IID IRI_ID not null,
  14620. RGU_USER_ID integer not null,
  14621. RGU_PERMISSIONS integer not null, -- 1 for read, 2 for write, 4 for sponge, 8 for list, 16 for admin, 256 for owner.
  14622. primary key (RGU_GRAPH_IID, RGU_USER_ID)
  14623. )
  14624. alter index RDF_GRAPH_USER on DB.DBA.RDF_GRAPH_USER partition cluster replicated
  14625. create index RDF_GRAPH_USER_USER_ID on DB.DBA.RDF_GRAPH_USER (RGU_USER_ID, RGU_GRAPH_IID, RGU_PERMISSIONS) partition cluster replicated
  14626. ;
  14627. create procedure DB.DBA.RDF_GRAPH_CACHE_IID (in iid IRI_ID)
  14628. {
  14629. declare iri any;
  14630. iri := __uname (id_to_canonicalized_iri (iid));
  14631. dict_put (__rdf_graph_iri2id_dict(), iri, iid);
  14632. dict_put (__rdf_graph_id2iri_dict(), iid, iri);
  14633. }
  14634. ;
  14635. create procedure DB.DBA.RDF_GRAPH_GROUP_CREATE_MEMONLY (in group_iri varchar, in group_iid IRI_ID)
  14636. {
  14637. group_iri := cast (group_iri as varchar);
  14638. DB.DBA.RDF_GRAPH_CACHE_IID (group_iid);
  14639. dict_put (__rdf_graph_group_dict(), group_iid, vector ());
  14640. jso_mark_affected (group_iri);
  14641. log_text ('jso_mark_affected (?)', group_iri);
  14642. __rdf_cli_mark_qr_to_recompile ();
  14643. }
  14644. ;
  14645. create function DB.DBA.RDF_GRAPH_GROUP_IRI_CHECK (in group_iri varchar, in fname varchar) returns IRI_ID
  14646. {
  14647. declare group_iid IRI_ID;
  14648. group_iri := cast (group_iri as varchar);
  14649. group_iid := iri_to_id (group_iri);
  14650. if (group_iri <> id_to_canonicalized_iri (group_iid))
  14651. signal ('RDF99', sprintf ('Group IRI should be canonical, but the specified group IRI <%s> differs from its canonical form <%s>', group_iri, id_to_canonicalized_iri (group_iid)));
  14652. for (select RGG_IID from DB.DBA.RDF_GRAPH_GROUP where RGG_IRI = group_iri) do
  14653. {
  14654. if (RGG_IID = group_iid)
  14655. return RGG_IID;
  14656. if (not exists (select top 1 1 from DB.DBA.RDF_GRAPH_GROUP where RGG_IID = group_iid))
  14657. signal ('RDF99', sprintf ('Integrity violation in DB.DBA.RDF_GRAPH_GROUP table (found group IRI <%s>, not found group IRI ID %s)', group_iri, cast (group_iid as varchar)));
  14658. }
  14659. for (select RGG_IRI from DB.DBA.RDF_GRAPH_GROUP where RGG_IID = group_iid) do
  14660. {
  14661. if (RGG_IRI = id_to_canonicalized_iri (group_iid))
  14662. signal ('RDF99', sprintf ('Table DB.DBA.RDF_GRAPH_GROUP contains group with IRI <%s>, not IRI <%s>, for group IRI ID %s', RGG_IRI, group_iri, cast (group_iid as varchar)));
  14663. signal ('RDF99', sprintf ('Integrity violation in DB.DBA.RDF_GRAPH_GROUP table (not found group IRI <%s>, found group IRI ID %s)', group_iri, cast (group_iid as varchar)));
  14664. }
  14665. return NULL;
  14666. }
  14667. ;
  14668. create procedure DB.DBA.RDF_GRAPH_GROUP_CREATE (in group_iri varchar, in quiet integer, in member_pattern varchar := null, in comment varchar := null)
  14669. {
  14670. declare group_iid IRI_ID;
  14671. group_iri := cast (group_iri as varchar);
  14672. group_iid := iri_to_id (group_iri);
  14673. DB.DBA.RDF_GRAPH_GROUP_IRI_CHECK (group_iri, 'DB.DBA.RDF_GRAPH_GROUP_CREATE');
  14674. if (exists (select top 1 1 from DB.DBA.RDF_GRAPH_GROUP where RGG_IRI = group_iri))
  14675. {
  14676. if (quiet)
  14677. return;
  14678. signal ('RDF99', sprintf ('The graph group <%s> already exists (%s)', group_iri, coalesce (
  14679. (select top 1 RGG_COMMENT from DB.DBA.RDF_GRAPH_GROUP where RGG_IRI = group_iri), 'group has no comment' ) ) );
  14680. }
  14681. insert into DB.DBA.RDF_GRAPH_GROUP (
  14682. RGG_IID, RGG_IRI, RGG_MEMBER_PATTERN, RGG_COMMENT )
  14683. values (group_iid, group_iri, member_pattern, comment);
  14684. commit work;
  14685. DB.DBA.SECURITY_CL_EXEC_AND_LOG ('DB.DBA.RDF_GRAPH_GROUP_CREATE_MEMONLY (?, ?)', vector (group_iri, group_iid));
  14686. }
  14687. ;
  14688. create procedure DB.DBA.RDF_GRAPH_GROUP_DROP_MEMONLY (in group_iri varchar, in group_iid IRI_ID)
  14689. {
  14690. group_iri := cast (group_iri as varchar);
  14691. DB.DBA.RDF_GRAPH_CACHE_IID (group_iid);
  14692. dict_put (__rdf_graph_group_dict(), group_iid, vector ());
  14693. dict_remove (__rdf_graph_group_dict(), group_iid);
  14694. jso_mark_affected (group_iri);
  14695. log_text ('jso_mark_affected (?)', group_iri);
  14696. if (group_iri = 'http://www.openlinksw.com/schemas/virtrdf#PrivateGraphs')
  14697. {
  14698. declare privates any;
  14699. privates := dict_list_keys (__rdf_graph_group_of_privates_dict(), 2);
  14700. foreach (IRI_ID iid in privates) do
  14701. {
  14702. jso_mark_affected (id_to_iri (iid));
  14703. log_text ('jso_mark_affected (?)', id_to_iri (iid));
  14704. }
  14705. }
  14706. __rdf_cli_mark_qr_to_recompile ();
  14707. }
  14708. ;
  14709. create procedure DB.DBA.RDF_GRAPH_GROUP_DROP (in group_iri varchar, in quiet integer)
  14710. {
  14711. declare group_iid IRI_ID;
  14712. group_iri := cast (group_iri as varchar);
  14713. group_iid := iri_to_id (group_iri);
  14714. DB.DBA.RDF_GRAPH_GROUP_IRI_CHECK (group_iri, 'DB.DBA.RDF_GRAPH_GROUP_DROP');
  14715. if (not exists (select top 1 1 from DB.DBA.RDF_GRAPH_GROUP where RGG_IRI = group_iri))
  14716. {
  14717. if (quiet)
  14718. return;
  14719. signal ('RDF99', sprintf ('The graph group <%s> does not exist (%s)', group_iri, coalesce (
  14720. (select top 1 RGG_COMMENT from DB.DBA.RDF_GRAPH_GROUP where RGG_IRI = group_iri), 'group has no comment' ) ) );
  14721. }
  14722. if (group_iri = 'http://www.openlinksw.com/schemas/virtrdf#PrivateGraphs')
  14723. signal ('RDF99', sprintf ('The graph group <%s> is a special one and used to control security, can not drop it' ) );
  14724. delete from DB.DBA.RDF_GRAPH_GROUP_MEMBER where RGGM_GROUP_IID = group_iid;
  14725. delete from DB.DBA.RDF_GRAPH_GROUP where RGG_IID = group_iid;
  14726. commit work;
  14727. DB.DBA.SECURITY_CL_EXEC_AND_LOG ('DB.DBA.RDF_GRAPH_GROUP_DROP_MEMONLY (?, ?)', vector (group_iri, group_iid));
  14728. }
  14729. ;
  14730. create procedure DB.DBA.RDF_GRAPH_CHECK_VISIBILITY_CHANGE (in memb_iri varchar, in special_iid IRI_ID)
  14731. {
  14732. declare memb_iid IRI_ID;
  14733. memb_iid := iri_to_id (memb_iri);
  14734. declare new_default_perms integer;
  14735. new_default_perms := (select RGU_PERMISSIONS from DB.DBA.RDF_GRAPH_USER where RGU_GRAPH_IID = special_iid and RGU_USER_ID = http_nobody_uid());
  14736. for (select g.RGU_PERMISSIONS as g_perms, s.RGU_PERMISSIONS as s_perms, g.RGU_USER_ID as uid
  14737. from DB.DBA.RDF_GRAPH_USER as g left outer join DB.DBA.RDF_GRAPH_USER as s on (g.RGU_USER_ID = s.RGU_USER_ID and s.RGU_GRAPH_IID = special_iid)
  14738. where g.RGU_GRAPH_IID = memb_iid ) do
  14739. {
  14740. if (s_perms is not null and bit_and (s_perms, bit_not (g_perms)))
  14741. signal ('RDF99', sprintf ('Default %s permissions of user "%s" (UID %d) on RDF store can not be broader than permissions on specific graph <%s> so the graph can not be %s now',
  14742. case (equ (special_iid, #i8192)) when 0 then '"world"' else '"private area"' end,
  14743. (select U_NAME from DB.DBA.SYS_USERS where U_ID = uid),
  14744. uid,
  14745. memb_iri,
  14746. case (equ (special_iid, #i8192)) when 0 then 'removed from the "private area"' else 'added to the "private area"' end ) );
  14747. if (new_default_perms is not null and bit_and (new_default_perms, bit_not (g_perms)))
  14748. signal ('RDF99', sprintf ('Default %s permissions of unauthenticated user on RDF store can not be broader than permissions of user "%s" (UID %d) on specific graph <%s> so the graph can not be %s now',
  14749. case (equ (special_iid, #i8192)) when 0 then '"world"' else '"private area"' end,
  14750. (select U_NAME from DB.DBA.SYS_USERS where U_ID = uid),
  14751. uid,
  14752. memb_iri,
  14753. case (equ (special_iid, #i8192)) when 0 then 'removed from the "private area"' else 'added to the "private area"' end ) );
  14754. }
  14755. }
  14756. ;
  14757. create procedure DB.DBA.RDF_GRAPH_GROUP_INS_MEMONLY (in group_iri varchar, in group_iid IRI_ID, in memb_iri varchar, in memb_iid IRI_ID)
  14758. {
  14759. declare membs any;
  14760. group_iri := cast (group_iri as varchar);
  14761. memb_iri := cast (memb_iri as varchar);
  14762. DB.DBA.RDF_GRAPH_CACHE_IID (group_iid);
  14763. DB.DBA.RDF_GRAPH_CACHE_IID (memb_iid);
  14764. -- This is not scalable enough for big groups: N*N/2 time to create a group of size N.
  14765. -- dict_put (__rdf_graph_group_dict(), group_iid,
  14766. -- (select VECTOR_AGG (RGGM_MEMBER_IID) from DB.DBA.RDF_GRAPH_GROUP_MEMBER
  14767. -- where RGGM_GROUP_IID = group_iid
  14768. -- order by RGGM_MEMBER_IID ) );
  14769. membs := dict_get (__rdf_graph_group_dict(), group_iid, null);
  14770. if (membs is null)
  14771. dict_put (__rdf_graph_group_dict(), group_iid, vector (memb_iid));
  14772. else if (isvector (membs))
  14773. {
  14774. if (0 >= position (memb_iid, membs))
  14775. {
  14776. if (length (membs) < 1000)
  14777. dict_put (__rdf_graph_group_dict(), group_iid, vector_concat (membs, vector (memb_iid)));
  14778. else
  14779. {
  14780. declare new_membs any;
  14781. new_membs := dict_new (1000);
  14782. foreach (IRI_ID m in membs) do dict_put (new_membs, m, 1);
  14783. dict_put (new_membs, memb_iid, 1);
  14784. dict_put (__rdf_graph_group_dict(), group_iid, new_membs);
  14785. }
  14786. }
  14787. }
  14788. else
  14789. {
  14790. dict_put (membs, memb_iid, 1);
  14791. dict_put (__rdf_graph_group_dict(), group_iid, membs);
  14792. }
  14793. jso_mark_affected (group_iri);
  14794. log_text ('jso_mark_affected (?)', group_iri);
  14795. if (group_iri = 'http://www.openlinksw.com/schemas/virtrdf#PrivateGraphs')
  14796. {
  14797. dict_put (__rdf_graph_group_of_privates_dict(), memb_iid, 1);
  14798. jso_mark_affected (memb_iri);
  14799. log_text ('jso_mark_affected (?)', memb_iri);
  14800. }
  14801. }
  14802. ;
  14803. create procedure DB.DBA.RDF_GRAPH_GROUP_INS (in group_iri varchar, in memb_iri varchar)
  14804. {
  14805. declare group_iid, memb_iid IRI_ID;
  14806. group_iri := cast (group_iri as varchar);
  14807. DB.DBA.RDF_GRAPH_GROUP_IRI_CHECK (group_iri, 'DB.DBA.RDF_GRAPH_GROUP_INS');
  14808. memb_iri := cast (memb_iri as varchar);
  14809. group_iid := iri_to_id (group_iri);
  14810. memb_iid := iri_to_id (memb_iri);
  14811. set isolation = 'serializable';
  14812. commit work;
  14813. if (not exists (select top 1 1 from DB.DBA.RDF_GRAPH_GROUP where RGG_IRI = group_iri))
  14814. signal ('RDF99', sprintf ('Graph group <%s> does not exist', group_iri));
  14815. if (group_iri = 'http://www.openlinksw.com/schemas/virtrdf#PrivateGraphs')
  14816. {
  14817. DB.DBA.RDF_GRAPH_CHECK_VISIBILITY_CHANGE (memb_iri, #i8192);
  14818. if (isstring (registry_get ('DB.DBA.RDF_REPL'))
  14819. and exists (select top 1 1 from DB.DBA.RDF_GRAPH_GROUP_MEMBER
  14820. where RGGM_GROUP_IID = iri_to_id (UNAME'http://www.openlinksw.com/schemas/virtrdf#rdf_repl_graph_group') and RGGM_MEMBER_IID = memb_iid)
  14821. and not exists (select RGU_PERMISSIONS from DB.DBA.RDF_GRAPH_USER
  14822. where RGU_GRAPH_IID = memb_iid and RGU_USER_ID = http_nobody_uid() and bit_and (RGU_PERMISSIONS, 1) )
  14823. and not exists (select RGU_PERMISSIONS from DB.DBA.RDF_GRAPH_USER
  14824. where RGU_GRAPH_IID = #i8192 and RGU_USER_ID = http_nobody_uid() and bit_and (RGU_PERMISSIONS, 1) )
  14825. and not exists (select RGU_PERMISSIONS from DB.DBA.RDF_GRAPH_USER
  14826. where RGU_GRAPH_IID = memb_iid and RGU_USER_ID = __rdf_repl_uid() and bit_and (RGU_PERMISSIONS, 1) )
  14827. and not exists (select RGU_PERMISSIONS from DB.DBA.RDF_GRAPH_USER
  14828. where RGU_GRAPH_IID = #i8192 and RGU_USER_ID = __rdf_repl_uid() and bit_and (RGU_PERMISSIONS, 1) ) )
  14829. signal ('RDF99', 'Can not add graph <' || memb_iri || '> to group of private graphs <' || group_iri || '>; either stop the RDF replication of this graph or grant an explicit read permission to __rdf_repl account');
  14830. }
  14831. else if (group_iri = 'http://www.openlinksw.com/schemas/virtrdf#rdf_repl_graph_group')
  14832. {
  14833. if (memb_iri = DB.DBA.JSO_SYS_GRAPH())
  14834. signal ('RDF99', 'Graph group <' || group_iri || '> is for RDF replication; can not enable RDF replication of <' || memb_iri || '> (the system metadata graph)');
  14835. if (isstring (registry_get ('DB.DBA.RDF_REPL')) and not __rgs_ack_cbk (memb_iid, __rdf_repl_uid(), 1))
  14836. signal ('RDF99', 'Graph group <' || group_iri || '> is for RDF replication; can not enable RDF replication of graph <' || memb_iri || '> because it is not readable by __rdf_repl account');
  14837. }
  14838. insert soft DB.DBA.RDF_GRAPH_GROUP_MEMBER (RGGM_GROUP_IID, RGGM_MEMBER_IID)
  14839. values (group_iid, memb_iid);
  14840. commit work;
  14841. DB.DBA.SECURITY_CL_EXEC_AND_LOG ('DB.DBA.RDF_GRAPH_GROUP_INS_MEMONLY (?, ?, ?, ?)', vector (group_iri, group_iid, memb_iri, memb_iid));
  14842. }
  14843. ;
  14844. create procedure DB.DBA.RDF_GRAPH_GROUP_DEL_MEMONLY (in group_iri varchar, in group_iid IRI_ID, in memb_iri varchar, in memb_iid IRI_ID)
  14845. {
  14846. declare membs any;
  14847. group_iri := cast (group_iri as varchar);
  14848. memb_iri := cast (memb_iri as varchar);
  14849. DB.DBA.RDF_GRAPH_CACHE_IID (group_iid);
  14850. DB.DBA.RDF_GRAPH_CACHE_IID (memb_iid);
  14851. -- This is not scalable enough for big groups: N*N/2 time to drop a group of size N item by item.
  14852. -- dict_put (__rdf_graph_group_dict(), group_iid,
  14853. -- (select VECTOR_AGG (RGGM_MEMBER_IID) from DB.DBA.RDF_GRAPH_GROUP_MEMBER
  14854. -- where RGGM_GROUP_IID = group_iid
  14855. -- order by RGGM_MEMBER_IID ) );
  14856. membs := dict_get (__rdf_graph_group_dict(), group_iid, null);
  14857. if (membs is null)
  14858. dict_put (__rdf_graph_group_dict(), group_iid, vector ());
  14859. else if (isvector (membs))
  14860. {
  14861. declare p integer;
  14862. again:
  14863. p := position (memb_iid, membs);
  14864. if (p > 0)
  14865. {
  14866. membs := vector_concat (subseq (membs, 0, p-1), subseq (membs, p));
  14867. goto again; -- Paranoidal check for multiple occurencies of memb_iid in the graph group
  14868. }
  14869. dict_put (__rdf_graph_group_dict(), group_iid, membs);
  14870. }
  14871. else
  14872. {
  14873. dict_remove (membs, memb_iid);
  14874. dict_put (__rdf_graph_group_dict(), group_iid, membs);
  14875. }
  14876. jso_mark_affected (group_iri);
  14877. log_text ('jso_mark_affected (?)', group_iri);
  14878. if (group_iri = 'http://www.openlinksw.com/schemas/virtrdf#PrivateGraphs')
  14879. {
  14880. dict_remove (__rdf_graph_group_of_privates_dict(), memb_iid);
  14881. jso_mark_affected (memb_iri);
  14882. log_text ('jso_mark_affected (?)', memb_iri);
  14883. }
  14884. }
  14885. ;
  14886. create procedure DB.DBA.RDF_GRAPH_GROUP_DEL (in group_iri varchar, in memb_iri varchar)
  14887. {
  14888. declare group_iid, memb_iid IRI_ID;
  14889. group_iri := cast (group_iri as varchar);
  14890. DB.DBA.RDF_GRAPH_GROUP_IRI_CHECK (group_iri, 'DB.DBA.RDF_GRAPH_GROUP_DEL');
  14891. memb_iri := cast (memb_iri as varchar);
  14892. group_iid := iri_to_id (group_iri);
  14893. memb_iid := iri_to_id (memb_iri);
  14894. set isolation = 'serializable';
  14895. commit work;
  14896. if (not exists (select top 1 1 from DB.DBA.RDF_GRAPH_GROUP where RGG_IRI = group_iri))
  14897. signal ('RDF99', sprintf ('Graph group <%s> does not exist', group_iri));
  14898. if (group_iri = 'http://www.openlinksw.com/schemas/virtrdf#PrivateGraphs')
  14899. DB.DBA.RDF_GRAPH_CHECK_VISIBILITY_CHANGE (memb_iri, #i0);
  14900. delete from DB.DBA.RDF_GRAPH_GROUP_MEMBER
  14901. where RGGM_GROUP_IID = group_iid and RGGM_MEMBER_IID = memb_iid;
  14902. commit work;
  14903. DB.DBA.SECURITY_CL_EXEC_AND_LOG ('DB.DBA.RDF_GRAPH_GROUP_DEL_MEMONLY (?, ?, ?, ?)', vector (group_iri, group_iid, memb_iri, memb_iid));
  14904. }
  14905. ;
  14906. create function DB.DBA.RDF_GRAPH_USER_PERMS_GET (in graph_iri varchar, in uid any) returns integer
  14907. {
  14908. declare graph_iid IRI_ID;
  14909. declare res integer;
  14910. graph_iid := iri_to_id (graph_iri);
  14911. if (isstring (uid))
  14912. uid := ((select U_ID from DB.DBA.SYS_USERS where U_NAME = uid and (U_NAME='nobody' or (U_SQL_ENABLE and not U_ACCOUNT_DISABLED))));
  14913. if (uid is null)
  14914. return 0;
  14915. if (uid = 0)
  14916. return 1023;
  14917. res := coalesce (
  14918. (select RGU_PERMISSIONS from DB.DBA.RDF_GRAPH_USER where RGU_GRAPH_IID = graph_iid and RGU_USER_ID = uid),
  14919. __rdf_graph_approx_perms (graph_iid, uid) );
  14920. return res;
  14921. }
  14922. ;
  14923. create function DB.DBA.RDF_GRAPH_USER_PERMS_ACK (in graph_iri any, in uid any, in req_perms integer) returns integer
  14924. {
  14925. declare app_cbk, app_uid varchar;
  14926. declare graph_iid IRI_ID;
  14927. declare perms integer;
  14928. -- dbg_obj_princ ('DB.DBA.RDF_GRAPH_USER_PERMS_ACK (', graph_iri, uid, req_perms, ')');
  14929. graph_iid := iri_to_id (graph_iri);
  14930. if (__tag (uid) = __tag of vector)
  14931. {
  14932. app_cbk := uid[1];
  14933. app_uid := uid[2];
  14934. uid := uid[0];
  14935. }
  14936. else
  14937. app_cbk := NULL;
  14938. if (isstring (uid))
  14939. uid := ((select U_ID from DB.DBA.SYS_USERS where U_NAME = uid and (U_NAME='nobody' or (U_SQL_ENABLE and not U_ACCOUNT_DISABLED))));
  14940. if (uid is null)
  14941. perms := 0;
  14942. else if (uid = 0)
  14943. perms := 1023;
  14944. else
  14945. {
  14946. perms := __rdf_graph_approx_perms (graph_iid, uid);
  14947. if (bit_and (perms, req_perms) <> req_perms)
  14948. perms := coalesce ((select RGU_PERMISSIONS from DB.DBA.RDF_GRAPH_USER where RGU_GRAPH_IID = graph_iid and RGU_USER_ID = uid), perms);
  14949. }
  14950. if (bit_and (perms, req_perms) <> req_perms)
  14951. return 0;
  14952. if (app_cbk is not null)
  14953. {
  14954. perms := call (app_cbk)(graph_iid, app_uid);
  14955. if (bit_and (perms, req_perms) <> req_perms)
  14956. return 0;
  14957. }
  14958. return 1;
  14959. }
  14960. ;
  14961. --!AWK PUBLIC
  14962. create function DB.DBA.RDF_GRAPH_USER_PERM_TITLE (in perms integer) returns varchar
  14963. {
  14964. if (bit_and (perms, 1))
  14965. return 'read';
  14966. if (bit_and (perms, 2))
  14967. return 'write';
  14968. if (bit_and (perms, 4))
  14969. return 'sponge';
  14970. if (bit_and (perms, 8))
  14971. return 'get-group-list';
  14972. return sprintf ('"%d"', perms);
  14973. }
  14974. ;
  14975. create function DB.DBA.RDF_GRAPH_USER_PERMS_ASSERT (in graph_iri varchar, in uid any, in req_perms integer, in opname varchar) returns varchar
  14976. {
  14977. declare app_cbk, app_uid varchar;
  14978. declare graph_iid IRI_ID;
  14979. declare perms integer;
  14980. -- dbg_obj_princ ('DB.DBA.RDF_GRAPH_USER_PERMS_ASSERT (', graph_iri, uid, req_perms, opname, ')');
  14981. return __rgs_assert_cbk (graph_iri, uid, req_perms, opname);
  14982. graph_iid := iri_to_id (graph_iri);
  14983. if (__tag (uid) = __tag of vector)
  14984. {
  14985. app_cbk := uid[1];
  14986. app_uid := uid[2];
  14987. uid := uid[0];
  14988. }
  14989. else
  14990. app_cbk := NULL;
  14991. if (isstring (uid))
  14992. uid := ((select U_ID from DB.DBA.SYS_USERS where U_NAME = uid and (U_NAME='nobody' or (U_SQL_ENABLE and not U_ACCOUNT_DISABLED))));
  14993. if (uid is null)
  14994. perms := 0;
  14995. else if (uid = 0)
  14996. perms := 1023;
  14997. else
  14998. perms := coalesce (
  14999. (select RGU_PERMISSIONS from DB.DBA.RDF_GRAPH_USER where RGU_GRAPH_IID = graph_iid and RGU_USER_ID = uid),
  15000. (select RGU_PERMISSIONS from DB.DBA.RDF_GRAPH_USER where RGU_GRAPH_IID = graph_iid and RGU_USER_ID = http_nobody_uid()),
  15001. (select RGU_PERMISSIONS from DB.DBA.RDF_GRAPH_USER where RGU_GRAPH_IID = #i0 and RGU_USER_ID = uid),
  15002. (select RGU_PERMISSIONS from DB.DBA.RDF_GRAPH_USER where RGU_GRAPH_IID = #i0 and RGU_USER_ID = http_nobody_uid()),
  15003. 15 );
  15004. if (bit_and (perms, req_perms) <> req_perms)
  15005. signal ('RDF02', sprintf ('%s access denied: database user %s (%s) has no %s permission on graph %s',
  15006. opname, cast (uid as varchar), coalesce ((select top 1 U_NAME from DB.DBA.SYS_USERS where U_ID=uid)),
  15007. DB.DBA.RDF_GRAPH_USER_PERM_TITLE (bit_and (bit_not (perms), req_perms)),
  15008. graph_iri ) );
  15009. if (app_cbk is not null)
  15010. {
  15011. perms := call (app_cbk)(graph_iid, app_uid);
  15012. if (bit_and (perms, req_perms) <> req_perms)
  15013. signal ('RDF02', sprintf ('%s access denied: application user %s has no %s permission on graph %s',
  15014. opname, cast (uid as varchar), coalesce ((select top 1 U_NAME from DB.DBA.SYS_USERS where U_ID=uid)),
  15015. DB.DBA.RDF_GRAPH_USER_PERM_TITLE (bit_and (bit_not (perms), req_perms)),
  15016. graph_iri ) );
  15017. }
  15018. return graph_iri;
  15019. }
  15020. ;
  15021. create procedure DB.DBA.RDF_DEFAULT_USER_PERMS_SET_MEMONLY (in uname varchar, in uid integer, in perms integer, in special_iid IRI_ID, in set_private integer, in affected_jso any)
  15022. {
  15023. if (perms is null)
  15024. dict_remove (__rdf_graph_default_perms_of_user_dict (set_private), uid);
  15025. else
  15026. dict_put (__rdf_graph_default_perms_of_user_dict (set_private), uid, perms);
  15027. if (uid = http_nobody_uid())
  15028. {
  15029. if (perms is null)
  15030. dict_remove (__rdf_graph_public_perms_dict(), special_iid);
  15031. else
  15032. dict_put (__rdf_graph_public_perms_dict(), special_iid, perms);
  15033. }
  15034. foreach (varchar jso_key in affected_jso) do
  15035. {
  15036. jso_mark_affected (jso_key);
  15037. log_text ('jso_mark_affected (?)', jso_key);
  15038. }
  15039. }
  15040. ;
  15041. create procedure DB.DBA.RDF_DEFAULT_USER_PERMS_SET (in uname varchar, in perms integer, in set_private integer := 0)
  15042. {
  15043. declare uid integer;
  15044. declare special_iid IRI_ID;
  15045. declare affected_jso any;
  15046. -- dbg_obj_princ ('gs_hist.sql'); string_to_file ('gs_hist.sql', sprintf ('-- DB.DBA.RDF_DEFAULT_USER_PERMS_SET (''%s'', %d, %d);\n', uname, perms, set_private), -1);
  15047. if (perms is null)
  15048. {
  15049. DB.DBA.RDF_DEFAULT_USER_PERMS_DEL (uname, set_private);
  15050. return;
  15051. }
  15052. uid := (select U_ID from DB.DBA.SYS_USERS where U_NAME = uname and (U_NAME='nobody' or (U_SQL_ENABLE and not U_ACCOUNT_DISABLED)));
  15053. set isolation = 'serializable';
  15054. commit work;
  15055. if (uid is null)
  15056. signal ('RDF99', sprintf ('No active SQL user "%s" found, can not set its default permissions on RDF quad storage', uname));
  15057. if (set_private)
  15058. {
  15059. special_iid := #i8192;
  15060. for (select RGU_GRAPH_IID, RGU_PERMISSIONS from DB.DBA.RDF_GRAPH_USER
  15061. where RGU_GRAPH_IID <> #i0 and RGU_GRAPH_IID <> #i8192 and
  15062. RGU_USER_ID = uid and bit_and (bit_not (RGU_PERMISSIONS), perms) <> 0 and
  15063. exists (select top 1 1 from DB.DBA.RDF_GRAPH_GROUP_MEMBER where
  15064. RGGM_GROUP_IID = iri_to_id ('http://www.openlinksw.com/schemas/virtrdf#PrivateGraphs') and
  15065. RGGM_MEMBER_IID = RGU_GRAPH_IID ) ) do
  15066. signal ('RDF99', sprintf ('Default "private area" permissions of user "%s" on RDF quad store can not become broader than permissions on specific "private" graph <%s>',
  15067. uname, id_to_iri (RGU_GRAPH_IID) ) );
  15068. }
  15069. else
  15070. {
  15071. special_iid := #i0;
  15072. for (select RGU_GRAPH_IID, RGU_PERMISSIONS from DB.DBA.RDF_GRAPH_USER
  15073. where RGU_GRAPH_IID <> #i0 and RGU_GRAPH_IID <> #i8192 and
  15074. RGU_USER_ID = uid and bit_and (bit_not (RGU_PERMISSIONS), perms) <> 0 and
  15075. not exists (select top 1 1 from DB.DBA.RDF_GRAPH_GROUP_MEMBER where
  15076. RGGM_GROUP_IID = iri_to_id ('http://www.openlinksw.com/schemas/virtrdf#PrivateGraphs') and
  15077. RGGM_MEMBER_IID = RGU_GRAPH_IID ) ) do
  15078. signal ('RDF99', sprintf ('Default "world" permissions of user "%s" on RDF quad store can not become broader than permissions on specific "world" graph <%s>',
  15079. uname, id_to_iri (RGU_GRAPH_IID) ) );
  15080. }
  15081. if (uname='nobody')
  15082. {
  15083. for (select RGU_USER_ID, RGU_PERMISSIONS from DB.DBA.RDF_GRAPH_USER
  15084. where RGU_USER_ID <> uid and RGU_GRAPH_IID = special_iid and bit_and (bit_not (RGU_PERMISSIONS), perms) <> 0 ) do
  15085. signal ('RDF99', sprintf ('Default %s permissions of unauthenticated user ("nobody") on RDF quad store can not become broader than permissions of user %s (UID %d)',
  15086. (case (set_private) when 0 then '"world"' else '"private area"' end),
  15087. (select top 1 U_NAME from Db.DBA.SYS_USERS where U_ID = RGU_USER_ID), RGU_USER_ID) );
  15088. -- This is not required:
  15089. -- for (select RGU_GRAPH_IID, RGU_USER_ID, RGU_PERMISSIONS from DB.DBA.RDF_GRAPH_USER where RGU_USER_ID <> uid and RGU_GRAPH_IID <> #i0 and bit_and (bit_not (RGU_PERMISSIONS), perms) <> 0)
  15090. -- signal ('RDF99', sprintf ('Default permissions of unauthenticated user ("nobody") on RDF quad store can not become broader than permissions of user %s (UID %d) on specific graph <%s>',
  15091. -- (select top 1 U_NAME from Db.DBA.SYS_USER where U_ID = RGU_USER_ID), RGU_USER_ID, id_to_iri (RGU_GRAPH_IID) ) );
  15092. if (isstring (registry_get ('DB.DBA.RDF_REPL')) and not (bit_and (perms, 1))
  15093. and not exists (select top 1 1 from DB.DBA.RDF_GRAPH_USER where RGU_GRAPH_IID = special_iid and RGU_USER_ID = __rdf_repl_uid() and bit_and (RGU_PERMISSIONS, 1)))
  15094. {
  15095. if (set_private)
  15096. {
  15097. for (select RGGM_MEMBER_IID from DB.DBA.RDF_GRAPH_GROUP_MEMBER repl
  15098. where repl.RGGM_GROUP_IID = iri_to_id (UNAME'http://www.openlinksw.com/schemas/virtrdf#rdf_repl_graph_group')
  15099. and exists (select top 1 1 from DB.DBA.RDF_GRAPH_GROUP_MEMBER priv
  15100. where priv.RGGM_GROUP_IID = iri_to_id (UNAME'http://www.openlinksw.com/schemas/virtrdf#PrivateGraphs')
  15101. and priv.RGGM_MEMBER_IID = repl.RGGM_MEMBER_IID )
  15102. and not exists (select top 1 1 from DB.DBA.RDF_GRAPH_USER where RGU_GRAPH_IID = repl.RGGM_MEMBER_IID and RGU_USER_ID = __rdf_repl_uid() and bit_and (RGU_PERMISSIONS, 1))
  15103. and not exists (select top 1 1 from DB.DBA.RDF_GRAPH_USER where RGU_GRAPH_IID = special_iid and RGU_USER_ID = __rdf_repl_uid() and bit_and (RGU_PERMISSIONS, 1)) ) do
  15104. signal ('RDF99', 'Can not disable public read on private area while RDF replication is enabled and the replication account will loose its read permission on, e.g., <' || id_to_iri(RGGM_MEMBER_IID) || '>');
  15105. }
  15106. else
  15107. {
  15108. for (select RGGM_MEMBER_IID from DB.DBA.RDF_GRAPH_GROUP_MEMBER repl
  15109. where repl.RGGM_GROUP_IID = iri_to_id (UNAME'http://www.openlinksw.com/schemas/virtrdf#rdf_repl_graph_group')
  15110. and not exists (select top 1 1 from DB.DBA.RDF_GRAPH_GROUP_MEMBER priv
  15111. where priv.RGGM_GROUP_IID = iri_to_id (UNAME'http://www.openlinksw.com/schemas/virtrdf#PrivateGraphs')
  15112. and priv.RGGM_MEMBER_IID = repl.RGGM_MEMBER_IID )
  15113. and not exists (select top 1 1 from DB.DBA.RDF_GRAPH_USER where RGU_GRAPH_IID = repl.RGGM_MEMBER_IID and RGU_USER_ID = __rdf_repl_uid() and bit_and (RGU_PERMISSIONS, 1))
  15114. and not exists (select top 1 1 from DB.DBA.RDF_GRAPH_USER where RGU_GRAPH_IID = special_iid and RGU_USER_ID = __rdf_repl_uid() and bit_and (RGU_PERMISSIONS, 1)) ) do
  15115. signal ('RDF99', 'Can not disable public read on "world" area while RDF replication is enabled and the replication account will loose its read permission on, e.g., <' || id_to_iri(RGGM_MEMBER_IID) || '>');
  15116. }
  15117. }
  15118. }
  15119. if (uname <> 'dba')
  15120. {
  15121. if (not (exists (select top 1 1 from DB.DBA.RDF_GRAPH_USER where RGU_GRAPH_IID = #i0 and RGU_USER_ID = 0)))
  15122. DB.DBA.RDF_DEFAULT_USER_PERMS_SET ('dba', 1023);
  15123. if (not (exists (select top 1 1 from DB.DBA.RDF_GRAPH_USER where RGU_GRAPH_IID = #i8192 and RGU_USER_ID = 0)))
  15124. DB.DBA.RDF_DEFAULT_USER_PERMS_SET ('dba', 1023, 1);
  15125. }
  15126. insert replacing DB.DBA.RDF_GRAPH_USER (RGU_GRAPH_IID, RGU_USER_ID, RGU_PERMISSIONS)
  15127. values (special_iid, uid, perms);
  15128. -- dbg_obj_princ ('gs_hist.sql'); string_to_file ('gs_hist.sql', sprintf ('insert replacing DB.DBA.RDF_GRAPH_USER (RGU_GRAPH_IID, RGU_USER_ID, RGU_PERMISSIONS) values (%s, %d, %d);\n', cast (special_iid as varchar), uid, perms), -1);
  15129. commit work;
  15130. if (uname = 'nobody')
  15131. affected_jso := ((select DB.DBA.VECTOR_AGG (sub."jso_key")
  15132. from (sparql
  15133. define input:storage ""
  15134. prefix virtrdf: <http://www.openlinksw.com/schemas/virtrdf#>
  15135. select (str(?s)) as ?jso_key where {
  15136. graph <http://www.openlinksw.com/schemas/virtrdf#> { { ?s a virtrdf:QuadMap } union { ?s a virtrdf:QuadMap } } } ) sub
  15137. option (QUIETCAST) ));
  15138. else
  15139. affected_jso := vector (uname);
  15140. commit work;
  15141. DB.DBA.SECURITY_CL_EXEC_AND_LOG ('DB.DBA.RDF_DEFAULT_USER_PERMS_SET_MEMONLY (?,?,?,?,?,?)', vector (uname, uid, perms, special_iid, set_private, affected_jso));
  15142. }
  15143. ;
  15144. create procedure DB.DBA.RDF_DEFAULT_USER_PERMS_DEL (in uname varchar, in set_private integer := 0)
  15145. {
  15146. declare uid integer;
  15147. declare special_iid IRI_ID;
  15148. declare affected_jso any;
  15149. -- dbg_obj_princ ('gs_hist.sql'); string_to_file ('gs_hist.sql', sprintf ('-- DB.DBA.RDF_DEFAULT_USER_PERMS_DEL (''%s'', %d);\n', uname, set_private), -1);
  15150. if (uname in ('nobody', 'dba'))
  15151. signal ('RDF99', sprintf ('Default permissions of "%s" can be changed but can not be deleted', uname));
  15152. uid := (select U_ID from DB.DBA.SYS_USERS where U_NAME = uname);
  15153. set isolation = 'serializable';
  15154. commit work;
  15155. if (uid is null)
  15156. signal ('RDF99', sprintf ('No user "%s" found, can not delete its default permissions on RDF quad storage', uname));
  15157. if (set_private)
  15158. special_iid := #i8192;
  15159. else
  15160. special_iid := #i0;
  15161. delete from DB.DBA.RDF_GRAPH_USER where RGU_GRAPH_IID = special_iid and RGU_USER_ID = uid;
  15162. -- dbg_obj_princ ('gs_hist.sql'); string_to_file ('gs_hist.sql', sprintf ('delete from DB.DBA.RDF_GRAPH_USER where RGU_GRAPH_IID = %s and RGU_USER_ID = %d', cast (special_iid as varchar), uid), -1);
  15163. commit work;
  15164. affected_jso := vector (uname);
  15165. commit work;
  15166. DB.DBA.SECURITY_CL_EXEC_AND_LOG ('DB.DBA.RDF_DEFAULT_USER_PERMS_SET_MEMONLY (?,?,null,?,?,?)', vector (uname, uid, special_iid, set_private, affected_jso));
  15167. }
  15168. ;
  15169. create procedure DB.DBA.RDF_GRAPH_USER_PERMS_SET_MEMONLY (in graph_iri varchar, in graph_iid IRI_ID, in uid integer, in perms integer)
  15170. {
  15171. graph_iri := cast (graph_iri as varchar);
  15172. DB.DBA.RDF_GRAPH_CACHE_IID (graph_iid);
  15173. if (uid = http_nobody_uid())
  15174. dict_put (__rdf_graph_public_perms_dict(), graph_iid, perms);
  15175. else
  15176. __rdf_graph_specific_perms_of_user (graph_iid, uid, perms);
  15177. jso_mark_affected (graph_iri);
  15178. log_text ('jso_mark_affected (?)', graph_iri);
  15179. }
  15180. ;
  15181. create procedure DB.DBA.RDF_GRAPH_USER_PERMS_SET (in graph_iri varchar, in uname varchar, in perms integer)
  15182. {
  15183. declare graph_iid IRI_ID;
  15184. declare uid, graph_is_private, common_perms integer;
  15185. declare special_iid IRI_ID;
  15186. -- dbg_obj_princ ('gs_hist.sql'); string_to_file ('gs_hist.sql', sprintf ('-- DB.DBA.RDF_GRAPH_USER_PERMS_SET (''%s'', ''%s'', %d);\n', graph_iri, uname, perms), -1);
  15187. if (perms is null)
  15188. {
  15189. RDF_GRAPH_USER_PERMS_DEL (graph_iri, uname);
  15190. return;
  15191. }
  15192. graph_iid := iri_to_id (graph_iri);
  15193. uid := ((select U_ID from DB.DBA.SYS_USERS where U_NAME = uname and (U_NAME='nobody' or (U_SQL_ENABLE and not U_ACCOUNT_DISABLED))));
  15194. set isolation = 'serializable';
  15195. commit work;
  15196. if (uid is null)
  15197. signal ('RDF99', sprintf ('No active SQL user "%s" found, can not set its permissions on graph <%s>', uname, graph_iri));
  15198. graph_is_private := (select count (1) from DB.DBA.RDF_GRAPH_GROUP_MEMBER where
  15199. RGGM_GROUP_IID = iri_to_id ('http://www.openlinksw.com/schemas/virtrdf#PrivateGraphs') and
  15200. RGGM_MEMBER_IID = graph_iid );
  15201. if (graph_is_private)
  15202. special_iid := #i8192;
  15203. else
  15204. special_iid := #i0;
  15205. common_perms := coalesce (
  15206. (select RGU_PERMISSIONS from DB.DBA.RDF_GRAPH_USER where RGU_GRAPH_IID = special_iid and RGU_USER_ID = uid),
  15207. (select RGU_PERMISSIONS from DB.DBA.RDF_GRAPH_USER where RGU_GRAPH_IID = special_iid and RGU_USER_ID = http_nobody_uid()),
  15208. 15 );
  15209. if (bit_and (bit_not (perms), common_perms))
  15210. signal ('RDF99', sprintf ('Default permissions of user "%s" on RDF quad store are broader than new permissions on specific graph <%s>', uname, graph_iri));
  15211. if (uname = 'nobody')
  15212. {
  15213. if (isstring (registry_get ('DB.DBA.RDF_REPL')) and not (bit_and (perms, 1))
  15214. and exists (select top 1 1 from DB.DBA.RDF_GRAPH_GROUP_MEMBER
  15215. where RGGM_GROUP_IID = iri_to_id (UNAME'http://www.openlinksw.com/schemas/virtrdf#rdf_repl_graph_group') and RGGM_MEMBER_IID = graph_iid)
  15216. and not exists (select top 1 1 from DB.DBA.RDF_GRAPH_USER where RGU_GRAPH_IID = graph_iid and RGU_USER_ID = __rdf_repl_uid() and bit_and (RGU_PERMISSIONS, 1))
  15217. and not exists (select top 1 1 from DB.DBA.RDF_GRAPH_USER where RGU_GRAPH_IID = special_iid and RGU_USER_ID = __rdf_repl_uid() and bit_and (RGU_PERMISSIONS, 1)) )
  15218. signal ('RDF99', 'Can not disable public read access to <' || id_to_iri (graph_iid) || '> while it is included in RDF replication and the replication is enabled and the replication account will loose its read permission');
  15219. jso_mark_affected (graph_iri);
  15220. log_text ('jso_mark_affected (?)', graph_iri);
  15221. }
  15222. else
  15223. {
  15224. common_perms := coalesce (
  15225. (select RGU_PERMISSIONS from DB.DBA.RDF_GRAPH_USER where RGU_GRAPH_IID = graph_iid and RGU_USER_ID = http_nobody_uid()),
  15226. (select RGU_PERMISSIONS from DB.DBA.RDF_GRAPH_USER where RGU_GRAPH_IID = special_iid and RGU_USER_ID = http_nobody_uid()),
  15227. 15 );
  15228. if (bit_and (bit_not (perms), common_perms))
  15229. signal ('RDF99', sprintf ('Permissions of unauthenticated user are broader than new permissions of user "%s" on specific graph <%s>', uname, graph_iri));
  15230. if ((uname = '__rdf_repl') and isstring (registry_get ('DB.DBA.RDF_REPL')) and not (bit_and (perms, 1)) and
  15231. exists (select top 1 1 from DB.DBA.RDF_GRAPH_GROUP_MEMBER
  15232. where RGGM_GROUP_IID = iri_to_id (UNAME'http://www.openlinksw.com/schemas/virtrdf#rdf_repl_graph_group') and RGGM_MEMBER_IID = graph_iid) )
  15233. signal ('RDF99', 'Can not disable read access of __rdf_repl account to <' || id_to_iri (graph_iid) || '> while it is included in RDF replication and the replication is enabled');
  15234. }
  15235. if (not (exists (select top 1 1 from DB.DBA.RDF_GRAPH_USER where RGU_GRAPH_IID = #i0 and RGU_USER_ID = 0)))
  15236. DB.DBA.RDF_DEFAULT_USER_PERMS_SET ('dba', 1023);
  15237. if (not (exists (select top 1 1 from DB.DBA.RDF_GRAPH_USER where RGU_GRAPH_IID = #i8192 and RGU_USER_ID = 0)))
  15238. DB.DBA.RDF_DEFAULT_USER_PERMS_SET ('dba', 1023, 1);
  15239. insert replacing DB.DBA.RDF_GRAPH_USER (RGU_GRAPH_IID, RGU_USER_ID, RGU_PERMISSIONS)
  15240. values (graph_iid, uid, perms);
  15241. -- dbg_obj_princ ('gs_hist.sql'); string_to_file ('gs_hist.sql', sprintf ('insert replacing DB.DBA.RDF_GRAPH_USER (RGU_GRAPH_IID, RGU_USER_ID, RGU_PERMISSIONS) values (%s, %d, %d);\n', cast (graph_iid as varchar), uid, perms), -1);
  15242. commit work;
  15243. DB.DBA.SECURITY_CL_EXEC_AND_LOG ('DB.DBA.RDF_GRAPH_USER_PERMS_SET_MEMONLY (?,?,?,?)', vector (graph_iri, graph_iid, uid, perms));
  15244. }
  15245. ;
  15246. create procedure DB.DBA.RDF_GRAPH_USER_PERMS_DEL_MEMONLY (in graph_iri varchar, in graph_iid IRI_ID, in uid integer)
  15247. {
  15248. graph_iri := cast (graph_iri as varchar);
  15249. DB.DBA.RDF_GRAPH_CACHE_IID (graph_iid);
  15250. if (uid = http_nobody_uid())
  15251. dict_remove (__rdf_graph_public_perms_dict(), graph_iid);
  15252. else
  15253. __rdf_graph_specific_perms_of_user (graph_iid, uid, -1);
  15254. jso_mark_affected (graph_iri);
  15255. log_text ('jso_mark_affected (?)', graph_iri);
  15256. }
  15257. ;
  15258. create procedure DB.DBA.RDF_GRAPH_USER_PERMS_DEL (in graph_iri varchar, in uname varchar)
  15259. {
  15260. declare graph_iid IRI_ID;
  15261. declare uid integer;
  15262. declare special_iid IRI_ID;
  15263. -- dbg_obj_princ ('gs_hist.sql'); string_to_file ('gs_hist.sql', sprintf ('-- DB.DBA.RDF_GRAPH_USER_PERMS_SET (''%s'', ''%s'', %d);\n', graph_iri, uname, perms), -1);
  15264. graph_iid := iri_to_id (graph_iri);
  15265. uid := (select U_ID from DB.DBA.SYS_USERS where U_NAME = uname);
  15266. set isolation = 'serializable';
  15267. commit work;
  15268. if (uid is null)
  15269. signal ('RDF99', sprintf ('No user "%s" found, can not change its permissions on graph <%s>', uname, graph_iri));
  15270. delete from DB.DBA.RDF_GRAPH_USER where RGU_GRAPH_IID = graph_iid and RGU_USER_ID = uid;
  15271. -- dbg_obj_princ ('gs_hist.sql'); string_to_file ('gs_hist.sql', sprintf ('delete from DB.DBA.RDF_GRAPH_USER where RGU_GRAPH_IID = %s and RGU_USER_ID = %d;\n', cast (graph_iid as varchar), uid), -1);
  15272. commit work;
  15273. DB.DBA.SECURITY_CL_EXEC_AND_LOG ('DB.DBA.RDF_GRAPH_USER_PERMS_DEL_MEMONLY (?,?,?)', vector (graph_iri, graph_iid, uid));
  15274. }
  15275. ;
  15276. create procedure DB.DBA.RDF_ALL_USER_PERMS_DEL (in uname varchar, in uid integer := null)
  15277. {
  15278. declare special_iid IRI_ID;
  15279. declare graphs any;
  15280. declare graphs_count, graphs_ctr integer;
  15281. -- dbg_obj_princ ('gs_hist.sql'); string_to_file ('gs_hist.sql', sprintf ('-- DB.DBA.RDF_ALL_USER_PERMS_DEL (''%s'', %s);\n', uname, case (isnotnull (uid)) when 0 then 'null' else cast (uid as varchar) end), -1);
  15282. set isolation = 'serializable';
  15283. commit work;
  15284. if (uid is null)
  15285. {
  15286. uid := (select U_ID from DB.DBA.SYS_USERS where U_NAME = uname);
  15287. if (uid is null)
  15288. signal ('RDF99', sprintf ('No user "%s" found, can not change its permissions on RDF graphs', uname));
  15289. }
  15290. if (uname is null)
  15291. uname := (select U_NAME from DB.DBA.SYS_USERS where U_ID = uid);
  15292. if (uid = http_nobody_uid() or uid = 0)
  15293. {
  15294. graphs := (select DB.DBA.VECTOR_AGG (RGU_GRAPH_IID) from DB.DBA.RDF_GRAPH_USER where RGU_USER_ID = uid and not (RGU_GRAPH_IID in (#i0, #i8192)));
  15295. delete from DB.DBA.RDF_GRAPH_USER where RGU_USER_ID = uid and not (RGU_GRAPH_IID in (#i0, #i8192));
  15296. }
  15297. else
  15298. {
  15299. graphs := (select DB.DBA.VECTOR_AGG (RGU_GRAPH_IID) from DB.DBA.RDF_GRAPH_USER where RGU_USER_ID = uid);
  15300. delete from DB.DBA.RDF_GRAPH_USER where RGU_USER_ID = uid;
  15301. }
  15302. gvector_digit_sort (graphs, 1, 0, 1);
  15303. -- dbg_obj_princ ('graphs=', graphs);
  15304. graphs_count := length (graphs);
  15305. for (graphs_ctr := graphs_count-1; graphs_ctr >= 0; graphs_ctr := graphs_ctr-1)
  15306. {
  15307. declare g_iid IR_ID;
  15308. g_iid := graphs [graphs_ctr];
  15309. if (g_iid = #i0 or g_iid = #i8192)
  15310. {
  15311. declare affected_jso any;
  15312. if (uname is null)
  15313. affected_jso := vector ();
  15314. else
  15315. affected_jso := vector (uname);
  15316. DB.DBA.SECURITY_CL_EXEC_AND_LOG ('DB.DBA.RDF_DEFAULT_USER_PERMS_SET_MEMONLY (?,?,null,?,?,?)',
  15317. vector (uname, uid, g_iid, case (g_iid) when #i8192 then 1 else 0 end, affected_jso));
  15318. }
  15319. else
  15320. DB.DBA.SECURITY_CL_EXEC_AND_LOG ('DB.DBA.RDF_GRAPH_USER_PERMS_DEL_MEMONLY (?,?,?)', vector (id_to_iri_nosignal (g_iid), g_iid, uid));
  15321. }
  15322. commit work;
  15323. }
  15324. ;
  15325. create function DB.DBA.RDF_GRAPH_GROUP_LIST_GET (in group_iri any, in extra_graphs any, in uid any, in gs_app_cbk varchar, in gs_app_uid varchar, in req_perms integer) returns any
  15326. {
  15327. declare group_iid IRI_ID;
  15328. declare world_perms, private_perms, common_perms, perms integer;
  15329. declare perms_dict, full_list, filtered_list any;
  15330. -- dbg_obj_princ ('DB.DBA.RDF_GRAPH_GROUP_LIST_GET (', group_iri, extra_graphs, uid, req_perms, ')');
  15331. if (isstring (uid))
  15332. uid := ((select U_ID from DB.DBA.SYS_USERS where U_NAME = uid and (U_NAME='nobody' or (U_SQL_ENABLE and not U_ACCOUNT_DISABLED))));
  15333. if (uid is null)
  15334. return vector ();
  15335. perms_dict := __rdf_graph_default_perms_of_user_dict(0);
  15336. world_perms := coalesce (
  15337. dict_get (perms_dict, uid, NULL),
  15338. dict_get (perms_dict, http_nobody_uid(), NULL),
  15339. 15 );
  15340. perms_dict := __rdf_graph_default_perms_of_user_dict(1);
  15341. private_perms := coalesce (
  15342. dict_get (perms_dict, uid, NULL),
  15343. dict_get (perms_dict, http_nobody_uid(), NULL),
  15344. 15 );
  15345. if (gs_app_cbk is not null)
  15346. {
  15347. world_perms := bit_and (world_perms, call (gs_app_cbk)(#i0, gs_app_uid));
  15348. private_perms := bit_and (private_perms, call (gs_app_cbk)(#i8192, gs_app_uid));
  15349. }
  15350. common_perms := bit_and (world_perms, private_perms);
  15351. -- dbg_obj_princ ('DB.DBA.RDF_GRAPH_GROUP_LIST_GET: common_perms = ', common_perms);
  15352. if (__tag (group_iri) = __tag of vector)
  15353. {
  15354. vectorbld_init (full_list);
  15355. foreach (any g_iri in group_iri) do
  15356. {
  15357. group_iid := iri_to_id (g_iri);
  15358. if (not bit_and (common_perms, 8))
  15359. {
  15360. perms := __rdf_graph_approx_perms (group_iid, uid);
  15361. if (not bit_and (perms, 8))
  15362. perms := coalesce (
  15363. (select RGU_PERMISSIONS from DB.DBA.RDF_GRAPH_USER where RGU_GRAPH_IID = group_iid and RGU_USER_ID = uid),
  15364. perms );
  15365. if (gs_app_cbk is not null and bit_and (perms, 8))
  15366. perms := bit_and (perms, call (gs_app_cbk)(group_iid, gs_app_uid));
  15367. -- dbg_obj_princ ('DB.DBA.RDF_GRAPH_GROUP_LIST_GET: perms for list = ', perms);
  15368. }
  15369. else
  15370. perms := common_perms;
  15371. if (bit_and (perms, 8))
  15372. {
  15373. declare membs any;
  15374. membs := dict_get (__rdf_graph_group_dict(), group_iid, null);
  15375. if (membs is not null)
  15376. {
  15377. if (isvector (membs))
  15378. vectorbld_concat_acc (full_list, membs);
  15379. else
  15380. vectorbld_concat_acc (full_list, dict_list_keys (membs, 0));
  15381. }
  15382. }
  15383. }
  15384. vectorbld_final (full_list);
  15385. }
  15386. else
  15387. {
  15388. group_iid := iri_to_id (group_iri);
  15389. if (not bit_and (common_perms, 8))
  15390. {
  15391. perms := __rdf_graph_approx_perms (group_iid, uid);
  15392. if (not bit_and (perms, 8))
  15393. perms := coalesce (
  15394. (select RGU_PERMISSIONS from DB.DBA.RDF_GRAPH_USER where RGU_GRAPH_IID = group_iid and RGU_USER_ID = uid),
  15395. perms );
  15396. if (gs_app_cbk is not null and bit_and (perms, 8))
  15397. perms := bit_and (perms, call (gs_app_cbk)(group_iid, gs_app_uid));
  15398. -- dbg_obj_princ ('DB.DBA.RDF_GRAPH_GROUP_LIST_GET: perms for list = ', perms);
  15399. }
  15400. else
  15401. perms := common_perms;
  15402. if (bit_and (perms, 8))
  15403. {
  15404. full_list := dict_get (__rdf_graph_group_dict(), group_iid, null);
  15405. if (full_list is null)
  15406. full_list := vector ();
  15407. else if (not isvector (full_list))
  15408. full_list := dict_list_keys (full_list, 0);
  15409. }
  15410. else
  15411. full_list := vector ();
  15412. }
  15413. if (bit_and (common_perms, req_perms) = req_perms)
  15414. {
  15415. declare ctr integer;
  15416. if (extra_graphs is null)
  15417. return full_list;
  15418. ctr := length (extra_graphs);
  15419. while (ctr > 0)
  15420. {
  15421. ctr := ctr - 1;
  15422. extra_graphs [ctr] := iri_to_id (extra_graphs[ctr]);
  15423. }
  15424. full_list := vector_concat (full_list, extra_graphs);
  15425. gvector_digit_sort (full_list, 1, 0, 1);
  15426. return full_list;
  15427. }
  15428. vectorbld_init (filtered_list);
  15429. foreach (IRI_ID member_iid in full_list) do
  15430. {
  15431. perms := __rdf_graph_approx_perms (member_iid, uid);
  15432. if (bit_and (perms, req_perms) <> req_perms)
  15433. perms := coalesce (
  15434. (select RGU_PERMISSIONS from DB.DBA.RDF_GRAPH_USER where RGU_GRAPH_IID = member_iid and RGU_USER_ID = uid),
  15435. dict_get (__rdf_graph_public_perms_dict(), member_iid, NULL),
  15436. perms );
  15437. if (gs_app_cbk is not null and bit_and (perms, req_perms) = req_perms)
  15438. perms := bit_and (perms, call (gs_app_cbk)(member_iid, gs_app_uid));
  15439. -- dbg_obj_princ ('DB.DBA.RDF_GRAPH_GROUP_LIST_GET: perms for ', member_iid, ' = ', perms);
  15440. if (bit_and (perms, req_perms) = req_perms)
  15441. vectorbld_acc (filtered_list, member_iid);
  15442. }
  15443. foreach (any g in extra_graphs) do
  15444. {
  15445. declare g_iid IRI_ID;
  15446. g_iid := iri_to_id (g);
  15447. perms := coalesce (
  15448. (select RGU_PERMISSIONS from DB.DBA.RDF_GRAPH_USER where RGU_GRAPH_IID = g_iid and RGU_USER_ID = uid),
  15449. dict_get (__rdf_graph_public_perms_dict(), g_iid, NULL),
  15450. common_perms );
  15451. if (gs_app_cbk is not null and bit_and (perms, req_perms) = req_perms)
  15452. perms := bit_and (perms, call (gs_app_cbk)(g_iid, gs_app_uid));
  15453. -- dbg_obj_princ ('DB.DBA.RDF_GRAPH_GROUP_LIST_GET: perms for ', g_iid, ' = ', perms);
  15454. if (bit_and (perms, req_perms) = req_perms)
  15455. vectorbld_acc (filtered_list, g_iid);
  15456. }
  15457. vectorbld_final (filtered_list);
  15458. gvector_digit_sort (filtered_list, 1, 0, 1);
  15459. return filtered_list;
  15460. }
  15461. ;
  15462. create procedure DB.DBA.RDF_GRAPH_SECURITY_AUDIT (in recovery integer)
  15463. {
  15464. declare SEVERITY, GRAPH_IRI, USER_NAME, MESSAGE varchar;
  15465. declare GRAPH_IID IRI_ID;
  15466. declare USER_ID integer;
  15467. result_names (SEVERITY, GRAPH_IID, GRAPH_IRI, USER_ID, USER_NAME, MESSAGE);
  15468. declare mem_dict, mem_dict_inv, pg_mem_dict, mem_vec, mem_vec_inv, fake any;
  15469. declare mem_ctr, mem_count, pg_count, err_bad_count, err_recoverable_count, err_recoverable_count_total, err_count_total integer;
  15470. declare sparql_u_id integer;
  15471. declare user_sparql_half_protects_from_extra_access integer;
  15472. err_recoverable_count_total := 0; err_count_total := 0;
  15473. sparql_u_id := (select U_ID from DB.DBA.SYS_USERS where U_NAME='SPARQL');
  15474. -- dbg_obj_princ ('Starting RDF Graph Security Audit, please be patient.');
  15475. result ('', null, null, null, null, 'Inspecting caches of IRI_IDs of IRIs mentioned in security data...');
  15476. err_bad_count := 0;
  15477. err_recoverable_count := 0;
  15478. mem_dict := __rdf_graph_iri2id_dict();
  15479. mem_dict_inv := __rdf_graph_id2iri_dict();
  15480. if (dict_size (mem_dict_inv) <> dict_size (mem_dict))
  15481. {
  15482. result ('ERROR', null, null, null, null,
  15483. sprintf ('Cache of IRI_IDs of IRIs contains %d items, but cache of IRIs of IRI_IDs contains %d items, mismatch',
  15484. dict_size (mem_dict_inv), dict_size (mem_dict) ) );
  15485. err_recoverable_count := err_recoverable_count + 1;
  15486. }
  15487. mem_vec := dict_to_vector (mem_dict, 0);
  15488. mem_vec_inv := dict_to_vector (mem_dict_inv, 0);
  15489. mem_count := length (mem_vec);
  15490. -- dbg_obj_princ ('Inspecting ', mem_count, ' IRIs cached in memory for structures related to security and graph groups...');
  15491. for (mem_ctr := 0; mem_ctr < mem_count; mem_ctr := mem_ctr + 2)
  15492. {
  15493. declare iri varchar;
  15494. declare iid IRI_ID;
  15495. iri := mem_vec[mem_ctr];
  15496. iid := mem_vec[mem_ctr+1];
  15497. if ((__tag (iri) <> 217 /* __tag of UNAME */) or (__tag (iid) <> __tag of IRI_ID))
  15498. {
  15499. result ('ERROR', null, null, null, null,
  15500. sprintf ('Unexpected datatypes: tag of IRI "%.300s" is %d, tag of IRI_ID "%.300s" is %d; should be %d and %d',
  15501. cast (iri as varchar), __tag (iri),
  15502. cast (iid as varchar), __tag (iid),
  15503. 217 /* __tag of UNAME */, __tag of IRI_ID ) );
  15504. err_recoverable_count := err_recoverable_count + 1;
  15505. if (recovery)
  15506. dict_remove (mem_dict, iri);
  15507. }
  15508. else if (iri_to_id (iri) <> iid)
  15509. {
  15510. result ('ERROR', null, null, null, null,
  15511. sprintf ('Cached IRI_IDs of IRI <%.300s> is %s, actual is %s, mismatch',
  15512. cast (iri as varchar), cast (iid as varchar), cast (iri_to_id (iri) as varchar) ) );
  15513. err_recoverable_count := err_recoverable_count + 1;
  15514. if (recovery)
  15515. {
  15516. iid := iri_to_id_nosignal (iri);
  15517. if (iid is not null)
  15518. {
  15519. dict_put (mem_dict, iri, iid);
  15520. dict_put (mem_dict_inv, iid, iri);
  15521. }
  15522. else
  15523. dict_remove (mem_dict, iri);
  15524. }
  15525. }
  15526. if (0 = mod (mem_ctr, 100000))
  15527. {
  15528. -- dbg_obj_princ ('...', mem_ctr, '/', mem_count, ' IRIs passed forward check...');
  15529. ;
  15530. }
  15531. }
  15532. mem_count := length (mem_vec_inv);
  15533. -- dbg_obj_princ ('Inspecting ', mem_count, ' IRI IDs cached in memory for structures related to security and graph groups');
  15534. for (mem_ctr := 0; mem_ctr < mem_count; mem_ctr := mem_ctr + 2)
  15535. {
  15536. declare iid IRI_ID;
  15537. declare iri varchar;
  15538. iid := mem_vec_inv[mem_ctr];
  15539. iri := mem_vec_inv[mem_ctr+1];
  15540. if ((__tag (iid) <> __tag of IRI_ID) or (__tag (iri) <> 217 /* __tag of UNAME */))
  15541. {
  15542. result ('ERROR', null, null, null, null,
  15543. sprintf ('Unexpected datatypes: tag of IRI_ID "%.300s" is %d, tag of IRI "%.300s" is %d; should be %d and %d',
  15544. cast (iid as varchar), __tag (iid),
  15545. cast (iri as varchar), __tag (iri),
  15546. __tag of IRI_ID, 217 /* __tag of UNAME */ ) );
  15547. err_recoverable_count := err_recoverable_count + 1;
  15548. if (recovery)
  15549. dict_remove (mem_dict_inv, iid);
  15550. }
  15551. else if (__uname (id_to_iri (iid)) <> iri)
  15552. {
  15553. result ('ERROR', null, null, null, null,
  15554. sprintf ('Cached IRI of IRI_ID %s is <%.300s>, actual is <%.300s>, mismatch',
  15555. cast (iid as varchar), cast (iri as varchar), cast (id_to_iri (iid) as varchar) ) );
  15556. err_recoverable_count := err_recoverable_count + 1;
  15557. if (recovery)
  15558. {
  15559. iri := id_to_iri_nosignal (iid);
  15560. if (iri is not null)
  15561. {
  15562. iri := __uname (iri);
  15563. dict_put (mem_dict_inv, iid, iri);
  15564. dict_put (mem_dict, iri, iid);
  15565. }
  15566. else
  15567. dict_remove (mem_dict_inv, iid);
  15568. }
  15569. }
  15570. if (0 = mod (mem_ctr, 100000))
  15571. {
  15572. -- dbg_obj_princ ('...', mem_ctr, '/', mem_count, ' IRI IDs passed reverse check');
  15573. ;
  15574. }
  15575. }
  15576. if (err_recoverable_count)
  15577. {
  15578. if (not recovery)
  15579. {
  15580. result ('FATAL', null, null, null, null,
  15581. sprintf ('%d errors need urgent recovery, the rest of security audit has little sence while these errors persist',
  15582. err_recoverable_count ) );
  15583. return;
  15584. }
  15585. else
  15586. {
  15587. if (dict_size (mem_dict_inv) <> dict_size (mem_dict))
  15588. {
  15589. result ('FATAL', null, null, null, null,
  15590. sprintf ('Cache of IRI_IDs of IRIs contains %d items, but cache of IRIs of IRI_IDs contains %d items, mismatch even after recovery',
  15591. dict_size (mem_dict_inv), dict_size (mem_dict) ) );
  15592. err_bad_count := err_bad_count + 1;
  15593. }
  15594. }
  15595. }
  15596. err_count_total := err_count_total + err_recoverable_count + err_bad_count;
  15597. err_recoverable_count_total := err_recoverable_count_total + err_recoverable_count;
  15598. -- dbg_obj_princ ('Inspecting completeness of IRI cache for graph groups...');
  15599. result ('', null, null, null, null, 'Inspecting completeness of IRI cache for graph groups...');
  15600. err_bad_count := 0;
  15601. err_recoverable_count := 0;
  15602. for (select RGG_IID from DB.DBA.RDF_GRAPH_GROUP where dict_get (__rdf_graph_id2iri_dict(), RGG_IID, null) is null
  15603. union select RGGM_GROUP_IID from DB.DBA.RDF_GRAPH_GROUP_MEMBER where dict_get (__rdf_graph_id2iri_dict(), RGGM_GROUP_IID, null) is null
  15604. for update ) do
  15605. {
  15606. if (id_to_iri_nosignal (RGG_IID) is null)
  15607. result ('ERROR', RGG_IID, null, null, null,
  15608. sprintf ('The IRI_ID %s of a graph group does not correspond to any IRI',
  15609. cast (RGG_IID as varchar) ) );
  15610. else
  15611. result ('ERROR', RGG_IID, id_to_iri_nosignal (RGG_IID), null, null,
  15612. sprintf ('The IRI <%.300s> of graph group IRI_ID %s is not cached',
  15613. id_to_iri_nosignal (RGG_IID), cast (RGG_IID as varchar) ) );
  15614. err_recoverable_count := err_recoverable_count + 1;
  15615. }
  15616. if (err_recoverable_count and recovery)
  15617. {
  15618. -- dbg_obj_princ ('Erasing invalid graph groups...');
  15619. delete from DB.DBA.RDF_GRAPH_GROUP where id_to_iri_nosignal (RGG_IID) is null;
  15620. -- dbg_obj_princ ('Erasing membership data about invalid graph groups...');
  15621. delete from DB.DBA.RDF_GRAPH_GROUP_MEMBER where id_to_iri_nosignal (RGGM_GROUP_IID) is null;
  15622. commit work;
  15623. -- dbg_obj_princ ('Updating IRI caches for graph groups...');
  15624. fake := (select
  15625. count (dict_put (__rdf_graph_iri2id_dict(), __uname (id_to_canonicalized_iri (RGG_IID)), RGG_IID)) +
  15626. count (dict_put (__rdf_graph_id2iri_dict(), RGG_IID, __uname (id_to_canonicalized_iri (RGG_IID))))
  15627. from DB.DBA.RDF_GRAPH_GROUP );
  15628. -- dbg_obj_princ ('Updating IRI caches for graph groups via memberships...');
  15629. fake := (select
  15630. count (dict_put (__rdf_graph_iri2id_dict(), __uname (id_to_canonicalized_iri (RGGM_GROUP_IID)), RGGM_GROUP_IID)) +
  15631. count (dict_put (__rdf_graph_id2iri_dict(), RGGM_GROUP_IID, __uname (id_to_canonicalized_iri (RGGM_GROUP_IID))))
  15632. from DB.DBA.RDF_GRAPH_GROUP_MEMBER );
  15633. -- dbg_obj_princ ('Updating IRI caches for graph group members...');
  15634. fake := (select
  15635. count (dict_put (__rdf_graph_iri2id_dict(), __uname (id_to_canonicalized_iri (RGGM_MEMBER_IID)), RGGM_MEMBER_IID)) +
  15636. count (dict_put (__rdf_graph_id2iri_dict(), RGGM_MEMBER_IID, __uname (id_to_canonicalized_iri (RGGM_MEMBER_IID))))
  15637. from DB.DBA.RDF_GRAPH_GROUP_MEMBER );
  15638. }
  15639. err_count_total := err_count_total + err_recoverable_count + err_bad_count;
  15640. err_recoverable_count_total := err_recoverable_count_total + err_recoverable_count;
  15641. -- dbg_obj_princ ('Inspecting completeness of IRI cache for graph group members...');
  15642. result ('', null, null, null, null, 'Inspecting completeness of IRI cache for graph group members...');
  15643. err_bad_count := 0;
  15644. err_recoverable_count := 0;
  15645. for (select RGGM_MEMBER_IID, min (RGGM_GROUP_IID) as SAMPLE_GROUP_IID from DB.DBA.RDF_GRAPH_GROUP_MEMBER where dict_get (__rdf_graph_id2iri_dict(), RGGM_MEMBER_IID, null) is null group by RGGM_MEMBER_IID for update) do
  15646. {
  15647. if (id_to_iri_nosignal (RGGM_MEMBER_IID) is null)
  15648. result ('ERROR', RGGM_MEMBER_IID, null, null, null,
  15649. sprintf ('The IRI_ID %s of a member of a graph group <%.300s> does not correspond to any IRI',
  15650. cast (RGGM_MEMBER_IID as varchar), id_to_iri_nosignal (SAMPLE_GROUP_IID) ) );
  15651. else
  15652. result ('ERROR', RGGM_MEMBER_IID, id_to_iri_nosignal (RGGM_MEMBER_IID), null, null,
  15653. sprintf ('The IRI <%.300s> of IRI_ID %s of the member of a graph group <%.300s> is not cached',
  15654. id_to_iri_nosignal (RGGM_MEMBER_IID), cast (RGGM_MEMBER_IID as varchar), id_to_iri_nosignal (SAMPLE_GROUP_IID) ) );
  15655. err_recoverable_count := err_recoverable_count + 1;
  15656. }
  15657. if (err_recoverable_count and recovery)
  15658. {
  15659. delete from DB.DBA.RDF_GRAPH_GROUP_MEMBER where id_to_iri_nosignal (RGGM_MEMBER_IID) is null;
  15660. commit work;
  15661. fake := (select
  15662. count (dict_put (__rdf_graph_iri2id_dict(), __uname (id_to_iri (RGGM_MEMBER_IID)), RGGM_MEMBER_IID)) +
  15663. count (dict_put (__rdf_graph_id2iri_dict(), RGGM_MEMBER_IID, __uname (id_to_iri (RGGM_MEMBER_IID))))
  15664. from DB.DBA.RDF_GRAPH_GROUP_MEMBER );
  15665. }
  15666. err_count_total := err_count_total + err_recoverable_count + err_bad_count;
  15667. err_recoverable_count_total := err_recoverable_count_total + err_recoverable_count;
  15668. -- dbg_obj_princ ('Check for mismatches between graph group IRIs and graph group IRI_IDs...');
  15669. result ('', null, null, null, null, 'Check for mismatches between graph group IRIs and graph group IRI_IDs...');
  15670. err_bad_count := 0;
  15671. err_recoverable_count := 0;
  15672. for (select RGG_IID, id_to_iri_nosignal (RGG_IID) as actual_iri, RGG_IRI from DB.DBA.RDF_GRAPH_GROUP where id_to_iri_nosignal (RGG_IID) <> __bft (RGG_IRI, 1)) do
  15673. {
  15674. if (actual_iri is not null)
  15675. {
  15676. result ('ERROR', RGG_IID, actual_iri, null, null,
  15677. sprintf ('The IRI_ID %s of a graph group is the IRI_ID of <%.300s> IRI whereas the group declaration states it is supposed to be <%.300s>',
  15678. cast (RGG_IID as varchar), actual_iri, RGG_IRI ) );
  15679. err_recoverable_count := err_recoverable_count + 1;
  15680. }
  15681. }
  15682. for (select RGG_IID, id_to_iri_nosignal (RGG_IID) as actual_iri, RGG_IRI from DB.DBA.RDF_GRAPH_GROUP
  15683. where (id_to_iri_nosignal (RGG_IID) <> __bft (RGG_IRI, 1))
  15684. and (id_to_iri_nosignal (RGG_IID) = 'http://www.openlinksw.com/schemas/virtrdf#PrivateGraphs' or RGG_IRI = 'http://www.openlinksw.com/schemas/virtrdf#PrivateGraphs') ) do
  15685. {
  15686. result ('FATAL', RGG_IID, actual_iri, null, null,
  15687. sprintf ('The IRI_ID and IRI of a virtrdf:PrivateGraphs graph group does not match to each other, it means that some application has made a security hole. You may wish to disable any access to the database while the error is not fixed.',
  15688. cast (RGG_IID as varchar), actual_iri, RGG_IRI ) );
  15689. return;
  15690. }
  15691. -- dbg_obj_princ ('Check for memberships in nonexisting graph groups...');
  15692. for (select distinct RGGM_GROUP_IID as new_group_iid, iri_to_id_nosignal (RGGM_GROUP_IID) as new_group_iri from DB.DBA.RDF_GRAPH_GROUP_MEMBER
  15693. where not exists (select 1 from DB.DBA.RDF_GRAPH_GROUP where RGG_IID = RGGM_GROUP_IID) for update) do
  15694. {
  15695. if (new_group_iri is null)
  15696. {
  15697. result ('ERROR', new_group_iid, new_group_iri, null, null,
  15698. sprintf ('Garbage in list of members of all groups: the group does not exists and group IRI ID is invalid') );
  15699. err_recoverable_count := err_recoverable_count + 1;
  15700. if (recovery)
  15701. {
  15702. delete from DB.DBA.RDF_GRAPH_GROUP_MEMBER where RGGM_GROUP_IID = new_group_iid;
  15703. commit work;
  15704. }
  15705. }
  15706. else if (exists (select 1 from DB.DBA.RDF_GRAPH_GROUP where RGG_IRI = new_group_iri))
  15707. {
  15708. result ('ERROR', new_group_iid, new_group_iri, null, null,
  15709. sprintf ('Conflicting data in list of groups: the group does not exists, the group IRI is used in a corrupted group record') );
  15710. err_recoverable_count := err_recoverable_count + 1;
  15711. if (recovery)
  15712. {
  15713. delete from DB.DBA.RDF_GRAPH_GROUP_MEMBER where RGGM_GROUP_IID = new_group_iid;
  15714. commit work;
  15715. }
  15716. }
  15717. else
  15718. {
  15719. result ('ERROR', new_group_iid, new_group_iri, null, null,
  15720. sprintf ('The record about graph group does not exist but there exists a list of members') );
  15721. err_recoverable_count := err_recoverable_count + 1;
  15722. if (recovery)
  15723. {
  15724. insert soft DB.DBA.RDF_GRAPH_GROUP (RGG_IID, RGG_IRI, RGG_MEMBER_PATTERN, RGG_COMMENT)
  15725. values (new_group_iid, new_group_iri, NULL, sprintf ('Group created %s by DB.DBA.RDF_GRAPH_SECURITY_AUDIT()', cast (now() as varchar)));
  15726. commit work;
  15727. }
  15728. }
  15729. }
  15730. err_count_total := err_count_total + err_recoverable_count + err_bad_count;
  15731. err_recoverable_count_total := err_recoverable_count_total + err_recoverable_count;
  15732. result ('', null, null, null, null, 'Inspecting caching of list of private graphs...');
  15733. err_bad_count := 0;
  15734. err_recoverable_count := 0;
  15735. pg_mem_dict := mem_dict := __rdf_graph_group_of_privates_dict();
  15736. pg_count := (select count (1) from DB.DBA.RDF_GRAPH_GROUP_MEMBER where RGGM_GROUP_IID = iri_to_id ('http://www.openlinksw.com/schemas/virtrdf#PrivateGraphs'));
  15737. -- dbg_obj_princ ('Inspecting caching of list of private graphs (', pg_mem_dict, ' items in memory, ', pg_count, ' items in the table) ...');
  15738. if (dict_size (mem_dict) <> pg_count)
  15739. {
  15740. result ('ERROR', null, null, null, null,
  15741. sprintf ('Cache of list of private graphs contains %d items, but virtrdf:PrivateGraphs group contains %d members, mismatch',
  15742. dict_size (mem_dict), pg_count ) );
  15743. err_recoverable_count := err_recoverable_count + 1;
  15744. }
  15745. mem_vec := dict_list_keys (mem_dict, 0);
  15746. mem_count := length (mem_vec);
  15747. for (mem_ctr := 0; mem_ctr < mem_count; mem_ctr := mem_ctr + 1)
  15748. {
  15749. declare mem_iid IRI_ID;
  15750. mem_iid := mem_vec[mem_ctr];
  15751. if (not exists (select 1 from DB.DBA.RDF_GRAPH_GROUP_MEMBER
  15752. where RGGM_GROUP_IID = iri_to_id ('http://www.openlinksw.com/schemas/virtrdf#PrivateGraphs')
  15753. and RGGM_MEMBER_IID = mem_iid ) )
  15754. {
  15755. result ('ERROR', mem_iid, id_to_iri_nosignal (mem_iid), null, null,
  15756. sprintf ('Cache of list of private graphs contains IRI_ID %s for graph IRI <%.300s> but virtrdf:PrivateGraphs group does not contain it',
  15757. cast (mem_iid as varchar), id_to_iri_nosignal (mem_iid) ) );
  15758. err_recoverable_count := err_recoverable_count + 1;
  15759. if (recovery)
  15760. {
  15761. insert soft DB.DBA.RDF_GRAPH_GROUP_MEMBER (RGGM_GROUP_IID, RGGM_MEMBER_IID)
  15762. values (iri_to_id ('http://www.openlinksw.com/schemas/virtrdf#PrivateGraphs'), mem_iid);
  15763. commit work;
  15764. }
  15765. }
  15766. if (0 = mod (mem_ctr, 100000))
  15767. {
  15768. -- dbg_obj_princ ('...', mem_ctr, '/', mem_count, ' in-memory private graphs done...');
  15769. ;
  15770. }
  15771. }
  15772. -- dbg_obj_princ ('...reverse check...');
  15773. for (select RGGM_MEMBER_IID from DB.DBA.RDF_GRAPH_GROUP_MEMBER
  15774. where RGGM_GROUP_IID = iri_to_id ('http://www.openlinksw.com/schemas/virtrdf#PrivateGraphs') ) do
  15775. {
  15776. if (not dict_get (mem_dict, RGGM_MEMBER_IID, 0))
  15777. {
  15778. result ('ERROR', RGGM_MEMBER_IID, id_to_iri_nosignal (RGGM_MEMBER_IID), null, null,
  15779. sprintf ('Cache of list of private graphs does not contain IRI_ID %s of graph IRI <%.300s> but virtrdf:PrivateGraphs group contains it',
  15780. cast (RGGM_MEMBER_IID as varchar), id_to_iri_nosignal (RGGM_MEMBER_IID) ) );
  15781. err_recoverable_count := err_recoverable_count + 1;
  15782. if (recovery)
  15783. dict_put (mem_dict, RGGM_MEMBER_IID, 1);
  15784. }
  15785. }
  15786. err_count_total := err_count_total + err_recoverable_count + err_bad_count;
  15787. err_recoverable_count_total := err_recoverable_count_total + err_recoverable_count;
  15788. -- dbg_obj_princ ('Inspecting permissions of users...');
  15789. result ('', null, null, null, null, 'Inspecting permissions of users...');
  15790. err_bad_count := 0;
  15791. err_recoverable_count := 0;
  15792. for (select RGU_USER_ID
  15793. from (select distinct RGU_USER_ID from DB.DBA.RDF_GRAPH_USER rgu) dist_rgu
  15794. where not exists (select 1 from DB.DBA.SYS_USERS where U_ID = RGU_USER_ID) ) do
  15795. {
  15796. result ('ERROR', NULL, NULL, RGU_USER_ID, null,
  15797. sprintf ('Garbage in table DB.DBA.RDF_GRAPH_USER: permissions are specified for nonexisting user ID') );
  15798. err_recoverable_count := err_recoverable_count + 1;
  15799. if (recovery)
  15800. DB.DBA.RDF_ALL_USER_PERMS_DEL (null, RGU_USER_ID);
  15801. }
  15802. for (select special.RGU_GRAPH_IID as s_g_iid, special.RGU_USER_ID as s_userid, special.RGU_PERMISSIONS as s_perms,
  15803. common.RGU_GRAPH_IID as c_g_iid, common.RGU_USER_ID as c_userid, common.RGU_PERMISSIONS as c_p
  15804. from DB.DBA.RDF_GRAPH_USER special, DB.DBA.RDF_GRAPH_USER common
  15805. where (common.RGU_GRAPH_IID = special.RGU_GRAPH_IID
  15806. and common.RGU_USER_ID = http_nobody_uid() and special.RGU_USER_ID <> http_nobody_uid()
  15807. and bit_and (common.RGU_PERMISSIONS, special.RGU_PERMISSIONS) < common.RGU_PERMISSIONS )
  15808. union select special.RGU_GRAPH_IID, special.RGU_USER_ID, special.RGU_PERMISSIONS,
  15809. common.RGU_GRAPH_IID, common.RGU_USER_ID, common.RGU_PERMISSIONS
  15810. from DB.DBA.RDF_GRAPH_USER special, DB.DBA.RDF_GRAPH_USER common
  15811. where (common.RGU_GRAPH_IID = #i8192 and dict_get (pg_mem_dict, special.RGU_GRAPH_IID, 0)
  15812. and common.RGU_USER_ID = http_nobody_uid() and special.RGU_USER_ID <> http_nobody_uid()
  15813. and bit_and (common.RGU_PERMISSIONS, special.RGU_PERMISSIONS) < common.RGU_PERMISSIONS )
  15814. union select special.RGU_GRAPH_IID, special.RGU_USER_ID, special.RGU_PERMISSIONS,
  15815. common.RGU_GRAPH_IID, common.RGU_USER_ID, common.RGU_PERMISSIONS
  15816. from DB.DBA.RDF_GRAPH_USER special, DB.DBA.RDF_GRAPH_USER common
  15817. where (common.RGU_GRAPH_IID = #i0 and special.RGU_GRAPH_IID <> #i8192 and not dict_get (pg_mem_dict, special.RGU_GRAPH_IID, 0)
  15818. and common.RGU_USER_ID = http_nobody_uid() and special.RGU_USER_ID <> http_nobody_uid()
  15819. and bit_and (common.RGU_PERMISSIONS, special.RGU_PERMISSIONS) < common.RGU_PERMISSIONS )
  15820. union select special.RGU_GRAPH_IID, special.RGU_USER_ID, special.RGU_PERMISSIONS,
  15821. common.RGU_GRAPH_IID, common.RGU_USER_ID, common.RGU_PERMISSIONS
  15822. from DB.DBA.RDF_GRAPH_USER special, DB.DBA.RDF_GRAPH_USER common
  15823. where (common.RGU_GRAPH_IID = #i8192 and dict_get (pg_mem_dict, special.RGU_GRAPH_IID, 0)
  15824. and common.RGU_USER_ID = special.RGU_USER_ID
  15825. and bit_and (common.RGU_PERMISSIONS, special.RGU_PERMISSIONS) < common.RGU_PERMISSIONS )
  15826. union select special.RGU_GRAPH_IID, special.RGU_USER_ID, special.RGU_PERMISSIONS,
  15827. common.RGU_GRAPH_IID, common.RGU_USER_ID, common.RGU_PERMISSIONS
  15828. from DB.DBA.RDF_GRAPH_USER special, DB.DBA.RDF_GRAPH_USER common
  15829. where (common.RGU_GRAPH_IID = #i0 and special.RGU_GRAPH_IID <> #i8192 and not dict_get (pg_mem_dict, special.RGU_GRAPH_IID, 0)
  15830. and common.RGU_USER_ID = special.RGU_USER_ID
  15831. and bit_and (common.RGU_PERMISSIONS, special.RGU_PERMISSIONS) < common.RGU_PERMISSIONS )
  15832. order by c_userid, c_g_iid ) do
  15833. {
  15834. declare c_g_iri_txt varchar;
  15835. c_g_iri_txt := case (c_g_iid) when #i0 then 'default public graph' when #i8192 then 'default private graph' else sprintf ('graph <%.300s>', id_to_iri_nosignal (c_g_iid)) end;
  15836. result ('ERROR', s_g_iid, id_to_iri_nosignal (s_g_iid), s_userid, (select U_NAME from DB.DBA.SYS_USERS where U_ID = s_userid),
  15837. sprintf ('Specific permissions %x are smaller than %s permissions %x of user %s',
  15838. s_perms, c_g_iri_txt, c_p, (select U_NAME from DB.DBA.SYS_USERS where U_ID = c_userid) ) );
  15839. err_bad_count := err_bad_count + 1;
  15840. if (s_g_iid = sparql_u_id)
  15841. {
  15842. user_sparql_half_protects_from_extra_access := 1;
  15843. result ('ERROR', s_g_iid, id_to_iri_nosignal (s_g_iid), s_userid, (select U_NAME from DB.DBA.SYS_USERS where U_ID = s_userid),
  15844. 'Note that The fix of above error by removal of all SPARQL''s permissions can give more access rights to users of ill applications that re-used "SPARQL" account' );
  15845. }
  15846. }
  15847. err_count_total := err_count_total + err_recoverable_count + err_bad_count;
  15848. err_recoverable_count_total := err_recoverable_count_total + err_recoverable_count;
  15849. -- dbg_obj_princ ('Inspecting SPARQL user...');
  15850. result ('', null, null, null, null, 'Inspecting SPARQL user...');
  15851. err_bad_count := 0;
  15852. err_recoverable_count := 0;
  15853. if (sparql_u_id is null)
  15854. {
  15855. result ('WARNING', null, null, sparql_u_id, 'SPARQL', 'The "SPARQL" user does not exist. It is not a security issue (no account --- no related leaks), just unusual');
  15856. }
  15857. else
  15858. {
  15859. if (exists (select 1 from DB.DBA.SYS_USERS where U_NAME='SPARQL' and not U_ACCOUNT_DISABLED))
  15860. {
  15861. result ('ERROR', null, null, sparql_u_id, 'SPARQL', 'The "SPARQL" user should be disabled. Applications should create separate accounts and grant SPARQL_SELECT etc., the account "SPARQL" is for system purposes only');
  15862. err_recoverable_count := err_recoverable_count + 1;
  15863. if (recovery)
  15864. {
  15865. update DB.DBA.SYS_USERS set U_ACCOUNT_DISABLED = 1 where U_NAME='SPARQL';
  15866. commit work;
  15867. }
  15868. }
  15869. if (not user_sparql_half_protects_from_extra_access)
  15870. {
  15871. declare user_sparql_has_perms integer;
  15872. user_sparql_has_perms := 0;
  15873. for (select RGU_GRAPH_IID from DB.DBA.RDF_GRAPH_USER where RGU_USER_ID = sparql_u_id) do
  15874. {
  15875. result ('ERROR', RGU_GRAPH_IID, id_to_iri_nosignal (RGU_GRAPH_IID), sparql_u_id, 'SPARQL', 'The "SPARQL" user has got some specific permissions. That''s strange and redundand, at best, it may also mislead somebody');
  15876. err_recoverable_count := err_recoverable_count + 1;
  15877. user_sparql_has_perms := 1;
  15878. }
  15879. if (user_sparql_has_perms and recovery)
  15880. DB.DBA.RDF_ALL_USER_PERMS_DEL ('SPARQL');
  15881. }
  15882. }
  15883. err_count_total := err_count_total + err_recoverable_count + err_bad_count;
  15884. err_recoverable_count_total := err_recoverable_count_total + err_recoverable_count;
  15885. if (0 = err_count_total)
  15886. result ('', null, null, null, null,
  15887. sprintf ('No errors found in RDF security', err_count_total) );
  15888. else if (recovery)
  15889. result ('', null, null, null, null,
  15890. sprintf ('%d security errors were found, DB.DBA.RDF_GRAPH_SECURITY_AUDIT (0) will list errors that may remain unfixed', err_count_total) );
  15891. else if (err_recoverable_count_total)
  15892. result ('', null, null, null, null,
  15893. sprintf ('%d security errors found, you may wish to run DB.DBA.RDF_GRAPH_SECURITY_AUDIT (1) to repair', err_count_total) );
  15894. else
  15895. result ('', null, null, null, null,
  15896. sprintf ('%d security errors found and none of them can be repaired by DB.DBA.RDF_GRAPH_SECURITY_AUDIT (1)', err_count_total) );
  15897. -- dbg_obj_princ ('Starting RDF Graph Security Audit complete, ', err_recoverable_count_total, '/', err_count_total, ' recoverable/total errors.');
  15898. }
  15899. ;
  15900. -----
  15901. -- Loading default set of quad map metadata.
  15902. create procedure DB.DBA.SPARQL_RELOAD_QM_GRAPH ()
  15903. {
  15904. declare ver varchar;
  15905. declare inx int;
  15906. ver := '2014-02-20 0001v7';
  15907. if (USER <> 'dba')
  15908. signal ('RDFXX', 'Only DBA can reload quad map metadata');
  15909. if (not exists (sparql define input:storage "" ask where {
  15910. graph <http://www.openlinksw.com/schemas/virtrdf#> {
  15911. <http://www.openlinksw.com/sparql/virtrdf-data-formats.ttl>
  15912. virtrdf:version ?:ver
  15913. } } ) )
  15914. {
  15915. declare txt1, txt2 varchar;
  15916. declare jso_sys_g_iid IRI_ID;
  15917. declare dict1, lst1, dict2, lst2, sum_lst any;
  15918. txt1 := cast ( DB.DBA.XML_URI_GET (
  15919. 'http://www.openlinksw.com/sparql/virtrdf-data-formats.ttl', '' ) as varchar );
  15920. txt2 := '
  15921. @prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .
  15922. @prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> .
  15923. @prefix owl: <http://www.w3.org/2002/07/owl#> .
  15924. @prefix xsd: <http://www.w3.org/2001/XMLSchema#> .
  15925. @prefix virtrdf: <http://www.openlinksw.com/schemas/virtrdf#> .
  15926. @prefix rdfdf: <http://www.openlinksw.com/virtrdf-data-formats#> .
  15927. virtrdf:DefaultQuadStorage
  15928. rdf:type virtrdf:QuadStorage ;
  15929. virtrdf:qsUserMaps virtrdf:DefaultQuadStorage-UserMaps ;
  15930. virtrdf:qsDefaultMap virtrdf:DefaultQuadMap ;
  15931. virtrdf:qsMatchingFlags virtrdf:SPART_QS_NO_IMPLICIT_USER_QM .
  15932. virtrdf:DefaultQuadStorage-UserMaps
  15933. rdf:type virtrdf:array-of-QuadMap .
  15934. virtrdf:DefaultServiceStorage
  15935. rdf:type virtrdf:QuadStorage ;
  15936. virtrdf:qsUserMaps virtrdf:DefaultServiceStorage-UserMaps ;
  15937. virtrdf:qsDefaultMap virtrdf:DefaultServiceMap ;
  15938. virtrdf:qsMatchingFlags virtrdf:SPART_QS_NO_IMPLICIT_USER_QM .
  15939. virtrdf:DefaultServiceStorage-UserMaps
  15940. rdf:type virtrdf:array-of-QuadMap .
  15941. virtrdf:SyncToQuads
  15942. rdf:type virtrdf:QuadStorage ;
  15943. virtrdf:qsUserMaps virtrdf:SyncToQuads-UserMaps .
  15944. virtrdf:SyncToQuads-UserMaps
  15945. rdf:type virtrdf:array-of-QuadMap .
  15946. ';
  15947. jso_sys_g_iid := iri_to_id (JSO_SYS_GRAPH ());
  15948. dict1 := DB.DBA.RDF_TTL2HASH (txt1, '');
  15949. dict2 := DB.DBA.RDF_TTL2HASH (txt2, '');
  15950. lst1 := dict_list_keys (dict1, 1);
  15951. lst2 := dict_list_keys (dict2, 1);
  15952. sum_lst := vector_concat (lst1, lst2);
  15953. inx := 0;
  15954. foreach (any triple in sum_lst) do
  15955. {
  15956. if ((triple[1] = iri_to_id ('http://www.w3.org/1999/02/22-rdf-syntax-ns#type')) and
  15957. isiri_id (triple[2]) and (triple[2] = iri_to_id ('http://www.openlinksw.com/schemas/virtrdf#QuadMapFormat')))
  15958. {
  15959. -- dbg_obj_princ ('will delete whole ', id_to_iri (triple[0]));
  15960. delete from DB.DBA.RDF_QUAD where G = jso_sys_g_iid and S = triple[0];
  15961. }
  15962. else
  15963. delete from DB.DBA.RDF_QUAD where G = jso_sys_g_iid and S = triple[0] and P = triple[1];
  15964. if (
  15965. triple[0] = iri_to_id ('http://www.openlinksw.com/sparql/virtrdf-data-formats.ttl')
  15966. and
  15967. triple[1] = iri_to_id ('http://www.openlinksw.com/schemas/virtrdf#version')
  15968. and
  15969. triple[2] <> ver
  15970. )
  15971. {
  15972. log_message (sprintf ('RDF metadata version: %s', ver));
  15973. triple[2] := ver;
  15974. sum_lst[inx] := triple;
  15975. }
  15976. inx := inx + 1;
  15977. }
  15978. DB.DBA.RDF_INSERT_TRIPLES (jso_sys_g_iid, sum_lst);
  15979. commit work;
  15980. cl_exec ('checkpoint');
  15981. }
  15982. DB.DBA.JSO_LOAD_AND_PIN_SYS_GRAPH ();
  15983. sequence_set ('RDF_URL_IID_NAMED', 1010000, 1);
  15984. sequence_set ('RDF_URL_IID_BLANK', iri_id_num (min_bnode_iri_id ()) + 10000, 1);
  15985. sequence_set ('RDF_URL_IID_NAMED_BLANK', iri_id_num (min_named_bnode_iri_id ()) + 10000, 1);
  15986. sequence_set ('RDF_PREF_SEQ', 101, 1);
  15987. sequence_set ('RDF_RO_ID', 1001, 1);
  15988. }
  15989. ;
  15990. create procedure DB.DBA.RDF_CREATE_SPARQL_ROLES ()
  15991. {
  15992. declare state, msg varchar;
  15993. declare cmds any;
  15994. cmds := vector (
  15995. 'create role SPARQL_SELECT',
  15996. 'create role SPARQL_SPONGE',
  15997. 'create role SPARQL_UPDATE',
  15998. 'grant SPARQL_SELECT to SPARQL_UPDATE',
  15999. 'grant SPARQL_SELECT to SPARQL_SPONGE',
  16000. 'grant SPARQL_SPONGE to SPARQL_UPDATE',
  16001. 'grant select on DB.DBA.RDF_QUAD to SPARQL_SELECT',
  16002. 'grant all on DB.DBA.RDF_QUAD to SPARQL_UPDATE',
  16003. 'grant select on DB.DBA.RDF_PREFIX to SPARQL_SELECT',
  16004. 'grant all on DB.DBA.RDF_PREFIX to SPARQL_UPDATE',
  16005. 'grant select on DB.DBA.RDF_IRI to SPARQL_SELECT',
  16006. 'grant all on DB.DBA.RDF_IRI to SPARQL_UPDATE',
  16007. 'grant select on DB.DBA.RDF_OBJ to SPARQL_SELECT',
  16008. 'grant all on DB.DBA.RDF_OBJ to SPARQL_UPDATE',
  16009. --'grant select on DB.DBA.RDF_FT to SPARQL_SELECT',
  16010. --'grant all on DB.DBA.RDF_FT to SPARQL_UPDATE',
  16011. 'grant select on DB.DBA.RDF_DATATYPE to SPARQL_SELECT',
  16012. 'grant all on DB.DBA.RDF_DATATYPE to SPARQL_UPDATE',
  16013. 'grant select on DB.DBA.RDF_LANGUAGE to SPARQL_SELECT',
  16014. 'grant all on DB.DBA.RDF_LANGUAGE to SPARQL_UPDATE',
  16015. 'grant select on DB.DBA.SYS_SPARQL_HOST to SPARQL_SELECT',
  16016. 'grant all on DB.DBA.SYS_SPARQL_HOST to SPARQL_UPDATE',
  16017. 'grant select on DB.DBA.RDF_EXPLICITLY_CREATED_GRAPH to SPARQL_SELECT',
  16018. 'grant all on DB.DBA.RDF_EXPLICITLY_CREATED_GRAPH to SPARQL_UPDATE',
  16019. 'grant select on DB.DBA.SYS_IDONLY_EMPTY to SPARQL_SELECT',
  16020. 'grant select on DB.DBA.SYS_IDONLY_ONE to SPARQL_SELECT',
  16021. 'grant execute on DB.DBA.RDF_GLOBAL_RESET to SPARQL_UPDATE',
  16022. 'grant execute on DB.DBA.RDF_MAKE_IID_OF_QNAME to SPARQL_SELECT',
  16023. 'grant execute on DB.DBA.RDF_MAKE_IID_OF_QNAME_SAFE to SPARQL_SELECT',
  16024. 'grant execute on DB.DBA.RDF_MAKE_IID_OF_LONG to SPARQL_SELECT',
  16025. 'grant execute on DB.DBA.RDF_QNAME_OF_IID to SPARQL_SELECT', -- DEPRECATED
  16026. 'grant execute on DB.DBA.RDF_MAKE_GRAPH_IIDS_OF_QNAMES to SPARQL_SELECT',
  16027. 'grant execute on DB.DBA.RDF_TWOBYTE_OF_DATATYPE to SPARQL_SELECT',
  16028. 'grant execute on DB.DBA.RDF_TWOBYTE_OF_LANGUAGE to SPARQL_SELECT',
  16029. 'grant execute on DB.DBA.RQ_LONG_OF_O to SPARQL_SELECT', -- DEPRECATED
  16030. 'grant execute on DB.DBA.RQ_SQLVAL_OF_O to SPARQL_SELECT', -- DEPRECATED
  16031. 'grant execute on DB.DBA.RDF_BOOL_OF_O to SPARQL_SELECT',
  16032. 'grant execute on DB.DBA.RQ_IID_OF_O to SPARQL_SELECT', -- DEPRECATED
  16033. 'grant execute on DB.DBA.RQ_O_IS_LIT to SPARQL_SELECT', -- DEPRECATED
  16034. 'grant execute on DB.DBA.RDF_OBJ_ADD to SPARQL_SELECT',
  16035. 'grant execute on DB.DBA.RDF_OBJ_FIND_EXISTING to SPARQL_SELECT',
  16036. 'grant execute on DB.DBA.RDF_MAKE_OBJ_OF_SQLVAL to SPARQL_SELECT',
  16037. 'grant execute on DB.DBA.RDF_MAKE_OBJ_OF_SQLVAL_FT to SPARQL_SELECT',
  16038. 'grant execute on DB.DBA.RDF_MAKE_OBJ_OF_TYPEDSQLVAL to SPARQL_SELECT',
  16039. 'grant execute on DB.DBA.RDF_MAKE_OBJ_OF_TYPEDSQLVAL_FT to SPARQL_SELECT',
  16040. 'grant execute on DB.DBA.RDF_MAKE_OBJ_OF_TYPEDSQLVAL_STRINGS to SPARQL_SELECT',
  16041. 'grant execute on DB.DBA.RDF_LONG_OF_OBJ to SPARQL_SELECT', -- DEPRECATED
  16042. 'grant execute on DB.DBA.RDF_DATATYPE_OF_OBJ to SPARQL_SELECT',
  16043. 'grant execute on DB.DBA.RDF_LANGUAGE_OF_OBJ to SPARQL_SELECT',
  16044. 'grant execute on DB.DBA.RDF_SQLVAL_OF_OBJ to SPARQL_SELECT', -- DEPRECATED
  16045. 'grant execute on DB.DBA.RDF_BOOL_OF_OBJ to SPARQL_SELECT',
  16046. 'grant execute on DB.DBA.RDF_QNAME_OF_OBJ to SPARQL_SELECT', -- DEPRECATED
  16047. 'grant execute on DB.DBA.RDF_STRSQLVAL_OF_OBJ to SPARQL_SELECT',
  16048. 'grant execute on DB.DBA.RDF_OBJ_OF_LONG to SPARQL_SELECT',
  16049. 'grant execute on DB.DBA.RDF_OBJ_OF_SQLVAL to SPARQL_SELECT',
  16050. 'grant execute on DB.DBA.RDF_MAKE_LONG_OF_SQLVAL to SPARQL_SELECT',
  16051. 'grant execute on DB.DBA.RDF_MAKE_LONG_OF_TYPEDSQLVAL to SPARQL_SELECT',
  16052. 'grant execute on DB.DBA.RDF_MAKE_LONG_OF_TYPEDSQLVAL_STRINGS to SPARQL_SELECT',
  16053. 'grant execute on DB.DBA.RDF_QNAME_OF_LONG_SAFE to SPARQL_SELECT', -- DEPRECATED
  16054. 'grant execute on DB.DBA.RDF_SQLVAL_OF_LONG to SPARQL_SELECT', -- DEPRECATED
  16055. 'grant execute on DB.DBA.RDF_BOOL_OF_LONG to SPARQL_SELECT',
  16056. 'grant execute on DB.DBA.RDF_DATATYPE_OF_LONG to SPARQL_SELECT',
  16057. 'grant execute on DB.DBA.RDF_DATATYPE_IRI_OF_LONG to SPARQL_SELECT',
  16058. 'grant execute on DB.DBA.RDF_LANGUAGE_OF_LONG to SPARQL_SELECT',
  16059. 'grant execute on DB.DBA.RDF_STRSQLVAL_OF_LONG to SPARQL_SELECT',
  16060. 'grant execute on DB.DBA.RDF_WIDESTRSQLVAL_OF_LONG to SPARQL_SELECT',
  16061. 'grant execute on DB.DBA.RDF_LONG_OF_SQLVAL to SPARQL_SELECT',
  16062. 'grant execute on DB.DBA.rdf_strdt_impl to SPARQL_SELECT',
  16063. 'grant execute on DB.DBA.rdf_strlang_impl to SPARQL_SELECT',
  16064. 'grant execute on DB.DBA.rdf_uuid_impl to SPARQL_SELECT',
  16065. 'grant execute on DB.DBA.RDF_QUAD_URI to SPARQL_UPDATE',
  16066. 'grant execute on DB.DBA.RDF_QUAD_URI_L to SPARQL_UPDATE',
  16067. 'grant execute on DB.DBA.RDF_QUAD_URI_L_TYPED to SPARQL_UPDATE',
  16068. 'grant execute on DB.DBA.TTLP_EV_NEW_GRAPH to SPARQL_UPDATE',
  16069. 'grant execute on DB.DBA.TTLP_EV_NEW_BLANK to SPARQL_UPDATE',
  16070. 'grant execute on DB.DBA.TTLP_EV_GET_IID to SPARQL_UPDATE',
  16071. 'grant execute on DB.DBA.TTLP_EV_TRIPLE to SPARQL_UPDATE',
  16072. 'grant execute on DB.DBA.TTLP_EV_TRIPLE_L to SPARQL_UPDATE',
  16073. 'grant execute on DB.DBA.TTLP_EV_TRIPLE_XLAT to SPARQL_UPDATE',
  16074. 'grant execute on DB.DBA.TTLP_EV_TRIPLE_L_XLAT to SPARQL_UPDATE',
  16075. 'grant execute on DB.DBA.TTLP to SPARQL_UPDATE',
  16076. 'grant execute on DB.DBA.TTLP_WITH_IRI_TRANSLATION to SPARQL_UPDATE',
  16077. 'grant execute on DB.DBA.RDF_TTL2HASH_EXEC_NEW_GRAPH to SPARQL_SELECT',
  16078. 'grant execute on DB.DBA.RDF_TTL2HASH_EXEC_NEW_BLANK to SPARQL_SELECT',
  16079. 'grant execute on DB.DBA.RDF_TTL2HASH_EXEC_GET_IID to SPARQL_SELECT',
  16080. 'grant execute on DB.DBA.RDF_TTL2HASH_EXEC_TRIPLE to SPARQL_SELECT',
  16081. 'grant execute on DB.DBA.RDF_TTL2HASH_EXEC_TRIPLE_L to SPARQL_SELECT',
  16082. 'grant execute on DB.DBA.RDF_TTL2HASH to SPARQL_SELECT',
  16083. 'grant execute on DB.DBA.RDF_LOAD_RDFXML to SPARQL_UPDATE',
  16084. 'grant execute on DB.DBA.RDF_RDFA11_FETCH_PROFILES to SPARQL_UPDATE',
  16085. 'grant execute on DB.DBA.RDF_LOAD_RDFA to SPARQL_UPDATE',
  16086. 'grant execute on DB.DBA.RDF_LOAD_RDFA_WITH_IRI_TRANSLATION to SPARQL_UPDATE',
  16087. 'grant execute on DB.DBA.RDF_LOAD_XHTML_MICRODATA to SPARQL_UPDATE',
  16088. 'grant execute on DB.DBA.RDF_RDFXML_TO_DICT to SPARQL_UPDATE',
  16089. 'grant execute on DB.DBA.RDF_LONG_TO_TTL to SPARQL_SELECT',
  16090. 'grant execute on DB.DBA.RDF_TRIPLES_TO_TTL to SPARQL_SELECT',
  16091. 'grant execute on DB.DBA.RDF_TRIPLES_TO_TRIG to SPARQL_SELECT',
  16092. 'grant execute on DB.DBA.RDF_TRIPLES_TO_NT to SPARQL_SELECT',
  16093. 'grant execute on DB.DBA.RDF_GRAPH_TO_TTL to SPARQL_SELECT',
  16094. 'grant execute on DB.DBA.RDF_TRIPLES_TO_RDF_XML_TEXT to SPARQL_SELECT',
  16095. 'grant execute on DB.DBA.RDF_TRIPLES_TO_TALIS_JSON to SPARQL_SELECT',
  16096. 'grant execute on DB.DBA.RDF_TRIPLES_TO_JSON_LD to SPARQL_SELECT',
  16097. 'grant execute on DB.DBA.RDF_TRIPLES_TO_CSV to SPARQL_SELECT',
  16098. 'grant execute on DB.DBA.RDF_TRIPLES_TO_TSV to SPARQL_SELECT',
  16099. 'grant execute on DB.DBA.RDF_TRIPLES_TO_RDFA_XHTML to SPARQL_SELECT',
  16100. 'grant execute on DB.DBA.RDF_TRIPLES_TO_HTML_UL to SPARQL_SELECT',
  16101. 'grant execute on DB.DBA.RDF_TRIPLES_TO_HTML_TR to SPARQL_SELECT',
  16102. 'grant execute on DB.DBA.RDF_TRIPLES_TO_HTML_MICRODATA to SPARQL_SELECT',
  16103. 'grant execute on DB.DBA.RDF_TRIPLES_TO_HTML_NICE_MICRODATA to SPARQL_SELECT',
  16104. 'grant execute on DB.DBA.RDF_TRIPLES_TO_HTML_NICE_TTL to SPARQL_SELECT',
  16105. 'grant execute on DB.DBA.RDF_TRIPLES_TO_JSON_MICRODATA to SPARQL_SELECT',
  16106. 'grant execute on DB.DBA.RDF_TRIPLES_TO_ATOM_XML_TEXT to SPARQL_SELECT',
  16107. 'grant execute on DB.DBA.RDF_TRIPLES_TO_ODATA_JSON to SPARQL_SELECT',
  16108. 'grant execute on DB.DBA.RDF_FORMAT_RESULT_SET_AS_TTL_INIT to SPARQL_SELECT',
  16109. 'grant execute on DB.DBA.RDF_FORMAT_RESULT_SET_AS_TTL_ACC to SPARQL_SELECT',
  16110. 'grant execute on DB.DBA.RDF_FORMAT_RESULT_SET_AS_TTL_FIN to SPARQL_SELECT',
  16111. 'grant execute on DB.DBA.RDF_FORMAT_RESULT_SET_AS_NT_INIT to SPARQL_SELECT',
  16112. 'grant execute on DB.DBA.RDF_FORMAT_RESULT_SET_AS_NT_ACC to SPARQL_SELECT',
  16113. 'grant execute on DB.DBA.RDF_FORMAT_RESULT_SET_AS_NT_FIN to SPARQL_SELECT',
  16114. 'grant execute on DB.DBA.RDF_FORMAT_RESULT_SET_AS_RDF_XML_INIT to SPARQL_SELECT',
  16115. 'grant execute on DB.DBA.RDF_FORMAT_RESULT_SET_AS_RDF_XML_ACC to SPARQL_SELECT',
  16116. 'grant execute on DB.DBA.RDF_FORMAT_RESULT_SET_AS_RDF_XML_FIN to SPARQL_SELECT',
  16117. 'grant execute on DB.DBA.RDF_FORMAT_RESULT_SET_AS_HTML_NICE_TTL to SPARQL_SELECT',
  16118. 'grant execute on DB.DBA.RDF_FORMAT_RESULT_SET_AS_JSON_INIT to SPARQL_SELECT',
  16119. 'grant execute on DB.DBA.RDF_FORMAT_RESULT_SET_AS_JSON_ACC to SPARQL_SELECT',
  16120. 'grant execute on DB.DBA.RDF_FORMAT_RESULT_SET_AS_JSON_FIN to SPARQL_SELECT',
  16121. 'grant execute on DB.DBA.RDF_FORMAT_RESULT_SET_AS_CSV_INIT to SPARQL_SELECT',
  16122. 'grant execute on DB.DBA.RDF_FORMAT_RESULT_SET_AS_CSV_ACC to SPARQL_SELECT',
  16123. 'grant execute on DB.DBA.RDF_FORMAT_RESULT_SET_AS_TSV_ACC to SPARQL_SELECT',
  16124. 'grant execute on DB.DBA.RDF_FORMAT_RESULT_SET_AS_CSV_FIN to SPARQL_SELECT',
  16125. 'grant execute on DB.DBA.RDF_FORMAT_RESULT_SET_AS_CXML_INIT to SPARQL_SELECT',
  16126. 'grant execute on DB.DBA.RDF_FORMAT_RESULT_SET_AS_CXML_ACC to SPARQL_SELECT',
  16127. 'grant execute on DB.DBA.RDF_FORMAT_RESULT_SET_AS_CXML_FIN to SPARQL_SELECT',
  16128. 'grant execute on DB.DBA.RDF_FORMAT_TRIPLE_DICT_AS_ATOM_XML to SPARQL_SELECT',
  16129. 'grant execute on DB.DBA.RDF_FORMAT_TRIPLE_DICT_AS_ODATA_JSON to SPARQL_SELECT',
  16130. 'grant execute on DB.DBA.RDF_FORMAT_TRIPLE_DICT_AS_TTL to SPARQL_SELECT',
  16131. 'grant execute on DB.DBA.RDF_FORMAT_TRIPLE_DICT_AS_NICE_TTL to SPARQL_SELECT',
  16132. 'grant execute on DB.DBA.RDF_FORMAT_TRIPLE_DICT_AS_NT to SPARQL_SELECT',
  16133. 'grant execute on DB.DBA.RDF_FORMAT_TRIPLE_DICT_AS_RDF_XML to SPARQL_SELECT',
  16134. 'grant execute on DB.DBA.RDF_FORMAT_TRIPLE_DICT_AS_TALIS_JSON to SPARQL_SELECT',
  16135. 'grant execute on DB.DBA.RDF_FORMAT_TRIPLE_DICT_AS_JSON_LD to SPARQL_SELECT',
  16136. 'grant execute on DB.DBA.RDF_FORMAT_TRIPLE_DICT_AS_HTML_MICRODATA to SPARQL_SELECT',
  16137. 'grant execute on DB.DBA.RDF_FORMAT_TRIPLE_DICT_AS_HTML_NICE_MICRODATA to SPARQL_SELECT',
  16138. 'grant execute on DB.DBA.RDF_FORMAT_TRIPLE_DICT_AS_HTML_NICE_TTL to SPARQL_SELECT',
  16139. 'grant execute on DB.DBA.RDF_FORMAT_TRIPLE_DICT_AS_JSON_MICRODATA to SPARQL_SELECT',
  16140. 'grant execute on DB.DBA.RDF_FORMAT_TRIPLE_DICT_AS_CSV to SPARQL_SELECT',
  16141. 'grant execute on DB.DBA.RDF_FORMAT_TRIPLE_DICT_AS_TSV to SPARQL_SELECT',
  16142. 'grant execute on DB.DBA.RDF_FORMAT_TRIPLE_DICT_AS_RDFA_XHTML to SPARQL_SELECT',
  16143. 'grant execute on DB.DBA.RDF_FORMAT_TRIPLE_DICT_AS_CXML to SPARQL_SELECT',
  16144. 'grant execute on DB.DBA.RDF_FORMAT_TRIPLE_DICT_AS_CXML_QRCODE to SPARQL_SELECT',
  16145. 'grant execute on DB.DBA.RDF_INSERT_TRIPLES to SPARQL_UPDATE',
  16146. 'grant execute on DB.DBA.RDF_DELETE_TRIPLES to SPARQL_UPDATE',
  16147. 'grant execute on DB.DBA.RDF_DELETE_TRIPLES_AGG to SPARQL_UPDATE',
  16148. 'grant execute on DB.DBA.RDF_MODIFY_TRIPLES to SPARQL_UPDATE',
  16149. 'grant execute on DB.DBA.RDF_INSERT_QUADS to SPARQL_UPDATE',
  16150. 'grant execute on DB.DBA.RDF_DELETE_QUADS to SPARQL_UPDATE',
  16151. 'grant execute on DB.DBA.SPARQL_INSERT_DICT_CONTENT to SPARQL_UPDATE',
  16152. 'grant execute on DB.DBA.SPARQL_INSERT_QUAD_DICT_CONTENT to SPARQL_UPDATE',
  16153. 'grant execute on DB.DBA.SPARQL_DELETE_DICT_CONTENT to SPARQL_UPDATE',
  16154. 'grant execute on DB.DBA.SPARQL_DELETE_QUAD_DICT_CONTENT to SPARQL_UPDATE',
  16155. 'grant execute on DB.DBA.SPARQL_MODIFY_BY_DICT_CONTENTS to SPARQL_UPDATE',
  16156. 'grant execute on DB.DBA.SPARQL_MODIFY_BY_QUAD_DICT_CONTENTS to SPARQL_UPDATE',
  16157. 'grant execute on DB.DBA.SPARUL_ADD to SPARQL_UPDATE',
  16158. 'grant execute on DB.DBA.SPARUL_CLEAR to SPARQL_UPDATE',
  16159. 'grant execute on DB.DBA.SPARUL_COPY to SPARQL_UPDATE',
  16160. 'grant execute on SPARUL_LOAD_SERVICE_DATA to SPARQL_SPONGE',
  16161. 'grant execute on DB.DBA.SPARUL_CREATE to SPARQL_UPDATE',
  16162. 'grant execute on DB.DBA.SPARUL_DROP to SPARQL_UPDATE',
  16163. 'grant execute on DB.DBA.SPARUL_LOAD to SPARQL_UPDATE',
  16164. 'grant execute on DB.DBA.SPARUL_LOAD_SERVICE_DATA to SPARQL_UPDATE',
  16165. 'grant execute on DB.DBA.SPARUL_MOVE to SPARQL_UPDATE',
  16166. 'grant execute on DB.DBA.SPARUL_RUN to SPARQL_UPDATE',
  16167. 'grant execute on DB.DBA.SPARQL_SELECT_KNOWN_GRAPHS to SPARQL_SELECT',
  16168. 'grant execute on DB.DBA.SPARQL_DESC_AGG_INIT to SPARQL_SELECT',
  16169. 'grant execute on DB.DBA.SPARQL_DESC_AGG_ACC to SPARQL_SELECT',
  16170. 'grant execute on DB.DBA.SPARQL_DESC_AGG_FIN to SPARQL_SELECT',
  16171. 'grant execute on DB.DBA.SPARQL_DESC_DICT to SPARQL_SELECT',
  16172. 'grant execute on DB.DBA.SPARQL_DESC_DICT_SPO to SPARQL_SELECT',
  16173. 'grant execute on DB.DBA.SPARQL_DESC_DICT_SPO_PHYSICAL to SPARQL_SELECT',
  16174. 'grant execute on DB.DBA.SPARQL_DESC_DICT_CBD to SPARQL_SELECT',
  16175. 'grant execute on DB.DBA.SPARQL_DESC_DICT_CBD_PHYSICAL to SPARQL_SELECT',
  16176. 'grant execute on DB.DBA.SPARQL_DESC_DICT_OBJCBD to SPARQL_SELECT',
  16177. 'grant execute on DB.DBA.SPARQL_DESC_DICT_OBJCBD_PHYSICAL to SPARQL_SELECT',
  16178. 'grant execute on DB.DBA.SPARQL_DESC_DICT_SCBD to SPARQL_SELECT',
  16179. 'grant execute on DB.DBA.SPARQL_DESC_DICT_SCBD_PHYSICAL to SPARQL_SELECT',
  16180. 'grant execute on DB.DBA.SPARQL_CONSTRUCT_INIT to SPARQL_SELECT',
  16181. 'grant execute on DB.DBA.SPARQL_CONSTRUCT_ACC to SPARQL_SELECT',
  16182. 'grant execute on DB.DBA.SPARQL_CONSTRUCT_FIN to SPARQL_SELECT',
  16183. 'grant execute on DB.DBA.RDF_TYPEMIN_OF_OBJ to SPARQL_SELECT',
  16184. 'grant execute on DB.DBA.RDF_TYPEMAX_OF_OBJ to SPARQL_SELECT',
  16185. 'grant execute on DB.DBA.RDF_IID_CMP to SPARQL_SELECT',
  16186. 'grant execute on DB.DBA.RDF_OBJ_CMP to SPARQL_SELECT',
  16187. 'grant execute on DB.DBA.RDF_LONG_CMP to SPARQL_SELECT',
  16188. 'grant execute on DB.DBA.TTLP_MT to SPARQL_UPDATE',
  16189. 'grant execute on DB.DBA.TTLP_MT_LOCAL_FILE to SPARQL_UPDATE',
  16190. 'grant execute on DB.DBA.TTLP_EV_TRIPLE_W to SPARQL_UPDATE',
  16191. 'grant execute on DB.DBA.TTLP_EV_TRIPLE_L_W to SPARQL_UPDATE',
  16192. 'grant execute on DB.DBA.TTLP_EV_NEW_GRAPH_A to SPARQL_UPDATE',
  16193. 'grant execute on DB.DBA.TTLP_EV_TRIPLE_A to SPARQL_UPDATE',
  16194. 'grant execute on DB.DBA.TTLP_EV_TRIPLE_L_A to SPARQL_UPDATE',
  16195. 'grant execute on DB.DBA.TTLP_EV_REPORT_DEFAULT to SPARQL_UPDATE',
  16196. 'grant execute on DB.DBA.RDF_LOAD_RDFXML_MT to SPARQL_UPDATE',
  16197. 'grant execute on DB.DBA.RDF_LOAD_HTTP_RESPONSE to SPARQL_UPDATE',
  16198. 'grant execute on DB.DBA.RDF_FORGET_HTTP_RESPONSE to SPARQL_UPDATE',
  16199. 'grant execute on DB.DBA.TTLP_EV_COMMIT to SPARQL_UPDATE',
  16200. 'grant execute on DB.DBA.RDF_PROC_COLS to "SPARQL"',
  16201. 'grant execute on DB.DBA.RDF_GRAPH_USER_PERMS_ACK to SPARQL_SELECT', -- DEPRECATED
  16202. 'grant execute on DB.DBA.RDF_GRAPH_USER_PERMS_ASSERT to SPARQL_SELECT', -- DEPRECATED
  16203. 'grant execute on DB.DBA.RL_FLUSH to SPARQL_UPDATE',
  16204. 'grant execute on DB.DBA.RDF_OBJ_ADD_KEYWORD_FOR_GRAPH to SPARQL_UPDATE',
  16205. 'grant execute on DB.DBA.RDF_GRAPH_GROUP_LIST_GET to SPARQL_SELECT',
  16206. 'grant execute on L_O_LOOK to SPARQL_SPONGE',
  16207. 'grant execute on RL_I2ID_NP to SPARQL_SPONGE',
  16208. 'grant execute on rl_i2id to SPARQL_SPONGE',
  16209. 'grant execute on DB.DBA.TTLP_RL_TRIPLE to SPARQL_UPDATE',
  16210. 'grant execute on rdf_rl_type_id to SPARQL_UPDATE',
  16211. 'grant execute on rdf_rl_lang_id to SPARQL_UPDATE',
  16212. 'grant execute on DB.DBA.TTLP_RL_TRIPLE_L to SPARQL_UPDATE',
  16213. 'grant execute on DB.DBA.TTLP_RL_NEW_GRAPH to SPARQL_UPDATE',
  16214. 'grant execute on rl_local_dpipe to SPARQL_UPDATE',
  16215. 'grant execute on rl_local_dpipe_gs to SPARQL_UPDATE',
  16216. 'grant execute on RL_FLUSH to SPARQL_UPDATE',
  16217. 'grant execute on rl_send to SPARQL_UPDATE',
  16218. 'grant execute on DB.DBA.TTLP_RL_COMMIT to SPARQL_UPDATE',
  16219. 'grant execute on rl_send_gs to SPARQL_UPDATE',
  16220. 'grant execute on DB.DBA.TTLP_RL_GS_TRIPLE to SPARQL_UPDATE',
  16221. 'grant execute on DB.DBA.TTLP_RL_GS_TRIPLE_L to SPARQL_UPDATE',
  16222. 'grant execute on DB.DBA.TTLP_RL_GS_NEW_GRAPH to SPARQL_UPDATE',
  16223. 'grant execute on DB.DBA.TTLP_EV_NULL_IID to SPARQL_UPDATE',
  16224. 'grant execute on TTLP_V_GS to SPARQL_UPDATE',
  16225. 'grant execute on DB.DBA.TTLP_V to SPARQL_UPDATE',
  16226. 'grant execute on DB.DBA.RDF_LOAD_RDFXML_V to SPARQL_UPDATE',
  16227. 'grant execute on ID_TO_IRI_VEC to SPARQL_UPDATE' );
  16228. foreach (varchar cmd in cmds) do
  16229. {
  16230. exec (cmd, state, msg);
  16231. }
  16232. }
  16233. ;
  16234. create procedure DB.DBA.RDF_QUAD_AUDIT ()
  16235. {
  16236. declare stat, msg varchar;
  16237. declare err_dict any;
  16238. result_names (stat, msg);
  16239. if (exists (select top 1 1 from DB.DBA.SYS_COLS
  16240. where "TABLE" = fix_identifier_case ('DB.DBA.RDF_OBJ_RO_FLAGS_WORDS')
  16241. and "COLUMN" = fix_identifier_case ('VT_WORD') )
  16242. and exists (select top 1 1 from DB.DBA.SYS_COLS
  16243. where "TABLE" = fix_identifier_case ('DB.DBA.RDF_OBJ')
  16244. and "COLUMN" = fix_identifier_case ('RO_FLAGS')
  16245. and COL_DTP = 188 ) )
  16246. goto check_new_style;
  16247. err_dict := dict_new ();
  16248. if (isstring (registry_get ('DB.DBA.RDF_QUAD_FT_UPGRADE')))
  16249. {
  16250. result ('ERRol', 'old layout but isstring (registry_get (''DB.DBA.RDF_QUAD_FT_UPGRADE''))');
  16251. return;
  16252. }
  16253. for (select O as o_old from DB.DBA.RDF_QUAD where isstring (O)) do
  16254. {
  16255. declare o_old_len integer;
  16256. declare o_long any;
  16257. declare o_strval varchar;
  16258. declare val_len, o_id integeR;
  16259. declare o_dt, o_lang integeR;
  16260. o_old_len := length (o_old);
  16261. if (dict_size (err_dict) > 10000)
  16262. {
  16263. result ('ERRxx', 'Too many errors, bye');
  16264. return;
  16265. }
  16266. if (dict_get (err_dict, o_old, 0))
  16267. goto known_bug;
  16268. if (o_old_len = 29)
  16269. {
  16270. if (o_old [22] <> 0)
  16271. { result ('ERRol', sprintf ('ill literal |%U| (escaped like URL)', o_old)); dict_put (err_dict, o_old, 1); }
  16272. else
  16273. {
  16274. o_long := jso_parse_digest (o_old);
  16275. o_strval := (select case (isnull (RO_LONG)) when 0 then blob_to_string (RO_LONG) else RO_VAL end from DB.DBA.RDF_OBJ where RO_ID = o_long[3]);
  16276. if (o_strval is null)
  16277. { result ('ERRol', sprintf ('Non-existing RO_ID %d in literal |%U| (escaped like URL)', o_long[3], o_old)); dict_put (err_dict, o_old, 1); }
  16278. else if ("LEFT" (o_strval, 20) <> o_long[1])
  16279. { result ('ERRol', sprintf ('Full value of RO_ID %d starts with |%U|, does not match to literal |%U| (escaped like URL)', o_long[3], "LEFT" (o_strval, 20), o_old)); dict_put (err_dict, o_old, 1); }
  16280. o_dt := o_long[0];
  16281. o_lang := o_long[2];
  16282. }
  16283. }
  16284. else if (o_old_len < 5)
  16285. { result ('ERRot', sprintf ('ill literal |%U| (escaped like URL)', o_old)); dict_put (err_dict, o_old, 1); }
  16286. else if (o_old_len < 29)
  16287. {
  16288. val_len := length (o_old) - 5;
  16289. o_dt := o_old[0] + o_old[1]*256;
  16290. o_lang := o_old[val_len+3] + o_old[val_len+4]*256;
  16291. if ((o_old [val_len+2] <> 0) or 0 = o_old[0] or 0 = o_old[1] or 0 = o_old[val_len+3] or 0 = o_old[val_len+4])
  16292. { result ('ERRos', sprintf ('ill short literal |%U| (escaped like URL)', o_old)); dict_put (err_dict, o_old, 1); }
  16293. }
  16294. else
  16295. { result ('ERRoh', sprintf ('Too long literal |%U| (truncated, escaped like URL)', "LEFT" (o_old, 100))); dict_put (err_dict, o_old, 1); }
  16296. known_bug: ;
  16297. }
  16298. return;
  16299. check_new_style:
  16300. if (not isstring (registry_get ('DB.DBA.RDF_QUAD_FT_UPGRADE')))
  16301. result ('ERRft', 'new layout but not isstring (registry_get (''DB.DBA.RDF_QUAD_FT_UPGRADE''))');
  16302. }
  16303. ;
  16304. create procedure DB.DBA.RDF_QUAD_OUTLINE_ALL (in force integer := 0)
  16305. {
  16306. declare c_main, c_pogs, c_op integer;
  16307. declare c_main_tmp, c_pogs_tmp, c_op_tmp, old_mode integer;
  16308. declare c_main_fixed, c_pogs_fixed, c_op_fixed integer;
  16309. declare c_check char;
  16310. if ((registry_get ('__rb_id_only_for_plain_ro_obj') = '1') and not force)
  16311. return;
  16312. if (0 = sys_stat ('db_exists') or not exists (select top 1 1 from DB.DBA.RDF_QUAD option (no cluster)))
  16313. {
  16314. registry_set ('__rb_id_only_for_plain_ro_obj', '1');
  16315. return;
  16316. }
  16317. log_message ('This database may contain RDF data that could cause indexing problems on previous versions of the server.');
  16318. log_message ('The content of the DB.DBA.RDF_QUAD table will be checked and an update may automatically be performed if');
  16319. log_message ('such data is found.');
  16320. log_message ('This check will take some time but is made only once.');
  16321. if (not exists (select top 1 1 from DB.DBA.RDF_QUAD table option (index RDF_QUAD_OP, index_only) where rdf_box_migrate_after_06_02_3129 (O)))
  16322. {
  16323. log_message ('No need to update DB.DBA.RDF_QUAD.');
  16324. registry_set ('__rb_id_only_for_plain_ro_obj', '1');
  16325. exec ('checkpoint');
  16326. return;
  16327. }
  16328. if (coalesce (virtuoso_ini_item_value ('SPARQL', 'RecoveryMode'), '0') > '0')
  16329. {
  16330. log_message ('Update skipped in recovery mode');
  16331. return;
  16332. }
  16333. log_message ('An update is required.');
  16334. c_check := coalesce (virtuoso_ini_item_value ('Parameters', 'AnalyzeFixQuadStore'), '0');
  16335. if (coalesce (virtuoso_ini_item_value ('Parameters', 'LiteMode'), '0') <> '0') c_check := '1';
  16336. if (c_check <> '1')
  16337. {
  16338. log_message ('');
  16339. log_message ('NOTICE: Before Virtuoso can continue fixing the DB.DBA.RDF_QUAD table and its indexes');
  16340. log_message (' the DB Administrator should check make sure that:');
  16341. log_message ('');
  16342. log_message (' * there is a recent backup of the database');
  16343. log_message (' * there is enough free disk space available to complete this conversion');
  16344. log_message (' * the database can be offline for the duration of this conversion');
  16345. log_message ('');
  16346. log_message (' Since the update can take a considerable amount of time on large databases');
  16347. log_message (' it is advisable to schedule this at an appropriate time.');
  16348. log_message ('');
  16349. log_message ('To continue the DBA must change the virtuoso.ini file and add the following flag:');
  16350. log_message ('');
  16351. log_message (' [Parameters]');
  16352. log_message (' AnalyzeFixQuadStore = 1');
  16353. log_message ('');
  16354. log_message ('For additional information please contact OpenLink Support <support@openlinksw.com>');
  16355. log_message ('This process will now exit.');
  16356. raw_exit();
  16357. }
  16358. log_message ('Please be patient.');
  16359. log_message ('The table DB.DBA.RDF_QUAD and two of its additional indexes will be patched now.');
  16360. log_message ('In case of error during the operation, delete the transaction log before restarting the server.');
  16361. exec ('checkpoint');
  16362. declare exit handler for sqlstate '*'
  16363. {
  16364. log_message (sprintf ('Error %s: %s', __SQL_STATE, __SQL_MESSAGE));
  16365. log_message ('Do not forget to delete the transaction log before restarting the server.');
  16366. raw_exit ();
  16367. };
  16368. log_enable (2);
  16369. log_message ('Phase 1 of 9: Gathering statistics ...');
  16370. c_main := (select count (1) from DB.DBA.RDF_QUAD table option (index RDF_QUAD) option (no cluster));
  16371. c_pogs := (select count (1) from DB.DBA.RDF_QUAD table option (index RDF_QUAD_POGS) option (no cluster));
  16372. if (c_main <> c_pogs)
  16373. log_message ('* Existing indexes are damaged, will try to recover...');
  16374. c_op := (select count (1) from DB.DBA.RDF_QUAD table option (index RDF_QUAD_OP, index_only) option (no cluster));
  16375. log_message (sprintf (' * Index sizes before the processing: %09d RDF_QUAD, %09d POGS, %09d OP', c_main, c_pogs, c_op));
  16376. delete from DB.DBA.RDF_QUAD_RECOV_TMP table option (index RDF_QUAD_RECOV_TMP, no cluster) option (index RDF_QUAD_RECOV_TMP, no cluster);
  16377. delete from DB.DBA.RDF_QUAD_RECOV_TMP table option (index RDF_QUAD_RECOV_TMP_POGS, no cluster) option (index RDF_QUAD_RECOV_TMP_POGS, no cluster);
  16378. delete from DB.DBA.RDF_QUAD_RECOV_TMP table option (index RDF_QUAD_RECOV_TMP_OP, index_only, no cluster) option (index RDF_QUAD_RECOV_TMP_OP, no cluster);
  16379. log_message ('Phase 2 of 9: Copying all quads to a temporary table ...');
  16380. insert soft DB.DBA.RDF_QUAD_RECOV_TMP index RDF_QUAD_RECOV_TMP option (no cluster) (G1,S1,P1,O1) select G,S,P,O from DB.DBA.RDF_QUAD table option (index RDF_QUAD) option (no cluster);
  16381. insert soft DB.DBA.RDF_QUAD_RECOV_TMP index RDF_QUAD_RECOV_TMP_POGS option (no cluster) (G1,S1,P1,O1) select G,S,P,O from DB.DBA.RDF_QUAD table option (index RDF_QUAD_POGS) option (no cluster);
  16382. insert soft DB.DBA.RDF_QUAD_RECOV_TMP index RDF_QUAD_RECOV_TMP_OP option (index_only, no cluster) (P1,O1) select P,O from DB.DBA.RDF_QUAD table option (index RDF_QUAD_OP, index_only) option (no cluster);
  16383. if (c_main <> c_pogs) -- cluster should not do that
  16384. {
  16385. log_message ('* Recovering additional data from existing indexes');
  16386. if (c_main < c_pogs)
  16387. insert soft DB.DBA.RDF_QUAD_RECOV_TMP option (no cluster) (G1,S1,P1,O1) select G,S,P,O from DB.DBA.RDF_QUAD table option (index RDF_QUAD_POGS) option (no cluster);
  16388. if (c_pogs < c_main)
  16389. insert soft DB.DBA.RDF_QUAD_RECOV_TMP option (no cluster) (G1,S1,P1,O1) select G,S,P,O from DB.DBA.RDF_QUAD table option (index RDF_QUAD) option (no cluster);
  16390. }
  16391. c_op_tmp := (select count (1) from DB.DBA.RDF_QUAD_RECOV_TMP table option (index RDF_QUAD_RECOV_TMP_OP, index_only) option (no cluster));
  16392. log_message (sprintf ('* Index sizes of temporary table: %09d OP', c_op_tmp));
  16393. if (c_op_tmp < c_op)
  16394. log_message ('** Some data are lost or the corruption was strong before the processing.');
  16395. log_message ('Phase 3 of 9: Cleaning the quad storage ...');
  16396. delete from DB.DBA.RDF_QUAD table option (index RDF_QUAD, no cluster) option (index RDF_QUAD, no cluster);
  16397. delete from DB.DBA.RDF_QUAD table option (index RDF_QUAD_POGS, no cluster) option (index RDF_QUAD_POGS, no cluster);
  16398. delete from DB.DBA.RDF_QUAD table option (index RDF_QUAD_OP, index_only, no cluster) option (index RDF_QUAD_OP, no cluster);
  16399. log_message ('Phase 4 of 9: Refilling the quad storage from the temporary table...');
  16400. insert soft DB.DBA.RDF_QUAD index RDF_QUAD option (no cluster) (G,S,P,O) select G1,S1,P1,O1 from DB.DBA.RDF_QUAD_RECOV_TMP table option (index RDF_QUAD_RECOV_TMP) option (no cluster);
  16401. insert soft DB.DBA.RDF_QUAD index RDF_QUAD_POGS option (no cluster) (G,S,P,O) select G1,S1,P1,O1 from DB.DBA.RDF_QUAD_RECOV_TMP table option (index RDF_QUAD_RECOV_TMP_POGS) option (no cluster);
  16402. insert soft DB.DBA.RDF_QUAD index RDF_QUAD_OP option (index_only, no cluster) (P,O) select P1,O1 from DB.DBA.RDF_QUAD_RECOV_TMP table option (index RDF_QUAD_RECOV_TMP_OP, index_only) option (no cluster);
  16403. log_message ('Phase 5 of 9: Cleaning the temporary table ...');
  16404. delete from DB.DBA.RDF_QUAD_RECOV_TMP table option (index RDF_QUAD_RECOV_TMP, no cluster) option (index RDF_QUAD_RECOV_TMP, no cluster);
  16405. delete from DB.DBA.RDF_QUAD_RECOV_TMP table option (index RDF_QUAD_RECOV_TMP_POGS, no cluster) option (index RDF_QUAD_RECOV_TMP_POGS, no cluster);
  16406. delete from DB.DBA.RDF_QUAD_RECOV_TMP table option (index RDF_QUAD_RECOV_TMP_OP, index_only, no cluster) option (index RDF_QUAD_RECOV_TMP_OP, no cluster);
  16407. log_message ('Phase 6 of 9: Gathering statistics again ...');
  16408. c_main_fixed := (select count (1) from DB.DBA.RDF_QUAD table option (index RDF_QUAD) option (no cluster));
  16409. c_pogs_fixed := (select count (1) from DB.DBA.RDF_QUAD table option (index RDF_QUAD_POGS) option (no cluster));
  16410. c_op_fixed := (select count (1) from DB.DBA.RDF_QUAD table option (index RDF_QUAD_OP, index_only) option (no cluster));
  16411. log_message (sprintf ('* Index sizes after the processing: %09d RDF_QUAD, %09d POGS, %09d OP', c_main_fixed, c_pogs_fixed, c_op_fixed));
  16412. if ((__min (c_main_fixed, c_pogs_fixed) < __max (c_main, c_pogs)) or (c_op_fixed < c_op))
  16413. log_message ('** Some data are lost or the corruption was strong before the processing.');
  16414. --select * from DB.DBA.RDF_QUAD a table option (index RDF_QUAD) where not exists (select top 1 1 from DB.DBA.RDF_QUAD b table option (index RDF_QUAD) where a.G=b.G and a.S=b.S and a.P=b.P and a.O=b.O);
  16415. --select * from DB.DBA.RDF_QUAD a table option (index RDF_QUAD_POGS) where not exists (select top 1 1 from DB.DBA.RDF_QUAD b table option (index RDF_QUAD_POGS) where a.G=b.G and a.S=b.S and a.P=b.P and a.O=b.O);
  16416. --select * from DB.DBA.RDF_QUAD a table option (index RDF_QUAD_POGS) where not exists (select top 1 1 from DB.DBA.RDF_QUAD b table option (index RDF_QUAD) where a.G=b.G and a.S=b.S and a.P=b.P and a.O=b.O);
  16417. --select * from DB.DBA.RDF_QUAD a table option (index RDF_QUAD) where not exists (select top 1 1 from DB.DBA.RDF_QUAD b table option (index RDF_QUAD_POGS) where a.G=b.G and a.S=b.S and a.P=b.P and a.O=b.O);
  16418. --select * from DB.DBA.RDF_QUAD a table option (index RDF_QUAD_OP, index_only) where not exists (select top 1 1 from DB.DBA.RDF_QUAD b table option (index RDF_QUAD_OP, index_only) where a.P=b.P and a.O=b.O);
  16419. --select * from DB.DBA.RDF_QUAD a table option (index RDF_QUAD_OP, index_only) where not exists (select top 1 1 from DB.DBA.RDF_QUAD b table option (index RDF_QUAD) where a.P=b.P and a.O=b.O);
  16420. --select * from DB.DBA.RDF_QUAD a table option (index RDF_QUAD) where not exists (select top 1 1 from DB.DBA.RDF_QUAD b table option (index RDF_QUAD_OP, index_only) where a.P=b.P and a.O=b.O);
  16421. log_message ('Phase 7 of 9: integrity check (completeness of index RDF_QUAD_POGS of DB.DBA.RDF_QUAD) ...');
  16422. if (exists (select top 1 1 from DB.DBA.RDF_QUAD a table option (index RDF_QUAD) where not exists (select 1 from DB.DBA.RDF_QUAD b table option (loop, index RDF_QUAD_POGS) where a.g = b.g and a.p = b.p and a.o = b.o and a.s = b.s)))
  16423. log_message ('** IMPORTANT WARNING: not all rows of DB.DBA.RDF_QUAD are found in RDF_QUAD_POGS, data reloading is strictly recommended.');
  16424. log_message ('Phase 8 of 9: integrity check (completeness of primary key of DB.DBA.RDF_QUAD) ...');
  16425. if (exists (select top 1 1 from DB.DBA.RDF_QUAD a table option (index RDF_QUAD_POGS) where not exists (select 1 from DB.DBA.RDF_QUAD b table option (loop, index primary key) where a.g = b.g and a.p = b.p and a.o = b.o and a.s = b.s)))
  16426. log_message ('** IMPORTANT WARNING: not all rows of DB.DBA.RDF_QUAD are found in RDF_QUAD_POGS, data reloading is strictly recommended.');
  16427. log_message ('Phase 9 of 9: final checkpoint...');
  16428. registry_set ('__rb_id_only_for_plain_ro_obj', '1');
  16429. exec ('checkpoint');
  16430. log_enable (old_mode, 1);
  16431. log_message ('Update complete.');
  16432. }
  16433. ;
  16434. --!AFTER
  16435. DB.DBA.RDF_QUAD_OUTLINE_ALL ()
  16436. ;
  16437. create procedure DB.DBA.RDF_QUAD_LOAD_CACHE ()
  16438. {
  16439. declare fake integer;
  16440. fake := (select count (rdf_cache_id ('t', RDT_QNAME, RDT_TWOBYTE)) from DB.DBA.RDF_DATATYPE);
  16441. fake := (select count (rdf_cache_id ('l', RL_ID, RL_TWOBYTE)) from DB.DBA.RDF_LANGUAGE);
  16442. fake := (select
  16443. count (dict_put (__rdf_graph_iri2id_dict(), __uname (id_to_iri (RGG_IID)), RGG_IID)) +
  16444. count (dict_put (__rdf_graph_id2iri_dict(), RGG_IID, __uname (id_to_iri (RGG_IID))))
  16445. from DB.DBA.RDF_GRAPH_GROUP );
  16446. fake := (select
  16447. count (dict_put (__rdf_graph_iri2id_dict(), __uname (id_to_iri (RGGM_GROUP_IID)), RGGM_GROUP_IID)) +
  16448. count (dict_put (__rdf_graph_id2iri_dict(), RGGM_GROUP_IID, __uname (id_to_iri (RGGM_GROUP_IID))))
  16449. from DB.DBA.RDF_GRAPH_GROUP_MEMBER );
  16450. fake := (select
  16451. count (dict_put (__rdf_graph_iri2id_dict(), __uname (id_to_iri (RGGM_MEMBER_IID)), RGGM_MEMBER_IID)) +
  16452. count (dict_put (__rdf_graph_id2iri_dict(), RGGM_MEMBER_IID, __uname (id_to_iri (RGGM_MEMBER_IID))))
  16453. from DB.DBA.RDF_GRAPH_GROUP_MEMBER );
  16454. fake := (select
  16455. count (dict_put (__rdf_graph_iri2id_dict(), __uname (id_to_iri (RGU_GRAPH_IID)), RGU_GRAPH_IID)) +
  16456. count (dict_put (__rdf_graph_id2iri_dict(), RGU_GRAPH_IID, __uname (id_to_iri (RGU_GRAPH_IID))))
  16457. from DB.DBA.RDF_GRAPH_USER where RGU_GRAPH_IID <> #i8192 and RGU_GRAPH_IID <> #i0 );
  16458. for (select RGGM_GROUP_IID as group_iid, DB.DBA.VECTOR_AGG (RGGM_MEMBER_IID) as membs
  16459. from DB.DBA.RDF_GRAPH_GROUP_MEMBER join DB.DBA.RDF_GRAPH_GROUP on (RGGM_GROUP_IID = RGG_IID) ) do
  16460. {
  16461. if (length (membs) < 1000)
  16462. {
  16463. gvector_digit_sort (membs, 1, 0, 1);
  16464. dict_put (__rdf_graph_group_dict(), group_iid, membs);
  16465. }
  16466. else
  16467. {
  16468. declare new_membs any;
  16469. new_membs := dict_new (length (membs));
  16470. foreach (IRI_ID m in membs) do dict_put (new_membs, m, 1);
  16471. dict_put (__rdf_graph_group_dict(), group_iid, new_membs);
  16472. }
  16473. }
  16474. fake := (select count (dict_put (__rdf_graph_group_of_privates_dict(), RGGM_MEMBER_IID, 1))
  16475. from DB.DBA.RDF_GRAPH_GROUP_MEMBER where RGGM_GROUP_IID = iri_to_id('http://www.openlinksw.com/schemas/virtrdf#PrivateGraphs'));
  16476. fake := (select count (dict_put (__rdf_graph_default_perms_of_user_dict(0), RGU_USER_ID, RGU_PERMISSIONS))
  16477. from DB.DBA.RDF_GRAPH_USER where RGU_GRAPH_IID = #i0 );
  16478. fake := (select count (dict_put (__rdf_graph_default_perms_of_user_dict(1), RGU_USER_ID, RGU_PERMISSIONS))
  16479. from DB.DBA.RDF_GRAPH_USER where RGU_GRAPH_IID = #i8192 );
  16480. fake := (select count (dict_put (__rdf_graph_public_perms_dict(), RGU_GRAPH_IID, RGU_PERMISSIONS))
  16481. from DB.DBA.RDF_GRAPH_USER where RGU_USER_ID = http_nobody_uid () );
  16482. }
  16483. ;
  16484. create procedure DB.DBA.RDF_QUAD_FT_UPGRADE ()
  16485. {
  16486. declare stat, msg varchar;
  16487. declare fake integer;
  16488. if (USER <> 'dba')
  16489. signal ('RDFXX', 'Only DBA can alter DB.DBA.RDF_QUAD schema or initialize RDF storage');
  16490. if (sys_stat ('disable_rdf_init') = 1)
  16491. return;
  16492. if (0 = sys_stat ('db_exists') and 1 = sys_stat ('cl_run_local_only'))
  16493. {
  16494. -- v7 index is on by default
  16495. DB.DBA.RDF_OBJ_FT_RULE_ADD ('', '', 'ALL');
  16496. }
  16497. RDF_QUAD_FT_INIT ();
  16498. DB.DBA.RDF_QUAD_LOAD_CACHE ();
  16499. delete from DB.DBA.RDF_GRAPH_USER where not exists (select 1 from DB.DBA.SYS_USERS where RGU_USER_ID = U_ID);
  16500. if (row_count ())
  16501. log_message ('Non-existing users are removed from graph security list');
  16502. fake := (select count (__rdf_graph_specific_perms_of_user (RGU_GRAPH_IID, RGU_USER_ID, RGU_PERMISSIONS))
  16503. from DB.DBA.RDF_GRAPH_USER where RGU_USER_ID <> http_nobody_uid () and not (RGU_GRAPH_IID in (#i0, #i8192)) );
  16504. if (coalesce (virtuoso_ini_item_value ('SPARQL', 'RecoveryMode'), '0') > '0')
  16505. {
  16506. log_message ('Switching to RecoveryMode as set in [SPARQL] section of the configuration.');
  16507. log_message ('For safety, the use of SPARQL_UPDATE role is restricted.');
  16508. exec ('revoke "SPARQL_UPDATE" from "SPARQL"', stat, msg);
  16509. return;
  16510. }
  16511. if (1 <> sys_stat ('cl_run_local_only'))
  16512. goto final_qm_reload;
  16513. if (244 = coalesce ((select COL_DTP from SYS_COLS where "TABLE" = 'DB.DBA.RDF_QUAD' and "COLUMN"='G'), 0))
  16514. {
  16515. __set_64bit_min_bnode_iri_id();
  16516. sequence_set ('RDF_URL_IID_BLANK', iri_id_num (min_bnode_iri_id ()), 1);
  16517. }
  16518. --exec ('create index RO_DIGEST on DB.DBA.RDF_OBJ (RO_DIGEST)', stat, msg);
  16519. if (exists (select top 1 1 from DB.DBA.SYS_COLS
  16520. where "TABLE" = fix_identifier_case ('DB.DBA.RDF_OBJ_RO_FLAGS_WORDS')
  16521. and "COLUMN" = fix_identifier_case ('VT_WORD') )
  16522. and exists (select top 1 1 from DB.DBA.SYS_COLS
  16523. where "TABLE" = fix_identifier_case ('DB.DBA.RDF_OBJ')
  16524. and "COLUMN" = fix_identifier_case ('RO_FLAGS')
  16525. and COL_DTP = 188 ) )
  16526. goto final_qm_reload;
  16527. exec ('DB.DBA.vt_create_text_index (
  16528. fix_identifier_case (''DB.DBA.RDF_OBJ''),
  16529. fix_identifier_case (''RO_FLAGS''),
  16530. fix_identifier_case (''RO_ID''),
  16531. 0, 0, vector (), 1, ''*ini*'', ''UTF-8-QR'')', stat, msg);
  16532. __vt_index ('DB.DBA.RDF_QUAD', 'RDF_QUAD_OP', 'O', 'O', 'DB.DBA.RDF_OBJ_RO_FLAGS_WORDS');
  16533. exec ('DB.DBA.vt_batch_update (fix_identifier_case (''DB.DBA.RDF_OBJ''), ''ON'', 1)', stat, msg);
  16534. final_qm_reload:
  16535. DB.DBA.SPARQL_RELOAD_QM_GRAPH ();
  16536. insert soft rdf_datatype (rdt_iid, rdt_twobyte, rdt_qname) values
  16537. (iri_to_id ('http://www.openlinksw.com/schemas/virtrdf#Geometry'), 256, 'http://www.openlinksw.com/schemas/virtrdf#Geometry');
  16538. return;
  16539. }
  16540. ;
  16541. --!AFTER
  16542. DB.DBA.RDF_QUAD_FT_UPGRADE ()
  16543. ;
  16544. --#IF VER=5
  16545. --!AFTER __PROCEDURE__ DB.DBA.USER_CREATE !
  16546. --#ENDIF
  16547. DB.DBA.RDF_CREATE_SPARQL_ROLES ()
  16548. ;
  16549. -- loading subclass inference ctxs
  16550. create procedure rdfs_pn (in is_class int)
  16551. {
  16552. return case when is_class = 1 then iri_to_id ('http://www.w3.org/2000/01/rdf-schema#subClassOf')
  16553. else iri_to_id ('http://www.w3.org/2000/01/rdf-schema#subPropertyOf') end;
  16554. }
  16555. ;
  16556. create procedure rdf_owl_sas_p (in gr iri_id, in name varchar, in super_c iri_id, in c iri_id, in visited any, inout supers any, in pos int)
  16557. {
  16558. declare txt varchar;
  16559. declare meta, cc, res any;
  16560. txt := sprintf ('sparql define output:valmode "LONG" define input:storage ""select ?o from <%s> where { <%s> <http://www.w3.org/2002/07/owl#sameAs> ?o }',
  16561. id_to_iri(gr), id_to_iri(c) );
  16562. exec (txt, null, null, vector (), 0, meta, null, cc);
  16563. while (0 = exec_next (cc, null, null, res))
  16564. {
  16565. rdfs_closure_1 (gr, name, super_c, res[0], 0, visited, supers, pos);
  16566. }
  16567. exec_close (cc);
  16568. txt := sprintf ('sparql define output:valmode "LONG" define input:storage "" select ?s from <%s> where { ?s <http://www.w3.org/2002/07/owl#sameAs> <%s> }',
  16569. id_to_iri(gr), id_to_iri(c) );
  16570. exec (txt, null, null, vector (), 0, meta, null, cc);
  16571. while (0 = exec_next (cc, null, null, res))
  16572. {
  16573. rdfs_closure_1 (gr, name, super_c, res[0], 0, visited, supers, pos);
  16574. }
  16575. exec_close (cc);
  16576. }
  16577. ;
  16578. create table DB.DBA.SYS_RDF_SCHEMA (RS_NAME VARCHAR , RS_URI VARCHAR, RS_G IRI_ID,
  16579. PRIMARY KEY (RS_NAME, RS_URI))
  16580. alter index SYS_RDF_SCHEMA on DB.DBA.SYS_RDF_SCHEMA partition cluster replicated
  16581. ;
  16582. create function rdfs_load_schema (in ri_name varchar, in gn varchar := null) returns integer
  16583. {
  16584. declare gr iri_id;
  16585. declare visited any;
  16586. declare supers any;
  16587. declare eq_c, eq_p iri_id;
  16588. declare txt varchar;
  16589. declare idx integer;
  16590. declare cc, res, st, msg, meta any;
  16591. declare v any;
  16592. declare inx int;
  16593. declare from_text varchar;
  16594. declare rules_count integer;
  16595. from_text := '';
  16596. res := 0;
  16597. if (gn is null)
  16598. {
  16599. for (select RS_URI from DB.DBA.SYS_RDF_SCHEMA where RS_NAME=ri_name) do
  16600. {
  16601. from_text := from_text || sprintf (' from <%s>', RS_URI);
  16602. }
  16603. }
  16604. else
  16605. {
  16606. if (isiri_id (gn))
  16607. from_text := from_text || sprintf (' from <%s>', id_to_iri (gn));
  16608. else
  16609. from_text := from_text || sprintf (' from <%s>', gn);
  16610. }
  16611. if ('' = from_text)
  16612. return 0;
  16613. for (idx := 0; idx <= 4; idx := idx + 1)
  16614. {
  16615. txt := sprintf ('sparql define output:valmode "LONG" define input:storage "" select ?s ?o %s where { ?s <%s> ?o . filter (!isLITERAL (?o)) }',
  16616. from_text, id_to_iri (case (idx) when 4 then rdf_sas_iri () else rdf_owl_iri (idx) end) );
  16617. exec (txt, null, null, vector (), 0, meta, null, cc);
  16618. while (0 = exec_next (cc, null, null, res))
  16619. {
  16620. declare s, o any;
  16621. s := res[0]; o := res[1];
  16622. if (idx = 4)
  16623. {
  16624. rdf_inf_dir (ri_name, s, o, 2);
  16625. rdf_inf_dir (ri_name, s, o, 3);
  16626. rules_count := rules_count + 2;
  16627. }
  16628. else
  16629. {
  16630. rdf_inf_dir (ri_name, o, s, idx);
  16631. rules_count := rules_count + 1;
  16632. }
  16633. }
  16634. }
  16635. exec_close (cc);
  16636. -- Loading inverse functional properties
  16637. txt := sprintf ('select DB.DBA.VECTOR_AGG (sub."s") from
  16638. (sparql define output:valmode "LONG" define input:storage ""
  16639. select distinct ?s %s
  16640. where {
  16641. { ?s a <http://www.w3.org/2002/07/owl#InverseFunctionalProperty> }
  16642. union
  16643. { ?s a <http://www.w3.org/2002/07/owl#FunctionalProperty> , <http://www.w3.org/2002/07/owl#SymmetricProperty> }
  16644. union
  16645. { ?s1 a <http://www.w3.org/2002/07/owl#FunctionalProperty> .
  16646. ?s <http://www.w3.org/2002/07/owl#inverseOf> ?s1 }
  16647. union
  16648. { ?s1 a <http://www.w3.org/2002/07/owl#FunctionalProperty> .
  16649. ?s1 <http://www.w3.org/2002/07/owl#inverseOf> ?s }
  16650. }
  16651. ) sub option (QUIETCAST)',
  16652. from_text );
  16653. exec (txt, null, null, vector (), 0, meta, res);
  16654. v := res[0][0];
  16655. if (0 < length (v))
  16656. {
  16657. txt := sprintf ('select DB.DBA.VECTOR_AGG (sub."s") from
  16658. (sparql define output:valmode "LONG" define input:storage ""
  16659. select ?s %s
  16660. where {
  16661. ?s <http://www.w3.org/2000/01/rdf-schema#subPropertyOf> ?sp option (TRANSITIVE, T_MIN 1) .
  16662. filter (?sp = iri (?::0)) } ) sub option (QUIETCAST)',
  16663. from_text );
  16664. for (inx := length (v) - 1; 0 <= inx; inx := inx - 1)
  16665. {
  16666. declare meta1, res1 any;
  16667. declare subprops any;
  16668. exec (txt, null, null, vector (v[inx]), 0, meta1, res1);
  16669. subprops := res1[0][0];
  16670. foreach (IRI_ID subp in subprops) do
  16671. {
  16672. -- dbg_obj_princ ('Handled subproperty ', id_to_iri (subp), ' of ifp ', id_to_iri (v[inx]));
  16673. if (0 >= position (subp, v))
  16674. v := vector_concat (v, vector (subp));
  16675. }
  16676. }
  16677. -- dbg_obj_princ ('known ifps are: '); foreach (IRI_ID i in v) do -- dbg_obj_princ (id_to_iri(i));
  16678. gvector_digit_sort (v, 1, 0, 1);
  16679. rdf_inf_set_ifp_list (ri_name, v); --- Note that this should be after all super/sub relations in order to fill ric_iid_to_rel_ifp
  16680. rules_count := rules_count + length (v);
  16681. txt := sprintf ('
  16682. select vector_agg (sub."o") from
  16683. (sparql define output:valmode "LONG" define input:storage ""
  16684. select distinct ?o %s where {
  16685. { ?::0 <http://www.openlinksw.com/schemas/virtrdf#nullIFPValue> ?o .
  16686. filter (isREF (?o)) }
  16687. union
  16688. {
  16689. ?subp <http://www.w3.org/2000/01/rdf-schema#subPropertyOf> ?superp option (TRANSITIVE, T_MIN 1) .
  16690. ?subp <http://www.openlinksw.com/schemas/virtrdf#nullIFPValue> ?o .
  16691. filter (?superp = ?::0)
  16692. filter (isREF (?o)) } } ) sub option (QUIETCAST)',
  16693. from_text );
  16694. for (inx := 0; inx < length (v); inx := inx + 1)
  16695. {
  16696. declare meta1, res1 any;
  16697. declare excl any;
  16698. exec (txt, null, null, vector (v[inx]), 0, meta1, res1);
  16699. excl := meta1[0][0];
  16700. if (length (excl) > 0)
  16701. rdf_inf_set_ifp_exclude_list (ri_name, v[inx], excl);
  16702. }
  16703. }
  16704. -- Loading inverse functions
  16705. txt := sprintf ('select DB.DBA.VECTOR_CONCAT_AGG (vector (sub."s", sub."o", sub."o", sub."s")) from
  16706. (sparql define input:storage "" select ?s ?o %s where {
  16707. ?s <http://www.w3.org/2002/07/owl#inverseOf> ?o .
  16708. optional { ?o <http://www.w3.org/2002/07/owl#inverseOf> ?s2 . filter (?s2 = ?s ) }
  16709. filter ((str (?s) <= str (?o)) || !BOUND(?s2)) }) sub option (QUIETCAST)',
  16710. from_text );
  16711. exec (txt, null, null, vector (), 0, meta, res);
  16712. v := res[0][0];
  16713. txt := sprintf ('select DB.DBA.VECTOR_CONCAT_AGG (vector (sub."s", sub."s")) from
  16714. (sparql define input:storage "" select ?s %s where {
  16715. ?s a <http://www.w3.org/2002/07/owl#SymmetricProperty> }) sub option (QUIETCAST)',
  16716. from_text );
  16717. exec (txt, null, null, vector (), 0, meta, res);
  16718. v := vector_concat (v, res[0][0]);
  16719. if (0 < length (v))
  16720. {
  16721. gvector_sort (v, 2, 0, 1);
  16722. rdf_inf_set_inverses (ri_name, v);
  16723. rules_count := rules_count + length (v);
  16724. }
  16725. -- Loading bitmask properties of functions
  16726. txt := sprintf ('select DB.DBA.VECTOR_CONCAT_AGG (vector (sub."s", 1)) from
  16727. (sparql define input:storage "" select ?s %s where {
  16728. { ?s a <http://www.w3.org/2002/07/owl#TransitiveProperty> }
  16729. union
  16730. { ?s <http://www.w3.org/2002/07/owl#inverseOf> [ a <http://www.w3.org/2002/07/owl#TransitiveProperty> ] }
  16731. union
  16732. { [ a <http://www.w3.org/2002/07/owl#TransitiveProperty> ] <http://www.w3.org/2002/07/owl#inverseOf> ?s }
  16733. } ) sub option (QUIETCAST)',
  16734. from_text );
  16735. exec (txt, null, null, vector (), 0, meta, res);
  16736. v := res[0][0];
  16737. if (0 < length (v))
  16738. {
  16739. gvector_sort (v, 2, 0, 1);
  16740. rdf_inf_set_prop_props (ri_name, v);
  16741. rules_count := rules_count + length (v);
  16742. }
  16743. jso_mark_affected (ri_name);
  16744. log_text ('jso_mark_affected (?)', ri_name);
  16745. -- if (not rules_count)
  16746. rdf_inf_dir (ri_name, null, null, 0);
  16747. return rules_count + 1;
  16748. }
  16749. ;
  16750. create procedure rdf_schema_ld ()
  16751. {
  16752. if (1 <> sys_stat ('cl_run_local_only'))
  16753. return 0;
  16754. return (select count (*) from (select distinct s.RS_NAME from DB.DBA.SYS_RDF_SCHEMA s) sub where 0 = rdfs_load_schema (sub.RS_NAME));
  16755. }
  16756. ;
  16757. rdf_schema_ld ()
  16758. ;
  16759. create function CL_RDF_INF_CHANGED_SRV (in name varchar) returns integer
  16760. {
  16761. declare res integer;
  16762. set isolation = 'committed';
  16763. rdf_inf_clear (name);
  16764. return case (rdfs_load_schema (name)) when 0 then 1 else 0 end;
  16765. return res;
  16766. }
  16767. ;
  16768. create procedure CL_RDF_INF_CHANGED (in name varchar)
  16769. {
  16770. declare aq any;
  16771. if (2 = sys_stat ('cl_run_local_only'))
  16772. return;
  16773. aq := async_queue (1, 4);
  16774. aq_request (aq, 'DB.DBA.CL_RDF_INF_CHANGED_SRV', vector (name));
  16775. aq_wait_all (aq);
  16776. }
  16777. ;
  16778. create function rdfs_rule_set (in name varchar, in gn varchar, in remove int := 0) returns integer
  16779. {
  16780. delete from DB.DBA.SYS_RDF_SCHEMA where RS_NAME = name and RS_URI = gn;
  16781. if (not remove)
  16782. {
  16783. insert into DB.DBA.SYS_RDF_SCHEMA (RS_NAME, RS_URI) values (name, gn);
  16784. }
  16785. commit work;
  16786. if (0 = sys_stat ('cl_run_local_only'))
  16787. {
  16788. DB.DBA.SECURITY_CL_EXEC_AND_LOG ('DB.DBA.CL_RDF_INF_CHANGED (?)', vector (name));
  16789. return 1;
  16790. }
  16791. else
  16792. {
  16793. declare res integer;
  16794. rdf_inf_clear (name);
  16795. res := rdfs_load_schema (name);
  16796. log_text ('db.dba.rdfs_load_schema (?)', name);
  16797. return res;
  16798. }
  16799. }
  16800. ;
  16801. create function DB.DBA.RDF_IID_OF_QNAME (in qname varchar) returns IRI_ID
  16802. {
  16803. whenever sqlstate '*' goto retnull;
  16804. return iri_to_id (qname, 0, null);
  16805. retnull:
  16806. return null;
  16807. }
  16808. ;
  16809. create procedure SPARQL_INI_PARAMS (inout metas any, inout dta any)
  16810. {
  16811. declare item_cnt int;
  16812. declare items any;
  16813. declare item_name, item_value varchar;
  16814. declare res_dict any;
  16815. declare tmp any;
  16816. item_cnt := cfg_item_count (virtuoso_ini_path (), 'SPARQL');
  16817. tmp := string_output ();
  16818. for (declare i int, i := 0; i < item_cnt; i := i + 1)
  16819. {
  16820. item_name := cfg_item_name (virtuoso_ini_path (), 'SPARQL', i);
  16821. item_value := virtuoso_ini_item_value ('SPARQL', item_name);
  16822. http (sprintf ('<http://www.openlinksw.com/schemas/virtini#SPARQL> <http://www.openlinksw.com/schemas/virtini#%U> "%s" .\r\n',
  16823. item_name, item_value), tmp);
  16824. }
  16825. tmp := string_output_string (tmp);
  16826. res_dict := DB.DBA.RDF_TTL2HASH (tmp, '');
  16827. metas := vector (vector (vector ('res_dict', 242, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0)), 1);
  16828. dta := vector (vector (res_dict));
  16829. }
  16830. ;
  16831. --
  16832. -- Make geometries for geo:long, geo:lat pairs
  16833. --
  16834. create procedure num_or_null (in n any)
  16835. {
  16836. declare exit handler for sqlstate '*'{ return null; };
  16837. return cast (cast (n as decimal) as real);
  16838. }
  16839. ;
  16840. create procedure GEO_FILL_SRV (in arr any, in fill int)
  16841. {
  16842. declare lat, lng, s, g, l any;
  16843. declare inx int;
  16844. log_enable (2, 1);
  16845. declare geop iri_id_8;
  16846. declare gs, ss, os any array;
  16847. gs := make_array (fill, 'any');
  16848. ss := make_array (fill, 'any');
  16849. os := make_array (fill, 'any');
  16850. geop := iri_to_id ('http://www.w3.org/2003/01/geo/wgs84_pos#geometry');
  16851. for (inx := 0; inx < fill; inx := inx + 1)
  16852. {
  16853. l := aref_set_0 (arr, inx);
  16854. gs[inx] := aref_set_0 (l, 0);
  16855. ss[inx] := aref_set_0 (l, 1);
  16856. os[inx] := st_point (aref_set_0 (l, 2), aref_set_0 (l, 3));
  16857. }
  16858. for vectored (in g1 iri_id_8 := gs, in s1 iri_id_8 := ss, in o1 any array := os)
  16859. {
  16860. insert soft rdf_quad (g, s, p, o) values ("g1", "s1", geop, rdf_geo_add (rdf_box (o1, 256, 257, 0, 1)));
  16861. }
  16862. }
  16863. ;
  16864. create procedure rdf_geo_fill (in threads int := null, in batch int := 100000)
  16865. {
  16866. declare arr, fill, aq, ctr any;
  16867. if (threads is null) threads := sys_stat ('enable_qp');
  16868. aq := async_queue (threads);
  16869. arr := make_array (batch, 'any');
  16870. fill := 0;
  16871. ctr := 0;
  16872. log_enable (2, 1);
  16873. for select "s", "long", "lat", "g" from (sparql define output:valmode "LONG" select ?g ?s ?long ?lat where {
  16874. graph ?g { ?s geo:long ?long . ?s geo:lat ?lat}}) f do
  16875. {
  16876. declare lat2, long2 any;
  16877. long2 := num_or_null (rdf_box_data ("long"));
  16878. lat2 := num_or_null (rdf_box_data ("lat"));
  16879. if (isnumeric (long2) and isnumeric (lat2))
  16880. {
  16881. arr[fill] := vector ("g", "s", long2, lat2);
  16882. fill := fill + 1;
  16883. if (batch = fill)
  16884. {
  16885. aq_request (aq, 'DB.DBA.GEO_FILL_SRV', vector (arr, fill));
  16886. ctr := ctr + 1;
  16887. if (ctr > 100)
  16888. {
  16889. commit work;
  16890. aq_wait_all (aq);
  16891. ctr := 0;
  16892. }
  16893. arr := make_array (batch, 'any');
  16894. fill := 0;
  16895. }
  16896. }
  16897. }
  16898. geo_fill_srv (arr, fill);
  16899. commit work;
  16900. aq_wait_all (aq);
  16901. }
  16902. ;