diff --git a/ChangeLog b/ChangeLog index 65a9e7c052..9e069497ab 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,701 @@ +2023-09-26 Patrick van Kleef + + Updated version to 7.2.11 engine 3238 + +2023-09-26 Mitko Iliev + + Fixed issue with leading space before split + +2023-09-26 Patrick van Kleef + + Fixed parameter name to XAnyNormalization in documentation + + Reported-by: Arnoud Engelen + +2023-09-26 Ted Thibodeau Jr + + Fixed wrong column name in debian/README.Debian + + Fixed RDF to RDF/XML in human-facing serialization lists + + Fixed human-facing typos in cetop.c + + Fixed typos in viconfig.c + + Fixed human-facing typos in configure.ac + +2023-09-26 Patrick van Kleef + + Fixed startup time building VAD packages on linux/macos/unix + +2023-09-25 Mitko Iliev + + Fixed issues mixing valid and invalid MIME types in Accept header (fixes #786) + + Fixed href is needed in PROPPATCH response + + Fixed show failed argument value to convert + +2023-09-22 Patrick van Kleef + + Fixed missing export symbol for graphql plugin on musl c library + +2023-09-22 Mitko Iliev + + Fixed missing entry for JSON-LD in RDF DET + +2023-09-22 Patrick van Kleef + + Updated NEWS.md and Changelog + + Updated version to 7.2.11-rc1 + +2023-09-22 Mitko Iliev + + Fixed import of .pem certificate bundle should load all keys + + Fixed issue with DROP TABLE/VIEW not checking target + +2023-09-21 Mitko Iliev + + Fixed issue when copying constants in union + +2023-09-21 Patrick van Kleef + + Fixed small issue with lang matches + +2023-09-19 Mitko Iliev + + Fixed RDF quad sanity check for 'O' column + + Fixed issue if no hooks are specified + + Added new BIF jsonld_ctx_to_dict + + Fixed issue restoreing id on 1st traversal; last nest could reset it + + Fixed issue with @base outside of context; must be IRI + + Fixed issue loading virtuoso generated json-ld+ctx + + Fixed issue with type:vocan and vocab in context use + + Fixed no flags for tokens + + Fixed unset utf-8 flags for strings + + Fixed always unescape keywords + + Fixed strings should always be unescaped + + Fixed issue with escaped slash in URI + +2023-09-19 Mitko Iliev + + Added http_options_no_exec http virtual path option. + + The http_options_no_exec when set stops execution of stored procedure + published as service in case of pre-flight request/OPTIONS, this + is to avoid checking http method is OPTIONS in every published + procedure on that service. + +2023-09-18 Patrick van Kleef + + Refactored https check into one function + +2023-09-18 Mitko Iliev + + Fixed issue with base64 decode and trailing zeroes + + Fixed issue with missing name + +2023-09-18 Mitko Iliev + + Added support for Content-Security-Policy header + + This policy can be set in virtuoso.ini which will only allow loading of + resources (images, fonts, scripts etc) over https: + + [HTTP] + CSP_Directives = default-src https: + + See also: + https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Security-Policy + +2023-09-18 Mitko Iliev + + Fixed issue with log on delete/put/patch etc + + WM_ERROR is common for everything except for post/get; must + log delete/put/patch etc. + +2023-09-18 Mitko Iliev + + Fixed issue with dead http session + +2023-09-18 Patrick van Kleef + + Updated Conductor VAD version + +2023-09-18 Mitko Iliev + + Added simple webservices UI + + Fixed DAV browser to allow editing for json files + +2023-08-28 Mitko Iliev + + Added log info on manual enable/disable scheduler and checkpoint intervals + +2023-08-28 Mitko Iliev + + Fixed issue with AREF error on conflict join pred of pview + + If the join pred is out of scope, map internally to NULL thus no match + +2023-08-28 Mitko Iliev + + Fixed issue with get_keyword with soap options vector + + Added optional base url to http_xslt function as 3rd parameter + + Fixed do not replace trx log prefix with CHECKPOINT command + +2023-08-28 Patrick van Kleef + + Fixed issue with uninitialized variable + +2023-08-28 Mitko Iliev + + Fixed issue with chash on many threads + + Using chash on many threads can result in one branch cache to + memcache. We need to merge them to get all results + +2023-08-28 Mitko Iliev + + Added sprintf format %[xx]s for registry settings + +2023-08-28 Mitko Iliev + + Fixed SPARQL property path query returning incorrect results (bug19390) + + When the outer branch has no selection, the out code will not be reset + as the outer node is not run, therefore we reset here before leaving + +2023-08-28 Mitko Iliev + + Added input state in explain output where missing + +2023-08-28 Mitko Iliev + + Fixed issue reusing boxes + + See if we can re-use boxed str values with flags + +2023-08-28 VOS maintainer + + Fixed assignment must be recorded on the node before the end node (backport) + + Fixed deterministic ordering with mixed dtps (backport) + + Backported small fixes + +2023-08-28 Patrick van Kleef + + Used numeric entities for maximum X(HT)ML compatibility + +2023-07-26 Mitko Iliev + + Fixed issue with heterogeneous data column leading to range assert + + Usually this code block deals with data column with only numbers, dates + or any, but if the data col has reference to GROUP BY & DISTINCT it + eventually referenced RDF objects and it becomes heterogeneous. + + This case was not handled, leading to a range assert where in fact the + column structure is fine. + +2023-07-26 Patrick van Kleef + + Added CPU% and RSS usage to status() output + +2023-07-07 Patrick van Kleef + + Fixed issue with SPARQL UUID() function (fixes #515) + + Replaced the PL code with a BIF function and let the compiler know + this function cannot be optimized out of the query loop. + +2023-07-04 Patrick van Kleef + + Fixed missing grant from SPARQL_UPDATE role (fixes #1152) + + Updated version to 7.2.11-dev to mark the start of a new development cycle + +2023-06-07 Patrick van Kleef + + Merge tag 'v7.2.10' into develop/7 + + Tagged for release + +2023-06-07 Patrick van Kleef + + Merge branch 'release/7.2.10' into stable/7 + + Updated ChangeLog + + Updated version to 7.2.10 engine 3237 + + Added check for OpenSSL 3.1.x + +2023-06-07 Mitko Iliev + + Fixed issue with DV_REFERENCE + +2023-06-07 Sergey Malinin + + Fixed path to openssl libs + +2023-06-07 Patrick van Kleef + + Updated ChangeLog + + Updated NEWS.md for upcoming release + +2023-06-07 Mitko Iliev + + Fixed issue with incomplete MIME part without body + +2023-06-07 Patrick van Kleef + + Fixed "Run Query" button to use the sparqlSubmitForm function + + This allows the form to switch from GET to POST submit method when + the resulting URL is getting too long. + + The maximum length of the URL for a GET request can be + changed using: + + registry_set ('sparql-ui-max-url', '2000'); + + If you always want to use POST request use: + + registry_set ('sparql-ui-max-url', '1'); + + If you always want to use GET requests (the default) + use: + + registry_set ('sparql-ui-max-url', '0'); + +2023-06-07 Patrick van Kleef + + Updated version to 7.2.10-rc1 + + Fixed obj2json output should be canonical + + Rebuild JDBC providers + + Updated JDBC driver version + +2023-06-07 Sergey Malinin + + Removed some commented out code + +2023-06-07 Jerven bolleman + + Small optimization to VirtuosoInputStream + + Removed shared tmp bytes[16] array as it blocks a number of + optimizations. + +2023-06-07 Mitko Iliev + + Added checkpoint to end of online backup + + Fixed memory leak in bif_iri_name_id_64_vec + + Fixed issue with client_protocol mode + + Fixed check argument before calling vt_parse + + Fixed issue with TCN + + Fixed label + + Added extra opts param to pldebug print + +2023-06-07 Mitko Iliev + + Added BIF function for iso and http dates + + The PL wrapper of these procedures is left for compatibiluty in apps + +2023-06-07 Mitko Iliev + + Fixed missing escape of identifiers + + Fixed small memory leak in log replay + + Fixed string_buffer to use strses_string instead of malloc/realloc + + Fixed HTTPS accept timeout + + Added support for DROP TYPE .... IF EXISTS + + Fixed missing tags in obj2json() for UDT + +2023-06-07 Patrick van Kleef + + Fixed small SPARQL UI issues + +2023-06-07 Mitko Iliev + + Fixed do not make refs for dc_values + +2023-06-07 VOS maintainer + + Fixed issue when inserting "true"^^xsd:boolean + + Removed duplicate bif type + + Backported duration and interval fixes to v7 engine (fixes #1147) + +2023-06-07 Patrick van Kleef + + Fixed missing variable declaration (fixes #1148) + +2023-06-07 Mitko Iliev + + Added BIF http_request_status_code_get() + + This function returns the current http status code 20x/30x/30x etc + or NULL of not set. + +2023-06-07 Mitko Iliev + + Fixed RDF_LOAD_JSON_LD does not work with streams + + For now we can only load .jsonld and .jsonld.gz files + +2023-06-07 Patrick van Kleef + + Added support for bulkloading compressed .jsonld files + +2023-06-07 Mitko Iliev + + Fixed allow old clients to get application/xml + + Added support for uploading NQUAD and JSON_LD data via Conductor + +2023-06-07 Patrick van Kleef + + Fixed IRI patterns for SPARQL LOAD SERVICE (fixes #879) + + Some third party endpoints had a problem with the old pattern, which + causes Virtuoso to not properly detect the capabilities of these + endpoints. + + Also the old pattern was not very descriptive, which could cause remote + admins to block us. + + We have decided to use `urn:virtuoso:sparql:fed:probe:no-such-g` etc. as + the new IRI pattern. + + Reported by: Jerven Bolleman + +2023-06-07 Patrick van Kleef + + Added support for displaying custom dbpedia datatypes + +2023-06-07 Patrick van Kleef + + Added support for showing custom datatypes (fixes #963) + + Custom datatype is not shown when the value is treated as a string. When + there is no language and it is not `xsd:string`, it should be displayed. + + Reported-by: IS4Code + +2023-06-07 Patrick van Kleef + + Fixed issue in short-circuit evaluation (fixes #777) + + When `encname` is a null pointer, there will be a null pointer dereference + in the short-circuit evaluation. + + Found by the static analyzer of Qihoo360 CodeSafe Team! + +2023-06-07 Mitko Iliev + + Added n-quads support for SPARQL CRUD using REST (fixes #1142) + + $ curl -i --digest -u dba:dba http://localhost:8890/sparql-graph-crud-auth \ + -X POST -H 'Content-Type: application/n-quads' --data-binary @test.nq + + A default POST request can add triples to the existing graph. + + If you want to clean all the graphs mentioned in your .nq file, + you can use a PUT command, which will do a 'with-delete' similar + to the bulk loader. This feature has similar restriction: + + 1. Graphs cannot be split over 2 or more files + 2. Graphs should be limited in size based on available memory + +2023-06-07 Mitko Iliev + + Fixed use registered MIME type application/n-quads. + + Added handler for .jsonld + +2023-06-07 Ivan Mikhailov + + Fixed issues with Turtle 1.1 parser (fixes #1059) + + Fixed syntax for decimals and Turtle 1.1 rule re dot after object + without space in between. + +2023-06-07 Mitko Iliev + + Removed old grants + + Fixed use proper size for prefix + + Fixed int from temp becomes bigint, so map appropriately + + Fixed issue comparing column types against normalized source + + Fixed issue with flag comparison + + Fixed extra debug info on backup crash + + Removed redundant index + + Added debugging for bad buffer + + Fixed system bifs that start with '__' are marked as unsafe + +2023-06-07 Mitko Iliev + + Added separate option to limit number of triples in a SPARQL CONSTRUCT query + + [SPARQL] + MaxConstructTriples = 10000 ; if not set, use ResultSetMaxRows as fallback + +2023-06-07 Mitko Iliev + + Fixed issue when BIO* does not write trailing zero + +2023-06-07 Mitko Iliev + + Fixed issue with transaction mutex in checkpoint + + Keep the transaction mutex until checkpoint is done. + +2023-06-07 Mitko Iliev + + Removed duplicate define + + Fixed missing setting of itx isolation level + + Removed check for txn in itc_col_row_check; this is already done at top level call + + Fixed whitespace + + Added extra MALLOC_DEBUG code + + Added enable_cpt_rb_ck flag + + Added extra flag for testsuite + + Added option to debug buffer flags (-DBUF_FLAGS_DEBUG) + +2023-06-07 Patrick van Kleef + + Removed merge artifact (fixes #1144) + + Removed copying of images from dbpedia as fct already has them + +2023-06-07 Mitko Iliev + + Fixed issue with rdf_regex (fixes #705) + + This function is supposed to work on UTF-8 data not on narrow strings. + +2023-06-07 Mitko Iliev + + Fixed load unknown geometry as literal + + Fixed compiler warning + + Fixed issue placing simple functions inside control exp (fixes #1128) + + Fixed compare only up to cha key parts (fixes #1117) + + Added missing reuse check for dv bin (fixes #1121) + + Fixed typo in testsuite + +2023-06-07 Patrick van Kleef + + Fixed file permissions in VAD packages + +2023-06-07 Mitko Iliev + + Fixed issue if original dfe not there; see error in optimizer + + Added tsuite entries for recent fixes + + Fixed do not change col_dtp if already set before (fixes #1124) + + Fixed cannot add non-null column to existing data (fixes #1130) + + Fixed calculate set length after checking for errors + + Fixed missing check for a qexp to continue with + + Fixed first argument of CONTAINS() cannot be star (fixes #1140) + + Fixed wrap unions etc. if non-select for EXISTS ( subq ) (fixes #1139) + + Added check for non-terminals in WITH DATA (fixes #1138) + + Fixed missing check if column exists (fixes #1137) + + Fixed non-terminal in union branch is not supported (fixes #1136) + + Fixed missing check for table in positioned delete (fixes #1135) + + Fixed check number of values vs cols when inserting into view (fixes #1134) + + Fixed handling of aliases in output (fixes #1129) + + Fixed save/restore temp refs (fixes #1127) + + Fixed 64bit arith overflow (fixes #1123) + + Fixed 64bit arith exception (fixes #1122) + + Fixed missing check for max number of key parts (fixes #1120) + + Fixed expand column list during parsing (fixes #1119) + + Fixed missing arguments in table def (fixes #1118) + +2023-06-07 Patrick van Kleef + + Added additional testcases + +2023-06-07 Mitko Iliev + + Added support for IF EXISTS and IF NOT EXISTS in ALTER TABLE + + To prevent SQL errors if column already exists in the table: + + alter table add column XXX .... IF NOT EXISTS; + + To prevent SQL errors if column does not exist in the table: + + alter table drop column XXX .... IF EXISTS; + +2023-06-07 Patrick van Kleef + + Fixed issues compiling with MALLOC_DEBUG (Fixes #1116) + +2023-06-07 Mitko Iliev + + Fixed issue deleting strings with language tag (Fixes #1055) + + Fixed issue compiling with malloc_debug + + Fixed use macro to set bd_is_write for MTX debug + + Fixed issue compiling and running with mtx_debug enabled + + Fixed issue with mutex lock in phrasematch + + Fixed rwlock_tryrdlock() should return 1 on success + + Fixed issue when already running as dba + +2023-06-07 Patrick van Kleef + + Fixed issue with save/restore qualifier + + When the .sql script has a 'use XXX;' line we need to + duplicate the original qualifier and restore it at the end + of the script + +2023-06-07 Mitko Iliev + + Fixed issue with SOAP tests; must recreate SOAP user if exists + +2023-06-07 Patrick van Kleef + + Fixed missing AFTER decoration + +2023-06-07 Mitko Iliev + + Fixed issues with SOAP endpoint + + * Added missing SOAP user + * Fixed services.vsmx + +2023-06-07 Patrick van Kleef + + Rebuild JDBC drivers + +2023-06-07 Mitko Iliev + + Fixed issue generating labels in urilbl_ac_init_db + +2023-06-07 Patrick van Kleef + + Updated FCT vad version + +2023-06-07 Mitko Iliev + + Fixed use notation to get labels internally; _:vb do not make solution as per spec + +2023-06-07 Patrick van Kleef + + Fixed if set, pass lang param to navigation + 2023-06-07 Patrick van Kleef + Fixed issues truncating lists using '>>more>>' + + * only count visible li entries + * if all entries are hidden, make first one visible + * use cloneNode to limit the amount of redraws in browser + +2023-06-07 Patrick van Kleef + + Added note on `subdir-objects` setting for automake + + This setting only removes some warning messages generated by + the automake program, but may become compulsary in automake v2.0. + + Using automake versions v1.9 through v1.15, this setting actually breaks + the build with badly generated dependency files. + + Without this setting, the build actually does the correct thing for + all versions of automake 1.9 and newer, so we leave it out for now + +2023-06-07 Sergey Malinin + + Comment unnecessary include files + + Fix Win projects + + Fix issues with Win build + +2023-06-07 Patrick van Kleef + + Updated version to 7.2.10-dev to mark the start of a new development cycle + + Updated ChangeLog + Updated version to 7.2.10 engine 3237 Added check for OpenSSL 3.1.x diff --git a/NEWS.md b/NEWS.md index 2be5f9f675..ac50ce8605 100644 --- a/NEWS.md +++ b/NEWS.md @@ -1,5 +1,50 @@ # NEWS +## September 26, 2023, v7.2.11: + + * Virtuoso Engine + - Added log info on manual enable/disable scheduler and checkpoint intervals + - Added sprintf format %[xx]s for registry settings + - Added CPU% and RSS usage to status() output + - Added BIF jsonld_ctx_to_dict + - Added input state in explain output where missing + - Fixed issue with SPARQL UUID() function (fixes #515) + - Fixed missing grant from SPARQL_UPDATE role (fixes #1152) + - Fixed issue with DROP TABLE/VIEW not checking target + - Fixed issue when copying constants in union + - Fixed several issues in json parser + - Fixed issue with get_keyword with soap options vector + - Fixed issue with chash on many threads + - Fixed issue with lang matches + - Fixed issue loading graphql plugin with musl C library + - Fixed do not replace trx log prefix with CHECKPOINT command + - Fixed small typos in documentation and error messages + + * SPARQL + - Fixed SPARQL property path query returning incorrect results + - Fixed issue with conflict on join predicate of pview leading to AREF error + - Fixed issue with heterogeneous data column leading to range assert + - Fixed issue reusing boxes + - Fixed RDF quad sanity check for 'O' column + - Fixed entities in /sparql UI for maximum X(HT)ML compatibility + + * Web Server and DAV + - Added option http_options_no_exec for http virtual path + - Added support for Content-Security-Policy header + - Added optional base url to http_xslt function as 3rd parameter + - Fixed issues mixing valid and invalid MIME types in Accept header + - Fixed issue writing log on delete/put/patch etc + - Fixed missing entry for JSON-LD in RDF DET + - Fixed issue with missing href in PROPPATCH response + - Fixed issue with base64 decode and trailing zeroes + - Fixed issue with dead http session + + * Conductor + - Added simple webservices UI + - Fixed DAV browser to allow editing for json files + - Fixed import of all keys in a PEM certificate bundle + + ## June 7, 2023, v7.2.10: * Virtuoso Engine diff --git a/binsrc/conductor/account_create.vspx b/binsrc/conductor/account_create.vspx index 037803e1f1..6dde136850 100644 --- a/binsrc/conductor/account_create.vspx +++ b/binsrc/conductor/account_create.vspx @@ -742,7 +742,7 @@ 0) kn := concat(kname,'_',cast (i as varchar)); + USER_KEY_LOAD (kn, key_value, 'X.509', 'PEM', null, null, 1); + } + } http_request_status ('HTTP/1.1 302 Found'); http_header (sprintf ('Location: account_create.vspx?mode=edit&sid=%s&realm=%s&user_name=%U\r\n',self.sid ,self.realm, username)); ]]> diff --git a/binsrc/conductor/conductor.list b/binsrc/conductor/conductor.list index d168baded8..f2a49809b3 100644 --- a/binsrc/conductor/conductor.list +++ b/binsrc/conductor/conductor.list @@ -213,6 +213,7 @@ conductor/hosted_modules_show_sql.vsp conductor/hosted_modules.vspx conductor/hosted_page.vspx conductor/http_add_path.vspx +conductor/http_svc_edit.vspx conductor/http_del_path.vspx conductor/http_edit_paths.vspx conductor/http_host_clone.vspx diff --git a/binsrc/conductor/dav/dav_browser.xsl b/binsrc/conductor/dav/dav_browser.xsl index b52a1a8b0f..3899e53e33 100644 --- a/binsrc/conductor/dav/dav_browser.xsl +++ b/binsrc/conductor/dav/dav_browser.xsl @@ -5606,6 +5606,7 @@ or rowset[0] like '%.sql' or rowset[0] like '%.ini' or rowset[4] like 'text/%' + or rowset[4] = 'application/json' or rowset[4] = 'application/ld+json' or rowset[4] = 'application/sparql-query' ) diff --git a/binsrc/conductor/http_svc_edit.vspx b/binsrc/conductor/http_svc_edit.vspx new file mode 100644 index 0000000000..ebb5e0e186 --- /dev/null +++ b/binsrc/conductor/http_svc_edit.vspx @@ -0,0 +1,606 @@ + + + + + Virtuoso HTTP Server Management + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 0 then ':' else '' end, self.edit_port); + self._httphost := self.edit_httphost; + if (self.mode = 'edit') + { + self.lpath := get_keyword('path', self.vc_event.ve_params, self.lpath); + + if (length (self.edit_lpath) = 0) + self.edit_lpath := self.lpath; + + declare _ppath, _defpage, _vspuser, _soapuser, _security, _auth_realm, _auth_func, _after_func, + _sesvars, _soap_opts, _auth_opt, _global_opts varchar; + declare _dirbrowsing, _is_dav, _defdir integer; + whenever not found goto not_found; + select HP_PPATH, HP_DEFAULT, HP_DIR_BROWSEABLE, HP_RUN_VSP_AS, HP_RUN_SOAP_AS, + HP_SECURITY, HP_REALM, HP_AUTH_FUNC, HP_POSTPROCESS_FUNC, HP_PERSIST_SES_VARS, + HP_STORE_AS_DAV, deserialize (HP_SOAP_OPTIONS), deserialize (HP_AUTH_OPTIONS), + HP_IS_DEFAULT_HOST, deserialize(HP_OPTIONS) + into _ppath, _defpage, _dirbrowsing, _vspuser, _soapuser, + _security, _auth_realm, _auth_func, _after_func, _sesvars, + _is_dav, _soap_opts, _auth_opt, + _defdir, _global_opts + from DB.DBA.HTTP_PATH + where HP_HOST = self._httphost and HP_LISTEN_HOST = self._host and HP_LPATH = self.lpath; + self.ppath := _ppath; + self.defpage := _defpage; + self.vspuser := _vspuser; + self.soapuser := _soapuser; + self.security := _security; + self.auth_realm := _auth_realm; + self.auth_func := _auth_func; + self.after_func := _after_func; + self.persistvars := _sesvars; + self.soap_opts := _soap_opts; + self.auth_opt := _auth_opt; + self.global_opts := _global_opts; + self.dirbrowsing := _dirbrowsing; + self.is_dav := _is_dav; + self.defdir := _defdir; + + if (isarray (self.global_opts) and not mod (length (self.global_opts),2)) + { + -- defaults + self.xmlexec := NULL; + self.ovrexec := NULL; + self.ssbrow := ''; + self.cors := ''; + self.cors_allow_headers := ''; + self.cors_rej := 0; + self.global_opts_misc := vector(); + + -- We leave all unknown global options in self.global_opts_misc + for (declare i int, i := 0; i < length(self.global_opts); i := i+2) + { + if (self.global_opts[i] = 'xml_templates') + self.xmlexec := self.global_opts[i+1]; + else if (self.global_opts[i] = 'executable') + self.ovrexec := self.global_opts[i+1]; + else if (self.global_opts[i] = 'browse_sheet') + { + self.ssbrow := self.global_opts[i+1]; + if (not isstring (self.ssbrow)) + self.ssbrow := ''; + } + else if (self.global_opts[i] = 'noinherit') + self.noinherit := self.global_opts[i+1]; + else if (self.global_opts[i] = 'cors') + self.cors := self.global_opts[i+1]; + else if (self.global_opts[i] = 'cors_restricted') + self.cors_rej := self.global_opts[i+1]; + else if (self.global_opts[i] = 'cors_allow_headers') + self.cors_allow_headers := self.global_opts[i+1]; + else + self.global_opts_misc := vector_concat (self.global_opts_misc, vector (self.global_opts[i], self.global_opts[i+1])); + } + } + } + else if (self.mode = 'add1') + { + not_found: + self.lpath := ''; + self.defdir := 0; + self.ppath := ''; + self.defpage := ''; + + self.dirbrowsing := 0; + self.xmlexec := 0; + self.ovrexec := 0; + self.persistvars := 0; + self.vspuser := ''; + self.soapuser := ''; + } + if (exists (select 1 from HTTP_PATH where HP_HOST = self._httphost and HP_LISTEN_HOST = self._host and HP_SECURITY = 'SSL')) + self.is_https := 1; + ]]> + + + + + 0) then 1 else 0 end; + self.c_inherit.ufl_selected := case when self.noinherit is not null then 1 else 0 end; + self.dl_soapuser.ufl_value := self.soapuser; + if (self.dl_soapuser.vsl_item_values is not null) + self.dl_soapuser.vsl_selected_inx := position(cast(self.dl_soapuser.ufl_value as varchar), self.dl_soapuser.vsl_item_values) - 1; + + declare gopts varchar; + gopts := ''; + for (declare i int, i := 0; i < length(self.global_opts_misc); i := i+2) + { + gopts := concat( gopts, sprintf('%s=%s;\r\n', cast(self.global_opts_misc[i] as varchar), cast(self.global_opts_misc[i+1] as varchar))); + } + self.t_global_opt_misc.ufl_value := gopts; + gopts := ''; + for (declare i int, i := 0; i < length(self.soap_opts); i := i+2) + { + gopts := concat( gopts, sprintf('%s=%s;\r\n', cast(self.soap_opts[i] as varchar), cast(self.soap_opts[i+1] as varchar))); + } + self.t_soap_opt_misc.ufl_value := gopts; + + self.t_auth_realm.ufl_value := self.auth_realm; + self.t_auth_func.ufl_value := self.auth_func; + self.t_after_func.ufl_value := self.after_func; + if (isarray(self.auth_opt)) + { + declare idx integer; + declare opts varchar; + opts := ''; + idx := 0; + while (idx < length(self.auth_opt)) + { + opts := concat( opts, sprintf('%s=%s;\r\n', cast(self.auth_opt[idx] as varchar), cast(self.auth_opt[idx+1] as varchar))); + idx := idx + 2; + } + self.t_auth_opt.ufl_value := opts; + } + self.t_cors.ufl_value := self.cors; + self.t_cors_allow_headers.ufl_value := self.cors_allow_headers; + self.c_cors_rej.ufl_selected := self.cors_rej; + ]]> + + + + +
Please choose virtual directory type or an existing virtual directory to use as template.
+ + + + + + + + + + + + + + + +
+ + + +
+ + + + +
+ + + + + + + + + + + if (self.is_https and __proc_exists ('DB.DBA.WEBID_AUTH') is not null) + { + control.vsl_items := vector_concat (control.vsl_items, vector ('WebID protection')); + control.vsl_item_values := vector_concat (control.vsl_item_values, vector ('6')); + } + + +
+ + + + + + + +
+
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Virtual Directory Information +
Host
Interface
+ +
+ + + +
+ +
Permissions +
+ + + +
+ +
+ +
+ +
Authentication options +
+ +
+ + + + +
+ +
+ + Cross-Origin Resource Sharing + + +
+ + Allowed Headers (CORS) +
+ + +
+ +
+ + + + +
+ + + + + + + + + + + 'noinherit') + { + new_opts [j] := self.global_opts[i]; + new_opts [j+1] := self.global_opts[i+1]; + j := j + 2; + } + } + self.global_opts := new_opts; + } + if (length (self.cors)) + { + self.global_opts := vector_concat ( coalesce (self.global_opts, vector()), + vector ('cors', self.cors, + 'cors_allow_headers', self.cors_allow_headers, + 'cors_restricted', self.cors_rej)); + } + self.global_opts := DB.DBA.VECTOR_ZAP_EMPTY_OPTIONS (self.global_opts); + + if (self.lpath <> self.edit_lpath and + exists (select 1 from DB.DBA.HTTP_PATH where HP_HOST = self._httphost and HP_LISTEN_HOST = self._host and HP_LPATH = self.lpath)) + { + self.vc_is_valid := 0; + self.vc_error_message := 'Virtual directory ' || self.lpath || ' already exists.'; + return; + } + + commit work; + if (length (self.edit_lpath)) + VHOST_REMOVE (self._httphost, self._host, self.edit_lpath, 0); + + exec('VHOST_DEFINE (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)', state, message, + vector( self._httphost, self._host, self.lpath, self.ppath, + self.is_dav, self.dirbrowsing, self.defpage, + self.auth_func, self.auth_realm, self.after_func, self.vspuser, + self.soapuser, self.security, self.persistvars, self.soap_opts, + self.auth_opt, self.global_opts, self.defdir)); + catch: + if (message <> '') { + rollback work; + self.vc_is_valid := 0; + self.vc_error_message := message; + } + else { + self.mode := ''; + self.vc_data_bind(e); + self.vc_redirect (sprintf ('http_serv_mgmt.vspx?openat=%s', self._host)); + } + ]]> + + + +
+
+
+
+
+
diff --git a/binsrc/conductor/r2rml_import.vspx b/binsrc/conductor/r2rml_import.vspx index f8195e62c5..4b4a883577 100644 --- a/binsrc/conductor/r2rml_import.vspx +++ b/binsrc/conductor/r2rml_import.vspx @@ -163,7 +163,7 @@ if ((is_ttl + is_xml) = 0) { self.vc_is_valid := 0; - self.vc_error_message := 'You have attempted to upload invalid data. You can only upload RDF, Turtle, N3 serializations of RDF Data to the RDF Data Store.'; + self.vc_error_message := 'You have attempted to upload invalid data. You can only upload RDF/XML, Turtle, and N3 serializations of RDF Data to the RDF Data Store through this interface.'; return; } diff --git a/binsrc/conductor/rdf_import.vspx b/binsrc/conductor/rdf_import.vspx index 5ddfb0642d..970448abbf 100644 --- a/binsrc/conductor/rdf_import.vspx +++ b/binsrc/conductor/rdf_import.vspx @@ -150,7 +150,7 @@ if (http_request_status_code_get() > 299) { self.vc_is_valid := 0; self.vc_error_message := concat ('You have attempted to upload invalid data.', - ' You can only upload RDF, Turtle, N3, N-Quads and JSON-LD serializations of RDF Data to the RDF Data Store.'); + ' You can only upload RDF/XML, Turtle, N3, N-Quads, and JSON-LD serializations of RDF Data to the RDF Data Store through this interface.'); return; }; http_status_set (200); diff --git a/binsrc/conductor/soap_services_edit.vspx b/binsrc/conductor/soap_services_edit.vspx index 9e20055151..680bd0fc1b 100644 --- a/binsrc/conductor/soap_services_edit.vspx +++ b/binsrc/conductor/soap_services_edit.vspx @@ -1766,8 +1766,18 @@
- + +
+ + + + + + -
diff --git a/binsrc/conductor/sql/yacutia.sql b/binsrc/conductor/sql/yacutia.sql index a2f34482ba..01b1043abf 100644 --- a/binsrc/conductor/sql/yacutia.sql +++ b/binsrc/conductor/sql/yacutia.sql @@ -381,6 +381,7 @@ create procedure adm_menu_tree () + @@ -5965,6 +5966,9 @@ make_cert_stmt (in key_name varchar, in digest_type varchar := 'sha1') if (san is null) san := make_cert_iri (key_name); if (ian is null) ian := make_cert_iri (key_name); + if (aref(info, 0) <> 'RSAPublicKey') + return 'SPARQL {}'; -- only RSA is supported in cert ontology(for now) + cert_exponent := info[1]; cert_modulus := bin2hex(info[2]); cert_fingerprint := replace (cert_fingerprint, ':', ''); diff --git a/binsrc/conductor/vad_version b/binsrc/conductor/vad_version index 4cf8999e45..b47822630f 100644 --- a/binsrc/conductor/vad_version +++ b/binsrc/conductor/vad_version @@ -1 +1 @@ -1.00.8849 +1.00.8852 diff --git a/binsrc/dav/DET_RDFData.sql b/binsrc/dav/DET_RDFData.sql index 6595c208e3..322378273c 100644 --- a/binsrc/dav/DET_RDFData.sql +++ b/binsrc/dav/DET_RDFData.sql @@ -639,6 +639,8 @@ create function DB.DBA."RDFData_DAV_RES_CONTENT" (in id any, inout content any, type := 'text/plain'; else if (lpath like '%.json') type := 'application/json'; + else if (lpath like '%.jsonld') + type := 'application/ld+json'; else type := 'text/turtle'; } diff --git a/binsrc/dav/dav.sql b/binsrc/dav/dav.sql index 1cc2cd8521..f641de3c1d 100644 --- a/binsrc/dav/dav.sql +++ b/binsrc/dav/dav.sql @@ -1225,6 +1225,7 @@ create procedure WS.WS.PROPPATCH_INT ( declare _body any; declare rc, rc_all, xtree, xtd any; declare po, pn, pns, pv, prop_name, props, rc_prop any; + declare lpath varchar; rc_all := id; _body := aref_set_0 (params, 1); @@ -1266,6 +1267,13 @@ create procedure WS.WS.PROPPATCH_INT ( http ('\n', rc); http ('\n', rc); http ('\n', rc); + if (mode = 'proppatch') + { + lpath := http_path (); + if (st = 'C' and lpath not like '%/') + lpath := concat (lpath, '/'); + http (sprintf ('%V\n', DB.DBA.DAV_HREF_URL (lpath)), rc); + } xtd := xml_tree_doc (xtree); props := xpath_eval ('/propertyupdate/*/prop/*', xtd, 0); diff --git a/binsrc/driver/Makefile.am b/binsrc/driver/Makefile.am index 9a1d6a764c..8706e678ed 100644 --- a/binsrc/driver/Makefile.am +++ b/binsrc/driver/Makefile.am @@ -22,7 +22,7 @@ # # Driver version and description # -DRIVER_VERS = 07.02.3237 +DRIVER_VERS = 07.02.3238 DRIVER_DESC = OpenLink Virtuoso ODBC Driver diff --git a/binsrc/graphql/graphql_l.l b/binsrc/graphql/graphql_l.l index 8ea364631e..b8d039a652 100644 --- a/binsrc/graphql/graphql_l.l +++ b/binsrc/graphql/graphql_l.l @@ -17,7 +17,6 @@ struct sparp_s; /* forward */ #define SPAR_STRLITERAL_SPARQL_STRING 0 #define SPAR_STRLITERAL_JSON_STRING 1 #define SPAR_STRLITERAL_SPARQL_QNAME 2 -extern caddr_t spar_unescape_strliteral (struct sparp_s *sparp, const char *strg, int count_of_quotes, int mode); #define BOX_TOKEN_L graphqlyylval.box = t_box_dv_short_nchars (graphqlyytext, strlen (graphqlyytext)) %} diff --git a/binsrc/tests/suite/tview.sql b/binsrc/tests/suite/tview.sql index 612028fbc2..4a2592bdd2 100644 --- a/binsrc/tests/suite/tview.sql +++ b/binsrc/tests/suite/tview.sql @@ -144,7 +144,7 @@ select * from TVUPDATE_LOW_10; ECHO BOTH $IF $EQU $ROWCNT 1 "PASSED" "***FAILED"; ECHO BOTH ": deld from inserted view, now " $rowcnt " rows\n"; -drop view TVUPDATE; +drop table TVUPDATE; select * from TVUPDATE_LOW_10; ECHO BOTH $IF $NEQ $STATE OK "PASSED" "***FAILED"; ECHO BOTH ": trying to select from a view on a non-existent object STATE=" $STATE " MESSAGE=" $MESSAGE "\n"; diff --git a/binsrc/tests/suite/tvsp.sql b/binsrc/tests/suite/tvsp.sql index 7038835e71..74bfd0bd20 100644 --- a/binsrc/tests/suite/tvsp.sql +++ b/binsrc/tests/suite/tvsp.sql @@ -359,5 +359,38 @@ ECHO BOTH $IF $NEQ $STATE OK "PASSED" "***FAILED"; SET ARGV[$LIF] $+ $ARGV[$LIF] 1; ECHO BOTH ": B7386: log_enable(0) not nestable STATE=" $STATE " MESSAGE=" $MESSAGE "\n"; +create procedure base64test (in n int, in z int := 0) +{ + declare i int; + for (i := 0; i < n; i := i + 1) + { + declare bytes, e, r any; + if (z) + bytes := repeat ('\0', i); + else if (i > 0) + bytes := xenc_rand_bytes (i, 0); + else + bytes := ''; + bytes := cast (bytes as varchar); + e := encode_base64 (bytes); + r := decode_base64 (e); + if (bytes <> r or length (bytes) <> length (r)) + signal ('42000', sprintf ('FAILED: %s <> %s', bin2hex(bytes), bin2hex(r))); + e := encode_base64url (bytes); + r := decode_base64url (e); + if (bytes <> r or length (bytes) <> length (r)) + signal ('42000', sprintf ('FAILED: %s <> %s', bin2hex(bytes), bin2hex(r))); + } + return 'PASSED'; +}; + +select base64test(4000, 0); +ECHO BOTH $IF $EQU $STATE OK "PASSED" "***FAILED"; +SET ARGV[$LIF] $+ $ARGV[$LIF] 1; +ECHO BOTH ": encode/decode b64/b64url STATE=" $STATE " MESSAGE=" $MESSAGE "\n"; +select base64test(4000, 1); +ECHO BOTH $IF $EQU $STATE OK "PASSED" "***FAILED"; +SET ARGV[$LIF] $+ $ARGV[$LIF] 1; +ECHO BOTH ": encode/decode b64/b64url with zeroes STATE=" $STATE " MESSAGE=" $MESSAGE "\n"; ECHO BOTH "COMPLETED: VSP functions checkup (tvsp.sql) WITH " $ARGV[0] " FAILED, " $ARGV[1] " PASSED\n\n"; diff --git a/binsrc/virtodbc/virtodbc.rc b/binsrc/virtodbc/virtodbc.rc index f34c2678da..dde2212ff2 100644 --- a/binsrc/virtodbc/virtodbc.rc +++ b/binsrc/virtodbc/virtodbc.rc @@ -251,8 +251,8 @@ IDB_BITMAPVIRT BITMAP "virtodbc.bmp" // VS_VERSION_INFO VERSIONINFO - FILEVERSION 7,2,9,3236 - PRODUCTVERSION 7,2,9,3236 + FILEVERSION 7,2,11,3238 + PRODUCTVERSION 7,2,11,3238 FILEFLAGSMASK 0x17L #ifdef _DEBUG FILEFLAGS 0x1L @@ -269,11 +269,11 @@ BEGIN BEGIN VALUE "CompanyName", "OpenLink Software" VALUE "FileDescription", "Virtuoso OpenSource" - VALUE "FileVersion", "7.2.9.3236" + VALUE "FileVersion", "7.2.11.3238" VALUE "InternalName", "Virtuoso" VALUE "LegalCopyright", "Copyright (C) 1998-2023 OpenLink Software" VALUE "ProductName", "Virtuoso OpenSource" - VALUE "ProductVersion", "7.2.9.3236" + VALUE "ProductVersion", "7.2.11.3238" END END BLOCK "VarFileInfo" diff --git a/binsrc/virtuoso/viconfig.c b/binsrc/virtuoso/viconfig.c index 89f0771e8b..6527b88e48 100644 --- a/binsrc/virtuoso/viconfig.c +++ b/binsrc/virtuoso/viconfig.c @@ -125,6 +125,7 @@ extern char *https_key; extern char *https_extra; extern char *https_dhparam; extern char *https_ecdh_curve; +extern char *https_csp; extern int32 https_hsts_max_age; extern int32 https_client_verify; extern int32 https_client_verify_depth; @@ -869,7 +870,7 @@ cfg_setup (void) cp_unremap_quota = 0; else cp_unremap_quota_is_set = 1; -#if 0 /*GK: obosolete */ +#if 0 /*GK: obsolete */ if (cfg_getlong (pconfig, section, "AtomicDive", &c_atomic_dive) == -1) c_atomic_dive = 1; #endif @@ -1491,6 +1492,9 @@ cfg_setup (void) if (cfg_getlong (pconfig, section, "HSTS_MaxAge", &https_hsts_max_age) == -1) https_hsts_max_age = -1; + if (cfg_getstring (pconfig, section, "CSP_Directives", &https_csp) == -1) + https_csp = NULL; + if (cfg_getstring (pconfig, section, "SSLPrivateKey", &c_https_key) == -1) c_https_key = NULL; @@ -1988,8 +1992,8 @@ new_cfg_set_checkpoint_interval (int32 f) } /* - * Called from DBMS to build the main dbs. - * Simply passes all configuration to the dbs. + * Called from DBMS to build the main db. + * Simply passes all configuration to the db. */ void new_db_read_cfg (dbe_storage_t * ignore, char *mode) @@ -2650,7 +2654,7 @@ db_lck_lock_fd (int fd, char *name) /* we could not get a lock, so who owns it? */ fcntl (fd, F_GETLK, &fl); - log (L_ERR, "Virtuoso is already runnning (pid %ld)", fl.l_pid); + log (L_ERR, "Virtuoso is already running (pid %ld)", fl.l_pid); return -1; } #elif defined (HAVE_FLOCK_IN_SYS_FILE) diff --git a/binsrc/virtuoso/virtuoso_t.rc b/binsrc/virtuoso/virtuoso_t.rc index 031905b75e..e0e478bcf5 100644 --- a/binsrc/virtuoso/virtuoso_t.rc +++ b/binsrc/virtuoso/virtuoso_t.rc @@ -60,8 +60,8 @@ LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US // VS_VERSION_INFO VERSIONINFO - FILEVERSION 7, 2, 9, 3236 - PRODUCTVERSION 7, 2, 9, 3236 + FILEVERSION 7, 2, 11, 3238 + PRODUCTVERSION 7, 2, 11, 3238 FILEFLAGSMASK 0x17L #ifdef _DEBUG FILEFLAGS 0x1L @@ -78,11 +78,11 @@ BEGIN BEGIN VALUE "CompanyName", "OpenLink Software" VALUE "FileDescription", "Virtuoso OpenSource" - VALUE "FileVersion", "7.2.9.3236" + VALUE "FileVersion", "7.2.11.3238" VALUE "InternalName", "Virtuoso" VALUE "LegalCopyright", "Copyright (C) 1998-2023 OpenLink Software" VALUE "ProductName", "Virtuoso OpenSource" - VALUE "ProductVersion", "7.2.9.3236" + VALUE "ProductVersion", "7.2.11.3238" END END BLOCK "VarFileInfo" diff --git a/binsrc/websocket/make_vad.sh b/binsrc/websocket/make_vad.sh index f3a2ece945..7a070bb15b 100755 --- a/binsrc/websocket/make_vad.sh +++ b/binsrc/websocket/make_vad.sh @@ -171,42 +171,50 @@ directory_init() { } virtuoso_start() { - ddate=`date` - starth=`date | cut -f 2 -d :` - starts=`date | cut -f 3 -d :|cut -f 1 -d " "` - timeout=600 - $myrm -f *.lck + timeout=120 + + ECHO "Starting Virtuoso server ..." if [ "z$HOST_OS" != "z" ] then - "$SERVER" +foreground & + "$SERVER" +foreground & + + starth=`date | cut -f 2 -d :` + starts=`date | cut -f 3 -d :|cut -f 1 -d " "` + + while true + do + sleep 6 + if (netstat -an | grep "[\.\:]$PORT" | grep LISTEN > /dev/null) + then + break + fi + nowh=`date | cut -f 2 -d :` + nows=`date | cut -f 3 -d : | cut -f 1 -d " "` + + nowh=`expr $nowh - $starth` + nows=`expr $nows - $starts` + + nows=`expr $nows + $nowh \* 60` + if test $nows -ge $timeout + then + ECHO "***FAILED: Could not start Virtuoso Server within $timeout seconds" + exit 1 + fi + done else - "$SERVER" +wait - fi - stat="true" - while true - do - sleep 4 - echo "Waiting Virtuoso Server start on port $PORT..." - stat=`netstat -an | grep "[\.\:]$PORT " | grep LISTEN` - if [ "z$stat" != "z" ] - then - sleep 7 - LOG "PASSED: Virtuoso Server successfully started on port $PORT" - return 0 - fi - nowh=`date | cut -f 2 -d :` - nows=`date | cut -f 3 -d : | cut -f 1 -d " "` - nowh=`expr $nowh - $starth` - nows=`expr $nows - $starts` - nows=`expr $nows + $nowh \* 60` - if test $nows -ge $timeout + "$SERVER" +wait + if test $? -ne 0 then - LOG "***FAILED: Could not start Virtuoso Server within $timeout seconds" + ECHO "***FAILED: Could not start Virtuoso Server" exit 1 fi - done + fi + + ECHO "Virtuoso server started" + return 0 } + virtuoso_shutdown() { LOG "Shutdown Virtuoso Server..." $ISQL $DSN dba dba ERRORS=STDOUT VERBOSE=OFF PROMPT=OFF "EXEC=raw_exit();" $* >/dev/null @@ -388,7 +396,7 @@ directory_clean directory_init version_init sticker_init 1 -sticker_init 0 +#sticker_init 0 virtuoso_init #vad_create $STICKER_FS $VAD_NAME_DEVEL vad_create $STICKER_DAV $VAD_NAME_RELEASE diff --git a/configure.ac b/configure.ac index c40d6ed9e9..797c624879 100644 --- a/configure.ac +++ b/configure.ac @@ -30,7 +30,7 @@ AC_PREREQ(2.59) m4_define(vos_major, [7]) m4_define(vos_minor, [2]) -m4_define(vos_patch, [10]) +m4_define(vos_patch, [11]) m4_define(vos_devel, []) AC_INIT([Virtuoso Open Source Edition (Column Store)], @@ -401,7 +401,7 @@ dnl OBSOLETE AC_INT_16_BITS dnl now checked by AC_CHECK_SIZE(int) # if test "x$ac_cv_sizeof_void_p" != 'x8' then - AC_ERROR([The current version of $PACKAGE_NAME can only be build on 64bit platforms]) + AC_ERROR([The current version of $PACKAGE_NAME can only be built on 64bit platforms]) fi ########################################################################## @@ -1325,7 +1325,7 @@ main () [ AC_MSG_RESULT([bad. Check config.log for details]) with_proj4="no" - AC_MSG_WARN([The proj4 plugin will not be build]) + AC_MSG_WARN([The proj4 plugin will not be built]) ]) LIBS="$save_LIBS" @@ -1406,7 +1406,7 @@ main () [ AC_MSG_RESULT([bad. Check config.log for details]) with_geos="no" - AC_MSG_WARN([The geos plugin will not be build]) + AC_MSG_WARN([The geos plugin will not be built]) ]) LIBS="$save_LIBS" @@ -1527,7 +1527,7 @@ then if test "x$HS_LOOKUP" = "xnotfound" then - AC_MSG_WARN([The hslookup plugin will not be build]) + AC_MSG_WARN([The hslookup plugin will not be built]) with_hsl=no fi fi @@ -1577,7 +1577,7 @@ main () [ AC_MSG_RESULT([bad. Check config.log for details]) with_hsl="no" - AC_MSG_WARN([The hslookup plugin will not be build]) + AC_MSG_WARN([The hslookup plugin will not be built]) ]) LIBS="$save_LIBS" @@ -1621,7 +1621,7 @@ PKG_CHECK_MODULES_STATIC(IM, MagickWand, [], [ IM_CFLAGS=`"$IM_CONFIG" --cflags` IM_LIBS=`"$IM_CONFIG" --libs --static` else - AC_MSG_WARN([The ImageMagick plugin will not be build]) + AC_MSG_WARN([The ImageMagick plugin will not be built]) with_im=no fi ]) @@ -1660,7 +1660,7 @@ main () [ AC_MSG_RESULT([bad. Check config.log for details]) with_im="no" - AC_MSG_WARN([The ImageMagick plugin will not be build]) + AC_MSG_WARN([The ImageMagick plugin will not be built]) ]) LIBS="$save_LIBS" diff --git a/debian/README.Debian b/debian/README.Debian index 893cfa502e..c29a783586 100644 --- a/debian/README.Debian +++ b/debian/README.Debian @@ -54,7 +54,7 @@ the GUI in Administration Interface at http://127.0.0.1:8890/conductor/ under "WebDAV Administration / WebDAV services / Users Administrator" or use the SQL statement: -update WS.WS.SYS_DAV_USER set U_PASSWORD='' +update WS.WS.SYS_DAV_USER set U_PWD='' where U_NAME='' -- Obey Arthur Liu Tue, 22 Dec 2009 16:49:42 +0100 diff --git a/docsrc/xmlsource/server.xml b/docsrc/xmlsource/server.xml index 749fa839f3..b74f297617 100644 --- a/docsrc/xmlsource/server.xml +++ b/docsrc/xmlsource/server.xml @@ -1800,7 +1800,7 @@ impractical in all cases. - WideFileNames = 1/2/3/0 + XAnyNormalization = 1/2/3/0 0: default value. It means not to normalize anything, so for ex. "José" and "Jose" are two distinct words. 1: Any pair of base char and combinig char (NSM, non-spacing diff --git a/libsrc/Wi/auxfiles.c b/libsrc/Wi/auxfiles.c index 14c58606a2..c67cefba14 100644 --- a/libsrc/Wi/auxfiles.c +++ b/libsrc/Wi/auxfiles.c @@ -43,6 +43,7 @@ char * https_extra; char * https_dhparam; char * https_ecdh_curve; int32 https_hsts_max_age = -1; +char * https_csp; char * https_cipher_list; char * https_protocols; int32 https_client_verify = 0; diff --git a/libsrc/Wi/bif_explain.c b/libsrc/Wi/bif_explain.c index 7cdaea74f4..6683a75a7c 100644 --- a/libsrc/Wi/bif_explain.c +++ b/libsrc/Wi/bif_explain.c @@ -1755,10 +1755,13 @@ node_print (data_source_t * node) if (node->src_sets) { if (dbf_explain_level > 2) - stmt_printf (("s# %d %d ", node->src_sets, node->src_in_state)); + stmt_printf (("Set# %d i#%d ", node->src_sets, node->src_in_state)); else - stmt_printf (("s# %d ", node->src_sets)); + stmt_printf (("Set# %d ", node->src_sets)); } + else if (dbf_explain_level > 2) + stmt_printf (("i#%d ", node->src_in_state)); + if (in == (qn_input_fn) table_source_input || in == (qn_input_fn) table_source_input_unique) { @@ -2310,14 +2313,14 @@ node_print (data_source_t * node) stmt_printf (("\n shadow: ")); ssl_array_print (ose->ose_out_shadow); } - stmt_printf (("\n")); + stmt_printf (("\n} /* end of outer */\n")); } else if (in == (qn_input_fn) set_ctr_input) { QNCAST (set_ctr_node_t, sctr, node); - stmt_printf (("cluster outer seq start, set no ")); + stmt_printf (("Outer seq start, set no ")); ssl_print (sctr->sctr_set_no); - stmt_printf ((" \nsave ctx:")); + stmt_printf ((" { \nsave ctx:")); ssl_array_print (sctr->clb.clb_save); if (sctr->sctr_hash_spec) { diff --git a/libsrc/Wi/bif_file.c b/libsrc/Wi/bif_file.c index 336ab14c76..fa5dc9e8ec 100644 --- a/libsrc/Wi/bif_file.c +++ b/libsrc/Wi/bif_file.c @@ -2448,6 +2448,31 @@ bif_uuid (caddr_t * qst, caddr_t * err_ret, state_slot_t ** args) return box_dv_short_string (p); } +extern caddr_t iri_to_id (caddr_t *qst, caddr_t raw_name, int mode, caddr_t *err_ret); + +static caddr_t +bif_rdf_uuid_impl (caddr_t * qst, caddr_t * err_ret, state_slot_t ** args) +{ + caddr_t res, name; + caddr_t err = NULL; + char p[100]; + + uuid_str (p, sizeof (p)); + name = box_sprintf (128, "urn:uuid:%s", p); + box_flags (name) = BF_IRI; + + res = iri_to_id (qst, name, /*IRI_TO_ID_WITH_CREATE*/ 1, &err); + + if (NULL != err) + sqlr_resignal (err); + + if (NULL == res) + return NEW_DB_NULL; + + return res; +} + + static const char __tohex[] = "0123456789abcdef"; caddr_t md5 (caddr_t str) @@ -7465,6 +7490,7 @@ bif_file_init (void) bif_define_ex ("md5_final", bif_md5_final, BMD_RET_TYPE, &bt_varchar, BMD_DONE); bif_define_ex ("__vector_sort", bif_vector_sort, BMD_RET_TYPE, &bt_any, BMD_DONE); bif_define_ex ("uuid", bif_uuid, BMD_ALIAS, "rdf_struuid_impl", BMD_RET_TYPE, &bt_varchar, BMD_NO_FOLD, BMD_DONE); + bif_define_ex ("rdf_uuid_impl", bif_rdf_uuid_impl, BMD_RET_TYPE, &bt_iri_id, BMD_NO_FOLD, BMD_DONE); bif_define ("dime_compose", bif_dime_compose); bif_define ("dime_tree", bif_dime_tree); bif_define_ex ("file_stat", bif_file_stat, BMD_RET_TYPE, &bt_any, BMD_DONE); diff --git a/libsrc/Wi/bif_intl.c b/libsrc/Wi/bif_intl.c index 82d0ced6e9..56f05cd540 100644 --- a/libsrc/Wi/bif_intl.c +++ b/libsrc/Wi/bif_intl.c @@ -1243,6 +1243,8 @@ get_q_of_lang_in_http_accept_language (const char *lang, const char *line) int best_match_weight = 0; double best_q = 0; #define TAIL_SKIP_WS do { while ((' ' == tail[0]) || ('\t' == tail[0])) tail++; } while (0) + if (NULL == lang) + return 0; TAIL_SKIP_WS; while ('\0' != tail[0]) { @@ -1291,7 +1293,7 @@ caddr_t bif_langmatches_pct_http (caddr_t * qst, caddr_t * err_ret, state_slot_t ** args) { static const char * bifname = "langmatches_pct_http"; - caddr_t lang = bif_string_arg (qst, args, 0, bifname); + caddr_t lang = bif_string_or_null_arg (qst, args, 0, bifname); caddr_t line = bif_string_arg (qst, args, 1, bifname); double q; if (!lang) diff --git a/libsrc/Wi/bif_json.c b/libsrc/Wi/bif_json.c index 0781f3d717..26c3301135 100644 --- a/libsrc/Wi/bif_json.c +++ b/libsrc/Wi/bif_json.c @@ -156,7 +156,7 @@ jsonld_ctx_allocate (jsonp_t *jsonp_arg) /* We MUST be carefull here, MUST detect cycles in terms */ caddr_t -jsonld_term_resolve_1 (jsonp_t *jsonp_arg, caddr_t term, jsonld_item_t ** ret_item, int direct) +jsonld_term_resolve_1 (jsonp_t *jsonp_arg, caddr_t term, jsonld_item_t ** ret_item, int direct, int use_ns) { jsonld_ctx_t * ctx = jsonp_arg->curr_ctx; id_hash_t * ht = ctx ? ctx->ns2iri : NULL; @@ -177,13 +177,13 @@ jsonld_term_resolve_1 (jsonp_t *jsonp_arg, caddr_t term, jsonld_item_t ** ret_it /* use @base & @vocab if not */ if (ret_item) ret_item[0] = item ? item[0] : NULL; - if (name == term) + if (name == term && use_ns) name = jsonp_term_uri_resolve (jsonp_arg, qname); return (name ? name : qname); } caddr_t -jsonld_qname_resolve (jsonp_t *jsonp_arg, caddr_t qname, jsonld_item_t ** ret_item) +jsonld_qname_resolve_1 (jsonp_t *jsonp_arg, caddr_t qname, jsonld_item_t ** ret_item, int use_ns) { char * colon; caddr_t pref, local, ns_uri, abs_name; @@ -194,10 +194,10 @@ jsonld_qname_resolve (jsonp_t *jsonp_arg, caddr_t qname, jsonld_item_t ** ret_it (colon && strchr (qname, ':') != strrchr (qname, ':'))) /* must be more precise here ck for BF_IRI for ex. */ return qname; if (!colon) - return jsonld_term_resolve (jsonp_arg, qname, ret_item); + return jsonld_term_resolve_1 (jsonp_arg, qname, ret_item, 1, use_ns); pref = t_box_dv_short_nchars (qname, (int)(colon - qname)); local = t_box_dv_short_string (colon+1); - ns_uri = jsonld_term_resolve_1 (jsonp_arg, pref, &item, 0); + ns_uri = jsonld_term_resolve_1 (jsonp_arg, pref, &item, 0, use_ns); /* use @base & @vocab if not */ if (ret_item) ret_item[0] = item; @@ -211,7 +211,7 @@ jsonld_qname_resolve (jsonp_t *jsonp_arg, caddr_t qname, jsonld_item_t ** ret_it caddr_t jsonld_term_resolve (jsonp_t *jsonp_arg, caddr_t term, jsonld_item_t ** ret_item) { - return jsonld_term_resolve_1 (jsonp_arg, term, ret_item, 1); + return jsonld_term_resolve_1 (jsonp_arg, term, ret_item, 1, 1); } void @@ -278,16 +278,18 @@ jsonld_quad_insert (jsonp_t * jsonp_arg, jsonld_item_t *itm) if (0 == strncmp(subj, "_:", 2)) subj_iid = tf_bnode_iid (jsonp_arg->jtf, box_dv_short_string (subj)); else - subj_iid = subj = jsonld_qname_resolve(jsonp_arg, subj,NULL); + subj_iid = subj = jsonld_qname_resolve (jsonp_arg, subj, NULL); if (is_bnode_obj) obj_iid = tf_bnode_iid (jsonp_arg->jtf, box_dv_short_string (obj)); if (is_ref) { if (!is_bnode_obj) { - obj = jsonld_qname_resolve(jsonp_arg, obj,NULL); - obj_iid = obj = jsonp_uri_resolve (jsonp_arg, obj); /* relative ref obj resloved here */ + obj = jsonld_qname_resolve_1(jsonp_arg, obj, NULL, ((prop == uname_rdf_ns_uri_type)|(0 != itm->use_ns))); + obj_iid = obj = jsonp_uri_resolve (jsonp_arg, obj); /* relative ref obj resolved here */ } + if (DV_STRINGP(obj_iid) && !strlen(obj_iid)) + goto done; tf_triple (jsonp_arg->jtf, subj_iid, prop, obj_iid); } else @@ -300,6 +302,7 @@ jsonld_quad_insert (jsonp_t * jsonp_arg, jsonld_item_t *itm) if (!err) tf_triple_l (jsonp_arg->jtf, subj_iid, prop, obj, dt, lang); } +done: #ifdef _JSONLD_DEBUG_Q printf ("QUAD: "); jsonld_item_print (itm); @@ -376,6 +379,7 @@ jsonld_frame_push (jsonp_t *jsonp_arg) jsonp_arg->curr_value = NULL; jsonp_arg->curr_type = NULL; jsonp_arg->curr_lang = NULL; + jsonp_arg->curr_use_ns = 0; } jsonp_arg->last_node_no++; jsonp_arg->curr_node_no = jsonp_arg->last_node_no; @@ -398,6 +402,8 @@ jsonld_frame_pop (jsonp_t *jsonp_arg) if (!jsonp_arg->curr_id) jsonp_arg->curr_id = gethash ((void*)jsonp_arg->curr_node_no, jsonp_arg->node2id); } + if (JSON_LD_MAP == jsonp_arg->jpmode) + jsonp_arg->curr_id = itm->id; if (jsonp_arg->curr_id) JF_SET(ID); } @@ -453,9 +459,65 @@ jsonld_context_uri_get (jsonp_t * jsonp_arg, caddr_t uri, id_hash_t *ht) END_QR_RESET; if (err) /* just free and forget */ dk_free_tree (err); + if (NULL != jsonp_arg && NULL != jsonp_arg->curr_ctx && NULL != jctx.ns && 0 != strncmp (jctx.ns, "_:", 2)) + jsonp_arg->curr_ctx->ns = jctx.ns; return; } +caddr_t +bif_jsonld_ctx_to_dict (caddr_t * qst, caddr_t * err_ret, state_slot_t ** args) +{ + id_hash_t *ht; + static char * fn = "jsonld_ctx_to_dict"; + caddr_t uri = bif_string_or_uname_arg (qst, args, 0, fn); + id_hash_iterator_t *hit = bif_dict_iterator_arg (qst, args, 1, fn, 0); + uint64 flags = BOX_ELEMENTS_0 (args) > 2 ? bif_long_arg (qst, args, 2, fn) : 0; + jsonp_t jsonp; + + MP_START(); + memset (&jsonp, 0, sizeof (jsonp_t)); + jsonp.qi = (query_instance_t *)qst; + ht = t_id_hash_allocate (100, sizeof (caddr_t), sizeof (caddr_t), strhash, strhashcmp); + jsonld_context_uri_get (&jsonp, uri, ht); + + DO_IDHASH(caddr_t, k, jsonld_item_t *, v, ht) + { + if (!flags) + { + caddr_t url; + caddr_t pref, local; + caddr_t val = list (3, box_copy(k), box_copy_tree(v->type), box_num(v->flags)); + url = NULL; + if (v->flags & JLD_LIST_CONT || v->flags & JLD_LANG_CONT) /* this is a heuristic/trick to maintain AP ordered list and lang containers */ + { + iri_split_ttl_qname (v->id, &pref, &local, 0); + if (0 != strcmp (k, local)) + url = box_dv_short_concat (pref, k); + dk_free_box (pref); + dk_free_box (local); + } + if (!url) + url = box_copy(v->id); + box_flags (url) = BF_IRI; + dict_put_impl (hit, url, val, 0); + } + else /* sparql compat */ + { + caddr_t url = box_copy(v->id); + caddr_t type = box_copy_tree(v->type); + box_flags (url) = BF_IRI; + if (DV_STRING == DV_TYPE_OF(type)) + box_flags (type) = BF_IRI; + if (!type) + type = uname_xmlschema_ns_uri_hash_string; + dict_put_impl (hit, list (2, url, type), list(1, box_copy(k)), 0); + } + } + END_DO_IDHASH; + MP_DONE(); + return NULL; +} + static caddr_t bif_rdf_load_jsonld (caddr_t * qst, caddr_t * err_ret, state_slot_t ** args) @@ -473,7 +535,7 @@ bif_rdf_load_jsonld (caddr_t * qst, caddr_t * err_ret, state_slot_t ** args) jsonp_t jsonp; yyscan_t scanner; - if ((COUNTOF__TRIPLE_FEED__REQUIRED > BOX_ELEMENTS (cbk_names)) || (COUNTOF__TRIPLE_FEED__ALL < BOX_ELEMENTS (cbk_names))) + if ((COUNTOF__TRIPLE_FEED__REQUIRED > BOX_ELEMENTS_0 (cbk_names)) || (COUNTOF__TRIPLE_FEED__ALL < BOX_ELEMENTS_0 (cbk_names))) sqlr_new_error ("22023", "RDF01", "The argument #4 of rdf_load_jsonld() should be a vector of %d to %d names of stored procedures", COUNTOF__TRIPLE_FEED__REQUIRED, COUNTOF__TRIPLE_FEED__ALL ); @@ -551,4 +613,5 @@ bif_json_init (void) { bif_define ("json_parse", bif_json_parse); bif_define ("rdf_load_jsonld", bif_rdf_load_jsonld); + bif_define ("jsonld_ctx_to_dict", bif_jsonld_ctx_to_dict); } diff --git a/libsrc/Wi/bif_soap.c b/libsrc/Wi/bif_soap.c index 1c9bb3946a..9677c465ea 100644 --- a/libsrc/Wi/bif_soap.c +++ b/libsrc/Wi/bif_soap.c @@ -6215,20 +6215,7 @@ ws_soap_get_url (ws_connection_t *ws, int full_path) int inx, len; dk_session_t *out = strses_allocate (); caddr_t res; - caddr_t xproto = NULL; - int is_https = 0; - -#ifdef _SSL - SSL *ssl = (SSL *) tcpses_get_ssl (ws->ws_session->dks_session); - is_https = (NULL != ssl); -#endif - - /* Additional https check when running behind proxy */ - if (NULL != (xproto = ws_mime_header_field (ws->ws_lines, "X-Forwarded-Proto", NULL, 1))) - if (!strcmp (xproto, "https")) - is_https = 1; - if (xproto) - dk_free_box (xproto); + int is_https = ws_is_https (ws); if (!(szHost = ws_mime_header_field (ws->ws_lines, "Host", NULL, 0))) { @@ -11381,6 +11368,7 @@ ws_soap_http (ws_connection_t * ws) query_t *qr = NULL; caddr_t err = NULL, *pars, text; dk_session_t *ses = ws->ws_strses; + ws_http_map_t *vd = ws->ws_map; wcharset_t *volatile charset = ws->ws_charset; int is_http = 0; @@ -11491,6 +11479,11 @@ ws_soap_http (ws_connection_t * ws) dk_free_tree ((box_t) pars); goto end; } + if (NULL != vd && vd->hm_exec_opts && WM_OPTIONS == ws->ws_method) + { + dk_free_tree ((box_t) pars); + goto end; + } err = qr_exec (cli, call_qry, CALLER_LOCAL, NULL, NULL, &lc, pars, NULL, 1); dk_free_box ((box_t) pars); diff --git a/libsrc/Wi/cetop.c b/libsrc/Wi/cetop.c index bcce25f4cd..0e394211ca 100644 --- a/libsrc/Wi/cetop.c +++ b/libsrc/Wi/cetop.c @@ -434,7 +434,7 @@ itc_bad_len_ins (it_cursor_t * itc, db_buf_t ce, int64 delta, int dtp_cmp, int r if (1 || ASC_NUMBERS == dtp_cmp) return itc_num_cast_search (itc, ce, delta, dtp_cmp, rc); GPF_T1 - ("not to come here. All comparisons needing cast or with different length intlike compressed strings go via the general case"); + ("not to come here. All comparisons needing CAST or with different length INT-like compressed strings go via the general case"); set = itc->itc_set - itc->itc_col_first_set; if (ASC_NUMBERS != dtp_cmp && CE_FIND_LAST == rc) { @@ -1185,7 +1185,7 @@ ce_search_rld (it_cursor_t * itc, db_buf_t ce, row_no_t row_of_ce, int rc, int n if (below > 0) { if (!allow_non_unq_range) - GPF_T1 ("In rld it is suspect to find lt value in range when looking for last match"); + GPF_T1 ("In rld, it is suspect to find lt value in range when looking for last match"); itc->itc_reset_after_seg = col_ins_error = 1; } goto next_set; @@ -1912,7 +1912,7 @@ ce_search_int_delta (it_cursor_t * itc, db_buf_t ce, row_no_t row_of_ce, int rc, itc->itc_ranges[set].r_end = COL_NO_ROW; return CE_CONTINUES; } - GPF_T1 ("not supposed to hity end with eq still looking for 1st"); + GPF_T1 ("not supposed to hit end with eq still looking for 1st"); } if (0 == nth_key && CE_FIND_FIRST == rc) itc_range (itc, COL_NO_ROW, COL_NO_ROW); diff --git a/libsrc/Wi/colsearch.c b/libsrc/Wi/colsearch.c index 0b8da5f251..8179cc0fcb 100644 --- a/libsrc/Wi/colsearch.c +++ b/libsrc/Wi/colsearch.c @@ -1327,6 +1327,20 @@ itc_any_param (it_cursor_t * itc, int nth_key, dtp_t * dtp_ret) numeric_to_dv ((numeric_t) n, tmp, NUMERIC_MAX_PRECISION_INT); return (int64) tmp; } + case DV_ANY: /* usually we do not get heterogeneous data here, however transitivity may push rdf boxes in ssl column dc, should see if dc dtp can be reset before this point */ + { + db_buf_t dv; + dv = ((db_buf_t*)dc->dc_values) [itc->itc_param_order[itc->itc_set]]; + *dtp_ret = dtp_canonical[*dv]; + if (DV_RDF == *dtp_ret) + { + dv += 2; + *dtp_ret = dtp_canonical[*dv]; + } + if (DV_LONG_INT == *dtp_ret || DV_IRI_ID == *dtp_ret) + return dv_int (dv, dtp_ret); + return (int64)dv; + } default: return ((int64 *) dc->dc_values)[itc->itc_param_order[itc->itc_set]]; } diff --git a/libsrc/Wi/ddlrun.c b/libsrc/Wi/ddlrun.c index 3c21792e38..018365c078 100644 --- a/libsrc/Wi/ddlrun.c +++ b/libsrc/Wi/ddlrun.c @@ -3330,13 +3330,13 @@ ddl_droptable_pre (query_instance_t * qi, char *name) void -ddl_drop_table (query_instance_t * qi, char *name) +ddl_drop_table (query_instance_t * qi, char *name, int target_is_view) { client_connection_t *cli = qi->qi_client; caddr_t err; query_t *del_st; caddr_t drop_stmt; - int atomic; + int atomic, ddl_object_is_view; caddr_t * repl = qi->qi_trx->lt_replicate; name = ddl_complete_table_name (qi, name); @@ -3345,6 +3345,13 @@ ddl_drop_table (query_instance_t * qi, char *name) else atomic = 0; + ddl_object_is_view = sch_view_def (wi_inst.wi_schema, name); + + if (!ddl_object_is_view && target_is_view) + sqlr_new_error ("42S02", "SQ025", "The target name is a table."); + if (ddl_object_is_view && !target_is_view) + sqlr_new_error ("42S02", "SQ025", "The target name is a view."); + if (ddl_droptable_pre (qi, name)) return; @@ -3385,7 +3392,7 @@ ddl_drop_table (query_instance_t * qi, char *name) #endif - if (!sch_view_def (wi_inst.wi_schema, name)) + if (!ddl_object_is_view) { char temp[500]; caddr_t escaped_name = box_sprintf_escaped (name, 1); @@ -4048,7 +4055,7 @@ sql_ddl_node_input_1 (ddl_node_t * ddl, caddr_t * inst, caddr_t * state) LEAVE_TXN; QR_RESET_CTX { - ddl_drop_table (qi, tree->_.table_def.name); + ddl_drop_table (qi, tree->_.table_def.name, 0); } QR_RESET_CODE { @@ -4098,7 +4105,7 @@ sql_ddl_node_input_1 (ddl_node_t * ddl, caddr_t * inst, caddr_t * state) case TABLE_DROP: if (tree->_.op.arg_2 && !sch_name_to_table (wi_inst.wi_schema, tree->_.table_def.name)) break; - ddl_drop_table (qi, tree->_.op.arg_1); + ddl_drop_table (qi, tree->_.op.arg_1, (int)(ptrlong)tree->_.op.arg_3); break; case SET_PASS_STMT: diff --git a/libsrc/Wi/eqlcomp.h b/libsrc/Wi/eqlcomp.h index c460542ceb..76d92fc466 100644 --- a/libsrc/Wi/eqlcomp.h +++ b/libsrc/Wi/eqlcomp.h @@ -197,6 +197,7 @@ void qr_garbage (query_t * qr, caddr_t garbage); void sqlc_ins_keys (comp_context_t * cc, insert_node_t * ins); void table_source_om (comp_context_t * cc, table_source_t * ts); void qr_set_freeable (comp_context_t * cc, query_t * qr); +extern client_connection_t * recomp_cli; query_t *sqlc_make_policy_trig (comp_context_t *cc, dbe_table_t *tb, int op); diff --git a/libsrc/Wi/http.c b/libsrc/Wi/http.c index 948fa55788..932e55190b 100644 --- a/libsrc/Wi/http.c +++ b/libsrc/Wi/http.c @@ -1113,7 +1113,7 @@ log_info_http (ws_connection_t * ws, const char * code, OFF_T clen) } break; case 'r': - snprintf (tmp, sizeof (tmp), "%.*s", tmp_len, ws->ws_req_line && ws->ws_method != WM_ERROR ? ws->ws_req_line : "GET unspecified"); + snprintf (tmp, sizeof (tmp), "%.*s", tmp_len, ws->ws_req_line ? ws->ws_req_line : "GET unspecified"); strcat_ck (tmp, ws->ws_proto); tmp [sizeof (tmp) - 1] = 0; break; @@ -1988,8 +1988,18 @@ char http_server_id_string_buf [1024]; char *http_server_id_string = NULL; const char *http_client_id_string = "Mozilla/4.0 (compatible; OpenLink Virtuoso)"; uint32 http_default_client_req_timeout = 100; +extern char * https_csp; static char hsts_header_buf[128]; +static char csp_header_buf[128]; +caddr_t http_host_domain_url = NULL; +int32 upgrade_insecure_http = 0; + +#ifdef _SSL +#define CSP_HEADER(ws) ((https_csp != NULL) ? csp_header_buf : "") +#else +#define CSP_HEADER(ws) "" +#endif static char * hsts_header_line (ws_connection_t * ws) @@ -2474,13 +2484,18 @@ ws_strses_reply (ws_connection_t * ws, const char * volatile code) { dk_session_t * strses = ws->ws_strses; client_connection_t * cli = ws->ws_cli; - caddr_t url, - xslt_url = ws->ws_xslt_url, xslt_parms = ws->ws_xslt_params; + caddr_t url = ws->ws_xslt_doc_url, xslt_url = ws->ws_xslt_url, xslt_parms = ws->ws_xslt_params; caddr_t err = NULL, * exec_params = NULL; - size_t current_url_len = strlen (http_port) + strlen (ws->ws_path_string) + 18; - caddr_t current_url = dk_alloc_box (current_url_len, DV_SHORT_STRING); - snprintf (current_url, current_url_len, "http://localhost:%s%s", http_port, ws->ws_path_string); - url = current_url; + + if (NULL == url) + { + /* The next is a guess, virtual path may not be on localhost:server_port, + unfortunately this lagacy is used by applications, so we keep it for now. + */ + size_t url_len = strlen (http_port) + strlen (ws->ws_path_string) + 18; + ws->ws_xslt_doc_url = url = dk_alloc_box (url_len, DV_SHORT_STRING); + snprintf (url, url_len, "http://localhost:%s%s", http_port, ws->ws_path_string); + } if (!http_xslt_qr || http_xslt_qr->qr_to_recompile) err = srv_make_new_error ("42001", "HT004", "No DB.DBA.__HTTP_XSLT defined"); @@ -2536,8 +2551,9 @@ ws_strses_reply (ws_connection_t * ws, const char * volatile code) ws->ws_xslt_url = NULL; dk_free_tree (ws->ws_xslt_params); ws->ws_xslt_params = NULL; + dk_free_box (ws->ws_xslt_doc_url); + ws->ws_xslt_doc_url = NULL; len = strses_length (ws->ws_strses); - dk_free_box (current_url); } #endif if (http_print_warnings_in_output) @@ -2691,6 +2707,7 @@ ws_strses_reply (ws_connection_t * ws, const char * volatile code) } SES_PRINT (ws->ws_session, hsts_header_line(ws)); + SES_PRINT (ws->ws_session, CSP_HEADER(ws)); if (ws->ws_header) /* user-defined headers */ { @@ -3043,6 +3060,7 @@ send_multipart_byteranges (ws_connection_t *ws, int fd, "Server: %.1000s\r\n" "Connection: %s\r\n" "%s" + "%s" "\r\n" "--THIS_STRING_SEPARATES\r\n" , @@ -3052,7 +3070,8 @@ send_multipart_byteranges (ws_connection_t *ws, int fd, date_now, http_server_id_string, ws->ws_try_pipeline ? "Keep-Alive" : "close", - hsts_header_line (ws)); + hsts_header_line (ws), + CSP_HEADER(ws)); SES_PRINT (ws->ws_session, head); fprintf (stdout, "Head_mp = %s\n", head); @@ -3343,6 +3362,7 @@ ws_file (ws_connection_t * ws) "%s" "%s" "%s" + "%s" "%s", head_beg, (OFF_T_PRINTF_DTP) off, @@ -3354,6 +3374,7 @@ ws_file (ws_connection_t * ws) ws->ws_try_pipeline ? "Keep-Alive" : "close", hsts_header_line(ws), (MAINTENANCE) ? "Retry-After: 1800\r\n" : "", + CSP_HEADER(ws), ws->ws_header ? ws->ws_header : "", ranges_buffer ); @@ -6829,36 +6850,52 @@ base64_store24(char ** d, char * c) size_t decode_base64_impl (char * src, char * end, char * table) { - char * start = src; - char c0, c[4], *p; - size_t i=0; - char *d=src; - if (!src || !*src || src == end) - return 0; - while ((c0 = *src++) && src < end) { - if (c0=='=') - break; /* a = symbol is end padding */ - if ((p=strchr(table, c0))) { - c[i++]=(char) (p-table); - if (i==4) { - base64_store24(&d, c); - i=0; - } - } /* unknown symbols are ignored */ - } - if (i>0) { - for(;i<4;c[i++]=0) - ; /* will leave padding nulls - does not matter here */ - base64_store24(&d, c); + char * start = src; + char c0, c[4], s[4], *p; + size_t i = 0; + char *d = src; + if (!src || !*src || src == end) + return 0; + memset (s, 0, sizeof (s)); + while ((c0 = *src++) && src < end) + { + if ((p = strchr(table, c0))) + { + s[i] = c0; + c[i]= (char) (p - table); + if (i == 3) + { + base64_store24(&d, c); + if (s[2] == '=') + { + d -= 2; + i = 0; + break; + } + else if (s[3] == '=') + { + d -= 1; + i = 0; + break; + } + memset (s, 0, sizeof (s)); + i = 0; + } + else + { + i ++; + } + } /* unknown symbols are ignored */ } - *d=0; - if (*(d - 1) == 0) { - if (*(d - 2) == 0) - d -= 2; - else - d -= 1; + if (i > 0) + { + for(; i < 4; c[i++] = 0); + base64_store24(&d, c); + for (i = 0; i < 4; i ++) + if ('\0' == s[i]) d--; } - return (d - start); + *d = 0; + return (d - start); } caddr_t @@ -8001,7 +8038,7 @@ bif_http_request_header_full (caddr_t * qst, caddr_t * err_ret, state_slot_t ** } else { - if (lines) + if (lines && name) { int inx; size_t len; @@ -8312,11 +8349,14 @@ bif_http_xslt (caddr_t *qst, caddr_t * err_ret, state_slot_t **args) query_instance_t * qi = (query_instance_t *) qst; ws_connection_t *ws = qi->qi_client->cli_ws; caddr_t xslt_url = bif_string_or_null_arg (qst, args, 0, "http_xslt"); - caddr_t params = NULL; + caddr_t params = NULL, base = NULL; if (BOX_ELEMENTS (args) > 1) params = bif_array_or_null_arg (qst, args, 1, "http_xslt"); + if (BOX_ELEMENTS (args) > 2) + base = bif_string_or_null_arg (qst, args, 2, "http_xslt"); + if (!ws) sqlr_new_error ("42000", "HT039", "Not allowed to call the http_xslt in an non VSP context"); @@ -8324,6 +8364,8 @@ bif_http_xslt (caddr_t *qst, caddr_t * err_ret, state_slot_t **args) ws->ws_xslt_url = xslt_url ? box_dv_short_string (xslt_url) : NULL; dk_free_tree (ws->ws_xslt_params); ws->ws_xslt_params = box_copy_tree (params); + dk_free_box (ws->ws_xslt_doc_url); + ws->ws_xslt_doc_url = box_copy(base); #endif return NULL; } @@ -9029,6 +9071,8 @@ bif_http_map_table (caddr_t * qst, caddr_t * err_ret, state_slot_t ** args) map->hm_executable = 1; else if (!stricmp (option_name,"exec_as_get")) map->hm_exec_as_get = 1; + else if (!stricmp (option_name,"http_options_no_exec")) + map->hm_exec_opts = 1; else if (!stricmp (option_name,"url_rewrite")) map->hm_url_rewrite_rule = box_copy_tree (option_value); else if (!stricmp (option_name,"url_rewrite_keep_lpath")) @@ -10394,30 +10438,40 @@ bif_is_http_ctx (caddr_t *qst, caddr_t * err_ret, state_slot_t **args) return box_num(1); } -static caddr_t -bif_is_https_ctx (caddr_t *qst, caddr_t * err_ret, state_slot_t **args) +int +ws_is_https (ws_connection_t * ws) { - query_instance_t *qi = (query_instance_t *)qst; - caddr_t xproto = NULL; int is_https = 0; - ws_connection_t *ws = qi->qi_client->cli_ws; -#ifdef _SSL - SSL *ssl = NULL; -#endif - if (!ws) - return box_num(0); #ifdef _SSL - ssl = (SSL *) tcpses_get_ssl (ws->ws_session->dks_session); - is_https = (NULL != ssl); + if (ws) + { + SSL *ssl = (SSL *) tcpses_get_ssl (ws->ws_session->dks_session); + is_https = (NULL != ssl); + + if (ws->ws_lines) + { + const char *xproto = ws_header_field (ws->ws_lines, "X-Forwarded-Proto:", ""); + while (*xproto && *xproto <= '\x20') + xproto++; + if (!strncmp (xproto, "https", 5)) + is_https = 1; + } + } #endif - if (ws && ws->ws_lines && NULL != (xproto = ws_mime_header_field (ws->ws_lines, "X-Forwarded-Proto", NULL, 1))) - if (!strcmp(xproto, "https")) - is_https = 1; - if (xproto) dk_free_box (xproto); + return is_https; +} - return box_num(is_https ? 1 : 0); +static caddr_t +bif_is_https_ctx (caddr_t * qst, caddr_t * err_ret, state_slot_t ** args) +{ + query_instance_t *qi = (query_instance_t *) qst; + int is_https = 0; + + is_https = ws_is_https (qi->qi_client->cli_ws); + + return box_num (is_https ? 1 : 0); } static caddr_t @@ -11763,7 +11817,7 @@ bif_http_recall_session (caddr_t * qst, caddr_t * err_ret, state_slot_t ** args) ret[1] = (caddr_t) 1; } - if (ws && ses == ws->ws_session) + if (NULL != ses && NULL != ws && ses == ws->ws_session) { mutex_enter (thread_mtx); ses->dks_n_threads--; @@ -12100,6 +12154,12 @@ http_init_part_one () } snprintf (hsts_header_buf, sizeof (hsts_header_buf), "Strict-Transport-Security: max-age=%d\r\n", https_hsts_max_age); + if (https_csp != NULL) + { + snprintf (csp_header_buf, sizeof (csp_header_buf), "Content-Security-Policy: %s\r\n", https_csp); + if (NULL != strstr (https_csp, "upgrade-insecure-requests")) + upgrade_insecure_http = 1; + } dns_host_name = get_qualified_host_name (); split_string (WS_CORS_DEFAULT_ALLOW_HEADERS, NULL, &http_default_allow_headers_list); diff --git a/libsrc/Wi/http.h b/libsrc/Wi/http.h index 65c3032fd1..2ae65a08fc 100644 --- a/libsrc/Wi/http.h +++ b/libsrc/Wi/http.h @@ -75,6 +75,7 @@ typedef struct ws_http_map_s int hm_xml_template; int hm_executable; int hm_exec_as_get; + int hm_exec_opts; caddr_t hm_htkey; caddr_t hm_url_rewrite_rule; int hm_url_rewrite_keep_lpath; @@ -127,6 +128,7 @@ typedef struct ws_connection_s #ifdef BIF_XML caddr_t ws_xslt_url; caddr_t ws_xslt_params; + caddr_t ws_xslt_doc_url; unsigned long ws_flushed; #endif caddr_t ws_client_ip; @@ -435,5 +437,6 @@ int ws_check_connect_timeout (session_t *ses, timeout_t * to, int want); size_t http_threads_mem_report (void); extern dk_hash_t * ws_cli_sessions; extern dk_mutex_t * ws_cli_mtx; +int ws_is_https (ws_connection_t * ws); #endif /* _HTTP_H */ diff --git a/libsrc/Wi/json.h b/libsrc/Wi/json.h index 4d76353327..d15a55824c 100644 --- a/libsrc/Wi/json.h +++ b/libsrc/Wi/json.h @@ -107,6 +107,7 @@ typedef struct jsonld_item_s { caddr_t value; /* node object value, used for import, not used in ctx mode */ caddr_t lang; /* intl. */ uint32 flags; /* bitmask of node type, container, nesting, ordered or unordered set etc. see JLD_xx flags */ + char use_ns; /* @type:@vocab, i.e. use the near ns to resolve as IRI */ } jsonld_item_t; typedef struct jsonp_s { @@ -137,6 +138,7 @@ typedef struct jsonp_s { #define curr_type curr_item.type #define curr_flags curr_item.flags #define curr_node_no curr_item.node_no +#define curr_use_ns curr_item.use_ns #define JLD_ITM_INIT(itm, id, name, value, type, lang) \ itm->id = id; \ @@ -189,7 +191,8 @@ void jsonyyerror_impl(jsonp_t * jsonp_arg, const char *s); jsonld_ctx_t * jsonld_ctx_allocate (jsonp_t *jsonp_arg); void jsonld_ctx_set (jsonp_t *jsonp_arg); caddr_t jsonld_term_resolve (jsonp_t *jsonp_arg, caddr_t term, jsonld_item_t **ret_item); -caddr_t jsonld_qname_resolve (jsonp_t *jsonp_arg, caddr_t qname, jsonld_item_t **ret_item); +caddr_t jsonld_qname_resolve_1 (jsonp_t *jsonp_arg, caddr_t qname, jsonld_item_t **ret_item, int use_ns); +#define jsonld_qname_resolve(jsonp_arg,qname,ret_item) jsonld_qname_resolve_1((jsonp_arg), (qname), (ret_item), 1) void jsonld_quad_insert (jsonp_t * jsonp_arg, jsonld_item_t *itm); void jsonld_context_uri_get (jsonp_t *jsonp_arg, caddr_t uri, id_hash_t *ht); caddr_t * jsonld_item_new (caddr_t type, caddr_t id, caddr_t value, caddr_t lang, uint32 flags); diff --git a/libsrc/Wi/json.l b/libsrc/Wi/json.l index f59d643c2b..c21b5b0c2e 100644 --- a/libsrc/Wi/json.l +++ b/libsrc/Wi/json.l @@ -67,7 +67,10 @@ extern VIRT_C_LINKAGE int jsonyylex (YYSTYPE *yylval, jsonp_t *jsonp_arg, yyscan #define TOKEN_OR_STRING(tok) \ do { \ jsonp_t *jsonp_arg = jsonyyget_extra (yyscanner); \ - yylval->box = t_box_dv_short_nchars (yytext+1, strlen (yytext)-2); \ + caddr_t box = spar_unescape_strliteral (NULL, yytext, 1, SPAR_STRLITERAL_JSON_STRING); \ + if (box) \ + box_flags (box) = 0; \ + yylval->box = box; \ if (jsonp_arg->jpmode & JSON_LD) \ return tok; \ return STRING; \ @@ -77,7 +80,7 @@ struct sparp_s; /* forward */ #define SPAR_STRLITERAL_SPARQL_STRING 0 #define SPAR_STRLITERAL_JSON_STRING 1 #define SPAR_STRLITERAL_SPARQL_QNAME 2 -extern caddr_t spar_unescape_strliteral (struct sparp_s *sparp, const char *strg, int count_of_quotes, int mode); +extern caddr_t spar_unescape_strliteral (void *sparp, const char *strg, int count_of_quotes, int mode); #ifdef NO_JSONLD_MP void * @@ -143,13 +146,15 @@ U4A \xF0[\x90-\xBF][\x80-\xBF]{2} U4B [\xF1-\xF3][\x80-\xBF]{3} U4C \xF4[\x80-\x8F][\x80-\xBF]{2} UTF_8 {U2A}|{U2B}|{U3A}|{U3B}|{U4A}|{U4B}|{U4C} +SLASH "\\/" IUNRESERVED ([A-Za-z0-9\x7f-\xfe]|[-.~_]|{UCHAR}|{UTF_8}) SUB_DELIMS ([!$&''()*+,;=]) ISEGMENT_NZNC ({IUNRESERVED}|{PERCENT}|{SUB_DELIMS}|@) -IRIREF ([^\x00-\x20<>\\""{}|^`]|{UCHAR}|{UTF_8}) +IRIREF ([^\x00-\x20<>\\""{}|^`]|{UCHAR}|{UTF_8}|{SLASH}) DQ \" +AT ("@"|"\\u0040") %% @@ -168,29 +173,29 @@ DQ \" ":" { return COLON; } "," { return COMMA; } -{DQ}"@context"{DQ} { TOKEN_OR_STRING(CONTEXT); } -{DQ}"@graph"{DQ} { TOKEN_OR_STRING(GRAPH); } -{DQ}"@direction"{DQ} { TOKEN_OR_STRING(DIRECTION); } -{DQ}"@id"{DQ} { TOKEN_OR_STRING(ID); } -{DQ}"@type"{DQ} { TOKEN_OR_STRING(TYPE); } -{DQ}"@language"{DQ} { TOKEN_OR_STRING(LANGUAGE); } -{DQ}"@list"{DQ} { TOKEN_OR_STRING(LIST); } -{DQ}"@base"{DQ} { TOKEN_OR_STRING(BASE); } -{DQ}"@import"{DQ} { TOKEN_OR_STRING(IMPORT); } -{DQ}"@included"{DQ} { TOKEN_OR_STRING(INCLUDED); } -{DQ}"@index"{DQ} { TOKEN_OR_STRING(INDEX); } -{DQ}"@json"{DQ} { TOKEN_OR_STRING(JSON); } -{DQ}"@container"{DQ} { TOKEN_OR_STRING(CONTAINER); } -{DQ}"@nest"{DQ} { TOKEN_OR_STRING(NEST); } -{DQ}"@none"{DQ} { TOKEN_OR_STRING(NONE); } -{DQ}"@prefix"{DQ} { TOKEN_OR_STRING(PREFIX); } -{DQ}"@propagate"{DQ} { TOKEN_OR_STRING(PROPAGATE); } -{DQ}"@protected"{DQ} { TOKEN_OR_STRING(PROTECTED); } -{DQ}"@reverse"{DQ} { TOKEN_OR_STRING(REVERSE); } -{DQ}"@set"{DQ} { TOKEN_OR_STRING(SET); } -{DQ}"@value"{DQ} { TOKEN_OR_STRING(VALUE); } -{DQ}"@vocab"{DQ} { TOKEN_OR_STRING(VOCAB); } -{DQ}"@version"{DQ} { TOKEN_OR_STRING(VERSION); } +{DQ}{AT}"context"{DQ} { TOKEN_OR_STRING(CONTEXT); } +{DQ}{AT}"graph"{DQ} { TOKEN_OR_STRING(GRAPH); } +{DQ}{AT}"direction"{DQ} { TOKEN_OR_STRING(DIRECTION); } +{DQ}{AT}"id"{DQ} { TOKEN_OR_STRING(ID); } +{DQ}{AT}"type"{DQ} { TOKEN_OR_STRING(TYPE); } +{DQ}{AT}"language"{DQ} { TOKEN_OR_STRING(LANGUAGE); } +{DQ}{AT}"list"{DQ} { TOKEN_OR_STRING(LIST); } +{DQ}{AT}"base"{DQ} { TOKEN_OR_STRING(BASE); } +{DQ}{AT}"import"{DQ} { TOKEN_OR_STRING(IMPORT); } +{DQ}{AT}"included"{DQ} { TOKEN_OR_STRING(INCLUDED); } +{DQ}{AT}"index"{DQ} { TOKEN_OR_STRING(INDEX); } +{DQ}{AT}"json"{DQ} { TOKEN_OR_STRING(JSON); } +{DQ}{AT}"container"{DQ} { TOKEN_OR_STRING(CONTAINER); } +{DQ}{AT}"nest"{DQ} { TOKEN_OR_STRING(NEST); } +{DQ}{AT}"none"{DQ} { TOKEN_OR_STRING(NONE); } +{DQ}{AT}"prefix"{DQ} { TOKEN_OR_STRING(PREFIX); } +{DQ}{AT}"propagate"{DQ} { TOKEN_OR_STRING(PROPAGATE); } +{DQ}{AT}"protected"{DQ} { TOKEN_OR_STRING(PROTECTED); } +{DQ}{AT}"reverse"{DQ} { TOKEN_OR_STRING(REVERSE); } +{DQ}{AT}"set"{DQ} { TOKEN_OR_STRING(SET); } +{DQ}{AT}"value"{DQ} { TOKEN_OR_STRING(VALUE); } +{DQ}{AT}"vocab"{DQ} { TOKEN_OR_STRING(VOCAB); } +{DQ}{AT}"version"{DQ} { TOKEN_OR_STRING(VERSION); } true { return TRUE_L; } false { return FALSE_L; } @@ -204,7 +209,10 @@ DQ \" "\""[^\\\"\n\r\t]* { yymore(); BEGIN(STRLIT); } "\""[^\\\"\n\r\t]*"\"" { - yylval->box = t_box_dv_short_nchars (yytext+1, strlen (yytext)-2); + caddr_t box = spar_unescape_strliteral (NULL /* no sparp for JSON_LITERAL */, yytext, 1, SPAR_STRLITERAL_JSON_STRING); + if (box) + box_flags (box) = 0; + yylval->box = box; return STRING; } diff --git a/libsrc/Wi/jsonld.y b/libsrc/Wi/jsonld.y index bd42da727c..c1804558ff 100644 --- a/libsrc/Wi/jsonld.y +++ b/libsrc/Wi/jsonld.y @@ -33,7 +33,7 @@ #include "sqlfn.h" #ifdef _JSONLD_DEBUG -static void bing () {} +void bing () {} #endif #define LVL jsonp_arg->lvl #define NID jsonp_arg->curr_node_no @@ -229,16 +229,20 @@ context_item /* tbd: more specific */ } | ctx_item_name COLON scalar { /* @version, @protected etc. tba */ } | ctx_item_name COLON OBJ_BEGIN OBJ_END {} - | ctx_item_name COLON OBJ_BEGIN { CTX_DOWN; if (jsonp_arg->jpmode != JSON_LD) memset (&(jsonp_arg->curr_item), 0, sizeof (jsonld_item_t)); } - context_term_definitions OBJ_END + | ctx_item_name COLON OBJ_BEGIN { + CTX_DOWN; + if (jsonp_arg->jpmode != JSON_LD) + memset (&(jsonp_arg->curr_item), 0, sizeof (jsonld_item_t)); + } + context_term_definitions OBJ_END { - CTX_UP; if (JSON_LD_META) { caddr_t item = t_alloc (sizeof (jsonld_item_t)); memcpy (item, &jsonp_arg->curr_item, sizeof (jsonld_item_t)); t_id_hash_set (jsonp_arg->curr_ctx->ns2iri, (caddr_t)&($1), (caddr_t)&item); } + CTX_UP; } | ctx_item_name COLON array { /* xxx */ } | STRING COLON value { /* bad or skip? */ } @@ -510,6 +514,7 @@ item : CONTEXT { } | LANGUAGE COLON STRING { JLD_SET_CURRENT(lang,NULL); $$ = NULL; } /* skip trple? */ | DIRECTION COLON NCNAME { $$ = NULL; } + | BASE COLON IRI { $$ = NULL; jsonp_arg->curr_ctx->base = $3; } | TYPE COLON type_value { if (JSON_LD_DATA) { caddr_t type; @@ -814,7 +819,10 @@ item : CONTEXT { if (uname_at_vocab != itm->type) JLD_SET_CURRENT(type, itm->type); else if (uname_at_vocab == itm->type && DV_STRINGP(lit)) - JLD_SET_CURRENT(type, uname_at_id); + { + JLD_SET_CURRENT(type, uname_at_id); + JLD_SET_CURRENT(use_ns, 1); + } } jsonp_arg->curr_item.flags |= itm->flags; } diff --git a/libsrc/Wi/rdf_core.c b/libsrc/Wi/rdf_core.c index f748796f61..53ddbc1ec1 100644 --- a/libsrc/Wi/rdf_core.c +++ b/libsrc/Wi/rdf_core.c @@ -72,21 +72,7 @@ uriqa_get_host_for_dynamic_local (client_connection_t *cli, int * is_https) res = ws_mime_header_field (ws->ws_lines, "Host", NULL, 0); if (NULL != is_https) { -#ifdef _SSL - caddr_t xproto = NULL; - - *is_https = (NULL != tcpses_get_ssl (ws->ws_session->dks_session)); - - xproto = ws_mime_header_field (ws->ws_lines, "X-Forwarded-Proto", NULL, 1); - if (xproto) - { - if (!strcmp (xproto, "https")) - *is_https = 1; - dk_free_box (xproto); - } -#else - *is_https = 0; -#endif + *is_https = ws_is_https (ws); } } if (NULL == res) diff --git a/libsrc/Wi/row.c b/libsrc/Wi/row.c index 810765235d..8f144cdb11 100644 --- a/libsrc/Wi/row.c +++ b/libsrc/Wi/row.c @@ -1856,7 +1856,8 @@ row_insert_cast (row_delta_t * rd, dbe_col_loc_t * cl, caddr_t data, return; } } - if ((DV_STRING == (dtp_t)str[0] || DV_SHORT_STRING_SERIAL == (dtp_t)str[0] || IS_WIDE_STRING_DTP ((dtp_t)str[0])) && tb_is_rdf_quad (key->key_table)) + if ((DV_STRING == (dtp_t)str[0] || DV_SHORT_STRING_SERIAL == (dtp_t)str[0] || IS_WIDE_STRING_DTP ((dtp_t)str[0]) || DV_BIN == (dtp_t)str[0]) && + tb_is_rdf_quad (key->key_table)) { caddr_t err = srv_make_new_error ("42000", "RDFST", "Inserting a string into O in RDF_QUAD. RDF box is expected"); if (err_ret) diff --git a/libsrc/Wi/sort.c b/libsrc/Wi/sort.c index 78a903e1b0..af9504bc4e 100644 --- a/libsrc/Wi/sort.c +++ b/libsrc/Wi/sort.c @@ -46,7 +46,7 @@ setp_comp_array (setp_node_t * setp, caddr_t * qst, caddr_t * left, state_slot_t int rc; right_v = qst_get (qst, right[inx]); - rc = cmp_boxes (left[inx], right_v, coll, coll); + rc = cmp_boxes_safe (left[inx], right_v, coll, coll); if (rc == DVC_UNKNOWN) { /* GK: the NULLs sort high */ dtp_t dtp1 = DV_TYPE_OF (left[inx]); @@ -63,8 +63,6 @@ setp_comp_array (setp_node_t * setp, caddr_t * qst, caddr_t * left, state_slot_t rc = DVC_GREATER; } else if (DVC_NOORDER == rc) - rc = DVC_UNKNOWN; -/* { dtp_t dtp1 = DV_TYPE_OF (left[inx]); dtp_t dtp2 = DV_TYPE_OF (right_v); @@ -73,7 +71,7 @@ setp_comp_array (setp_node_t * setp, caddr_t * qst, caddr_t * left, state_slot_t else if (dtp1 > dtp2) rc = DVC_GREATER; } -*/ + if (is_rev && ORDER_DESC == (ptrlong) is_rev->data) DVC_INVERT_CMP (rc); if (rc != DVC_MATCH) diff --git a/libsrc/Wi/sparql.h b/libsrc/Wi/sparql.h index 2d20f5e591..e4823f51de 100644 --- a/libsrc/Wi/sparql.h +++ b/libsrc/Wi/sparql.h @@ -944,7 +944,7 @@ extern ccaddr_t sparp_id_to_iri (sparp_t *sparp, iri_id_t iid); /*!< returns t_b #define SPAR_STRLITERAL_SPARQL_STRING 0 #define SPAR_STRLITERAL_JSON_STRING 1 #define SPAR_STRLITERAL_SPARQL_QNAME 2 -extern caddr_t spar_unescape_strliteral (sparp_t *sparp, const char *sparyytext, int count_of_quotes, int mode); +extern caddr_t spar_unescape_strliteral (void *sparp, const char *sparyytext, int count_of_quotes, int mode); extern caddr_t spar_mkid (sparp_t * sparp, const char *prefix); extern void spar_change_sign (caddr_t *lit_ptr); diff --git a/libsrc/Wi/sparql.sql b/libsrc/Wi/sparql.sql index 3441b70487..9127cad8b8 100644 --- a/libsrc/Wi/sparql.sql +++ b/libsrc/Wi/sparql.sql @@ -2536,12 +2536,6 @@ create function DB.DBA.regexp_xfn_replace (in src varchar, in needle varchar, in } ; -create function DB.DBA.rdf_uuid_impl () -{ - return iri_to_id ('urn:uuid:' || uuid()); -} -; - --!AWK PUBLIC create function DB.DBA.rdf_timezone_impl (in dt datetime) { @@ -14580,7 +14574,6 @@ create procedure DB.DBA.RDF_CREATE_SPARQL_ROLES () 'grant execute on DB.DBA.RDF_LONG_OF_SQLVAL to SPARQL_SELECT', 'grant execute on DB.DBA.rdf_strdt_impl to SPARQL_SELECT', 'grant execute on DB.DBA.rdf_strlang_impl to SPARQL_SELECT', - 'grant execute on DB.DBA.rdf_uuid_impl to SPARQL_SELECT', 'grant execute on DB.DBA.RDF_QUAD_URI to SPARQL_UPDATE', 'grant execute on DB.DBA.RDF_QUAD_URI_L to SPARQL_UPDATE', 'grant execute on DB.DBA.RDF_QUAD_URI_L_TYPED to SPARQL_UPDATE', @@ -14758,7 +14751,9 @@ create procedure DB.DBA.RDF_CREATE_SPARQL_ROLES () 'grant execute on DB.DBA.TTLP_V_GS to SPARQL_UPDATE', 'grant execute on DB.DBA.TTLP_V to SPARQL_UPDATE', 'grant execute on DB.DBA.RDF_LOAD_RDFXML_V to SPARQL_UPDATE', - 'grant execute on DB.DBA.ID_TO_IRI_VEC to SPARQL_UPDATE' ); + 'grant execute on DB.DBA.ID_TO_IRI_VEC to SPARQL_UPDATE', + 'grant execute on DB.DBA.L_O_LOOK_NE to SPARQL_UPDATE' ); + foreach (varchar cmd in cmds) do { exec (cmd, state, msg); diff --git a/libsrc/Wi/sparql2sqltext.c b/libsrc/Wi/sparql2sqltext.c index 5fe01056c9..3f4f59642b 100644 --- a/libsrc/Wi/sparql2sqltext.c +++ b/libsrc/Wi/sparql2sqltext.c @@ -8082,7 +8082,7 @@ ssg_print_retval_simple_expn (spar_sqlgen_t *ssg, SPART *gp, SPART *tree, ssg_va } case SPAR_FUNCALL: { - int bigtext, curr_arg_is_long, prev_arg_is_long = 0, arg_ctr, arg_count = BOX_ELEMENTS (tree->_.funcall.argtrees); + int bigtext, curr_arg_is_long = 0, prev_arg_is_long = 0, arg_ctr, arg_count = BOX_ELEMENTS (tree->_.funcall.argtrees); xqf_str_parser_desc_t *parser_desc; ssg_valmode_t native = sparp_rettype_of_function (ssg->ssg_sparp, tree->_.funcall.qname, tree); if (((SSG_VALMODE_SHORT_OR_LONG == needed) && ((SSG_VALMODE_LONG == native) || (SSG_VALMODE_NUM == native) || (SSG_VALMODE_BOOL == native))) || diff --git a/libsrc/Wi/sparql_core.c b/libsrc/Wi/sparql_core.c index 46198dcdba..98be18f924 100644 --- a/libsrc/Wi/sparql_core.c +++ b/libsrc/Wi/sparql_core.c @@ -822,8 +822,9 @@ sparp_id_to_iri (sparp_t *sparp, iri_id_t iid) return NULL; /* to keep compiler happy */ } -caddr_t spar_unescape_strliteral (sparp_t *sparp, const char *strg, int count_of_quotes, int mode) +caddr_t spar_unescape_strliteral (void *_sparp, const char *strg, int count_of_quotes, int mode) { + sparp_t *sparp = (sparp_t *)_sparp; caddr_t tmp_buf; caddr_t res; const char *err_msg; @@ -5107,7 +5108,7 @@ const sparp_bif_desc_t sparp_bif_descs[] = { { "tz" , SPAR_BIF_TZ , 'S' , SSG_SD_SPARQL11_DRAFT , 1 , 1 , SSG_VALMODE_SQLVAL , { SSG_VALMODE_NUM, NULL, NULL} , SPART_VARR_IS_LIT | SPART_VARR_NOT_NULL | SPART_VARR_LONG_EQ_SQL }, { "ucase" , SPAR_BIF_UCASE , 'B' , SSG_SD_SPARQL11_DRAFT , 1 , 1 , SSG_VALMODE_LONG , { SSG_VALMODE_LONG, NULL, NULL} , SPART_VARR_IS_LIT }, { "uri" , SPAR_BIF_URI , '-' , SSG_SD_BI_OR_SPARQL11_DRAFT , 1 , 1 , SSG_VALMODE_LONG , { SSG_VALMODE_SQLVAL, NULL, NULL} , SPART_VARR_IS_IRI | SPART_VARR_IS_REF }, - { "uuid" , SPAR_BIF_UUID , 'S' , SSG_SD_SPARQL11_DRAFT , 0 , 0 , SSG_VALMODE_LONG , { SSG_VALMODE_LONG, NULL, NULL} , SPART_VARR_IS_IRI | SPART_VARR_NOT_NULL }, + { "uuid" , SPAR_BIF_UUID , 'B' , SSG_SD_SPARQL11_DRAFT , 0 , 0 , SSG_VALMODE_LONG , { SSG_VALMODE_LONG, NULL, NULL} , SPART_VARR_IS_IRI | SPART_VARR_NOT_NULL }, { "valid" , SPAR_BIF_VALID , 'B' , SSG_SD_VOS_6 , 1 , 1 , SSG_VALMODE_BOOL , { SSG_VALMODE_LONG, NULL, NULL} , SPART_VARR_IS_LIT | SPART_VARR_NOT_NULL | SPART_VARR_LONG_EQ_SQL | SPART_VARR_IS_BOOL }, { "year" , SPAR_BIF_YEAR , 'B' , SSG_SD_SPARQL11_DRAFT , 1 , 1 , SSG_VALMODE_NUM , { SSG_VALMODE_NUM, NULL, NULL} , SPART_VARR_IS_LIT | SPART_VARR_NOT_NULL | SPART_VARR_LONG_EQ_SQL } }; diff --git a/libsrc/Wi/sparql_io.sql b/libsrc/Wi/sparql_io.sql index 4839175199..6e31076738 100644 --- a/libsrc/Wi/sparql_io.sql +++ b/libsrc/Wi/sparql_io.sql @@ -928,7 +928,10 @@ create procedure DB.DBA.SPARQL_SINV_IMP (in ws_endpoint varchar, in ws_params an declare qpos integer; qpos := qtext_posmap[qctr]; http (subseq (qtext_template, prev_pos, qpos), qtext_ses); - http_sparql_object (param_row[qtext_posmap[qctr+1]-1], qtext_ses); + if (isvector (param_row)) + http_sparql_object (param_row[qtext_posmap[qctr+1]-1], qtext_ses); + else -- conflict, join pred out of scope, mapped internally to null thus no match + http_sparql_object ( UNAME'http://www.w3.org/1999/02/22-rdf-syntax-ns#nil', qtext_ses); prev_pos := qpos+8; } http (subseq (qtext_template, prev_pos), qtext_ses); diff --git a/libsrc/Wi/sparql_ui.sql b/libsrc/Wi/sparql_ui.sql index 150bc2283d..a8f183cf1e 100644 --- a/libsrc/Wi/sparql_ui.sql +++ b/libsrc/Wi/sparql_ui.sql @@ -742,7 +742,7 @@ create procedure WS.WS.SPARQL_ENDPOINT_HTML_OPTION (in lbl varchar, in help varc if (enabled) color := 'bg-light text-primary'; - http (sprintf ('%V \n', help, color, lbl)); + http (sprintf ('%V \n', help, color, lbl)); } ; @@ -813,7 +813,7 @@ create procedure WS.WS.SPARQL_ENDPOINT_GENERATE_FORM ( endpoint_xsl := registry_get ('sparql_endpoint_xsl', ''); if (length(endpoint_xsl)) - http_xslt(endpoint_xsl); + http_xslt(endpoint_xsl, null, ''); -- @@ -880,7 +880,7 @@ create procedure WS.WS.SPARQL_ENDPOINT_GENERATE_FORM ( -- Show which options are enabled/disabled -- http ('
\n'); - http ('Extensions: \n'); + http ('Extensions: \n'); WS.WS.SPARQL_ENDPOINT_HTML_OPTION('cxml', 'enable_cxml', can_cxml); WS.WS.SPARQL_ENDPOINT_HTML_OPTION('save to dav', 'enable_det', isnotnull(save_dir)); WS.WS.SPARQL_ENDPOINT_HTML_OPTION('sponge', 'enable_sponge', can_sponge); diff --git a/libsrc/Wi/sql3.y b/libsrc/Wi/sql3.y index 76ac75c762..32c365ad81 100644 --- a/libsrc/Wi/sql3.y +++ b/libsrc/Wi/sql3.y @@ -1073,8 +1073,8 @@ opt_table ; drop_table - : DROP TABLE q_table_name opt_if_exists { $$ = t_listst (3, TABLE_DROP, $3, (ptrlong) $4); } - | DROP VIEW q_table_name opt_if_exists { $$ = t_listst (3, TABLE_DROP, $3, (ptrlong) $4); } + : DROP TABLE q_table_name opt_if_exists { $$ = t_listst (4, TABLE_DROP, $3, (ptrlong) $4, (ptrlong) 0); } + | DROP VIEW q_table_name opt_if_exists { $$ = t_listst (4, TABLE_DROP, $3, (ptrlong) $4, (ptrlong) 1); } ; opt_col_add_column @@ -3424,7 +3424,7 @@ soap_proc_opt_list ; soap_proc_opt - : NAME EQUALS signed_literal { $$ = t_CONS ($1, t_CONS ($3, NULL)); } + : NAME EQUALS signed_literal { caddr_t name = $1; box_tag_modify (name, DV_STRING); $$ = t_CONS (name, t_CONS ($3, NULL)); } ; soap_kwd diff --git a/libsrc/Wi/sqlbif.c b/libsrc/Wi/sqlbif.c index 5e7421f8f1..36fdbabb25 100644 --- a/libsrc/Wi/sqlbif.c +++ b/libsrc/Wi/sqlbif.c @@ -3999,6 +3999,7 @@ bif_sprintf (caddr_t * qst, caddr_t * err_ret, state_slot_t ** args) int volatile len = box_length (str) - 1; int volatile arg_inx = 1; int arg_len = 0, arg_prec = 0; + char varc = '\0'; ptr = str; *err_ret = NULL; @@ -4023,6 +4024,7 @@ bif_sprintf (caddr_t * qst, caddr_t * err_ret, state_slot_t ** args) } ptr = start + 1; + varc = '\0'; switch (ptr[0]) { @@ -4033,9 +4035,11 @@ bif_sprintf (caddr_t * qst, caddr_t * err_ret, state_slot_t ** args) session_buffered_write_char ('%', ses); goto get_next_no_arg_inx_increment; /* see below */ + case '[': + varc = ptr[0]; case '{': { - caddr_t connvar_name, connvar_value, *connvar_valplace; + caddr_t connvar_name, connvar_value, *connvar_valplace = NULL; dtp_t connvar_dtp; query_instance_t *qi = (query_instance_t *) qst; client_connection_t *cli = qi->qi_client; @@ -4045,9 +4049,12 @@ bif_sprintf (caddr_t * qst, caddr_t * err_ret, state_slot_t ** args) while (isalnum ((unsigned char) (ptr[0])) || ('_' == ptr[0])) ptr++; - if ('}' != ptr[0]) + if (!varc && '}' != ptr[0]) sqlr_new_error ("22026", "SR585", "sprintf format %%{ should have '}' immediately after the name of connection variable"); + if (']' == varc && ']' != ptr[0]) + sqlr_new_error ("22026", "SR585", + "sprintf format %%[ should have ']' immediately after the name of connection variable"); ptr++; @@ -4057,19 +4064,40 @@ bif_sprintf (caddr_t * qst, caddr_t * err_ret, state_slot_t ** args) memset (format, 0, sizeof (format)); memcpy (format, start + 2, MIN ((ptr - start) - 3, sizeof (format) - 1)); - connvar_name = box_dv_short_string (format); - connvar_valplace = (caddr_t *) id_hash_get (cli->cli_globals, (caddr_t) & connvar_name); - dk_free_box (connvar_name); + if (!varc) + { + connvar_name = box_dv_short_string (format); + connvar_valplace = (caddr_t *) id_hash_get (cli->cli_globals, (caddr_t) & connvar_name); + dk_free_box (connvar_name); - if (NULL != connvar_valplace) - connvar_value = connvar_valplace[0]; - else - { - connvar_value = uriqa_get_default_for_connvar (qi, format); - if (NULL == connvar_value) - sqlr_new_error ("22023", "SR587", - "Connection variable is mentioned by sprintf format %%{%s} but it does not exist", format); - } + if (NULL != connvar_valplace) + connvar_value = connvar_valplace[0]; + else + { + connvar_value = uriqa_get_default_for_connvar (qi, format); + if (NULL == connvar_value) + sqlr_new_error ("22023", "SR587", + "Connection variable is mentioned by sprintf format %%{%s} but it does not exist", format); + } + } + else + { + connvar_valplace = NULL; /* this s to free value below */ + IN_TXN; + connvar_value = registry_get (format); + LEAVE_TXN; + if (NULL == connvar_value) + { + if (recomp_cli == cli) + { + log_error ("Registry setting is mentioned by sprintf format %%[%s] but it does not exist", format); + connvar_value = box_dv_short_string ("(NULL)"); + } + else + sqlr_new_error ("22023", "SR587", + "Registry setting is mentioned by sprintf format %%[%s] but it does not exist", format); + } + } connvar_dtp = DV_TYPE_OF (connvar_value); @@ -10156,7 +10184,7 @@ box_cast (caddr_t * qst, caddr_t data, ST * dtp, dtp_t arg_dtp) } if (0 == rb->rb_is_complete) #ifdef DEBUG - sqlr_new_error ("22023", (IS_BOX_POINTER (qst) && (((query_instance_t *)qst)->qi_no_cast_error)) ? "sR066" : "SR066", "Unsupported case in CONVERT (incomplete RDF box -> %s)", dv_type_title((int) (dtp->type))); + sqlr_new_error ("22023", (IS_BOX_POINTER (qst) && (((query_instance_t *)qst)->qi_no_cast_error)) ? "SR066" : "SR066", "Unsupported case in CONVERT (incomplete RDF box -> %s)", dv_type_title((int) (dtp->type))); #else sqlr_new_error ("22023", "SR066", "Unsupported case in CONVERT (incomplete RDF box -> %s)", dv_type_title((int) (dtp->type))); #endif @@ -10533,7 +10561,12 @@ box_cast (caddr_t * qst, caddr_t data, ST * dtp, dtp_t arg_dtp) do_numeric: { numeric_t res = numeric_allocate (); - err = numeric_from_x (res, data, (int) unbox (((caddr_t*)dtp)[1]), (int) unbox (((caddr_t*)dtp)[2]), "CAST", 0, NULL); + char tmp[MAX_NAME_LEN], *cast_name; + if (IS_STRING_DTP (arg_dtp)) + cast_name = data; + else + snprintf (tmp, MAX_NAME_LEN, "data of type %s", dv_type_title(arg_dtp)), cast_name = tmp; + err = numeric_from_x (res, data, (int) unbox (((caddr_t*)dtp)[1]), (int) unbox (((caddr_t*)dtp)[2]), cast_name, 0, NULL); if (err) { numeric_free (res); @@ -13555,6 +13588,10 @@ bif_checkpoint_interval (caddr_t * qst, caddr_t * err_ret, state_slot_t ** args) c_checkpoint_interval = new_interval; cfg_autocheckpoint = new_interval > 0 ? (60000L * new_interval) : 0L; + if (!cfg_autocheckpoint) + log_info ("Checkpoint is disabled."); + else + log_info ("Checkpoint is enabled on every %d min.", new_interval); if (!atomic) { @@ -13585,6 +13622,10 @@ bif_scheduler_interval (caddr_t * qst, caddr_t * err_ret, state_slot_t ** args) if (0 > new_period) new_period = 0; cfg_scheduler_period = 60000L * new_period; + if (!cfg_scheduler_period) + log_info ("Scheduler events are disabled."); + else + log_info ("Scheduler events are enabled on every %d min.", new_period); if (!atomic) { diff --git a/libsrc/Wi/sqlbif.h b/libsrc/Wi/sqlbif.h index cb5d9e1d25..893427900b 100644 --- a/libsrc/Wi/sqlbif.h +++ b/libsrc/Wi/sqlbif.h @@ -338,6 +338,8 @@ EXE_EXPORT (int, uudecode_base64, (char * src, char * tgt)); EXE_EXPORT (caddr_t, sprintf_inverse, (caddr_t *qst, caddr_t *err_ret, ccaddr_t str, ccaddr_t fmt, long hide_errors)); EXE_EXPORT (caddr_t, sprintf_inverse_ex, (caddr_t *qst, caddr_t *err_ret, ccaddr_t str, ccaddr_t fmt, long hide_errors, unsigned char *expected_dtp_strg)); +EXE_EXPORT (caddr_t, spar_unescape_strliteral, (void *sparp, const char *sparyytext, int count_of_quotes, int mode)); + /* another 32 bit seed used in blobs */ extern int32 rnd_seed_b; extern int no_free_set; diff --git a/libsrc/Wi/sqlgen.c b/libsrc/Wi/sqlgen.c index 42f5e82977..30d3ffcb8e 100644 --- a/libsrc/Wi/sqlgen.c +++ b/libsrc/Wi/sqlgen.c @@ -5526,14 +5526,16 @@ sqlg_dt_query_1 (sqlo_t * so, df_elt_t * dt_dfe, query_t * ext_query, ST ** targ qn_ensure_prev (sc, &head, qn); sqlg_outer_with_iters (dfe, qn, &head); } - else if (DFE_DT== dfe->dfe_type && dfe->_.table.ot->ot_is_outer && dfe->_.sub.ot->ot_is_proc_view) + else if (DFE_DT== dfe->dfe_type && dfe->_.table.ot->ot_is_outer + && (IS_QN (qn, hash_source_input) || dfe->_.sub.ot->ot_is_proc_view)) { sqlg_set_no_if_needed (sc, &head); qn_ensure_prev (sc, &head, qn); sqlg_outer_with_iters (dfe, qn, &head); } else if (DFE_DT== dfe->dfe_type - && dfe->_.sub.ot->ot_is_outer && (1 != cl_run_local_only || sqlg_is_vector) && IS_QN (qn, subq_node_input)) + && dfe->_.sub.ot->ot_is_outer + && IS_QN (qn, subq_node_input)) { subq_source_t * sqs = (subq_source_t *)qn; outer_seq_end_node_t * ose; diff --git a/libsrc/Wi/sqlnode.h b/libsrc/Wi/sqlnode.h index 77d2eba278..a8ce7c06e5 100644 --- a/libsrc/Wi/sqlnode.h +++ b/libsrc/Wi/sqlnode.h @@ -810,7 +810,7 @@ typedef struct outer_seq_end_s state_slot_t * ose_prev_set_no; state_slot_t ** ose_out_slots; /* the ssls that are null for the outer row */ state_slot_t ** ose_out_shadow; /* If vectored, ssl vec (not ref) ssls for the nullable columns. Values are a solid copy of ose out slots */ - state_slot_t * ose_bits; + state_slot_t * ose_bits; /* keeps bitmask for outer join set/null */ state_slot_t * ose_buffered_row; int ose_last_outer_set; /* set no of the last outer row. inx of int in qi */ } outer_seq_end_node_t; diff --git a/libsrc/Wi/sqlrun.c b/libsrc/Wi/sqlrun.c index 9de04db614..537e71a93a 100644 --- a/libsrc/Wi/sqlrun.c +++ b/libsrc/Wi/sqlrun.c @@ -2742,8 +2742,7 @@ op_node_input (op_node_t * op, caddr_t * inst, caddr_t * state) case OP_CHECKPOINT: { ddl_commit (qi); - sf_makecp (arg_1 ? box_dv_short_string (arg_1) : sf_make_new_log_name (wi_inst.wi_master), - qi->qi_trx, 0, 0); + sf_makecp (sf_make_new_log_name (wi_inst.wi_master), qi->qi_trx, 0, 0); } break; diff --git a/libsrc/Wi/sqlvec.c b/libsrc/Wi/sqlvec.c index 59f454edaf..9fbcede28d 100644 --- a/libsrc/Wi/sqlvec.c +++ b/libsrc/Wi/sqlvec.c @@ -3029,6 +3029,8 @@ qn_vec_slots (sql_comp_t * sc, data_source_t * qn, dk_hash_t * res, dk_hash_t * { sc->sc_pre_code_of = qn; cv_vec_slots (sc, qn->src_pre_code, res, all_res, non_cl_local); + if (IS_QN (qn, end_node_input)) + cv_vec_slots (sc, qn->src_after_test, res, all_res, non_cl_local); sc->sc_pre_code_of = NULL; sc->sc_ssl_prereset_only = sc->sc_vec_new_ssls; } @@ -3102,6 +3104,18 @@ qn_vec_slots (sql_comp_t * sc, data_source_t * qn, dk_hash_t * res, dk_hash_t * sqs->sqs_query->qr_select_node->sel_vec_role = SEL_VEC_DT; sqs->sqs_query->qr_select_node->src_gen.src_sets = sqs->src_gen.src_sets; sqs->sqs_query->qr_select_node->src_gen.src_out_fill = sqs->src_gen.src_out_fill; +#if 0 + if (IS_QN(sqs->sqs_query->qr_head_node, union_node_input)) + { + QNCAST (union_node_t, un, sqs->sqs_query->qr_head_node); + DO_SET (query_t *, term, &un->uni_successors) + { + term->qr_select_node->src_gen.src_sets = sqs->src_gen.src_sets; + term->qr_select_node->src_gen.src_out_fill = sqs->src_gen.src_out_fill; + } + END_DO_SET(); + } +#endif DO_BOX (state_slot_t *, out, inx, sqs->sqs_out_slots) { state_slot_t *sh = (state_slot_t *) gethash ((void *) (ptrlong) out->ssl_index, sc->sc_vec_ssl_shadow); @@ -3400,7 +3414,7 @@ qn_vec_slots (sql_comp_t * sc, data_source_t * qn, dk_hash_t * res, dk_hash_t * { int ign = 0; QNCAST (end_node_t, en, qn); - cv_vec_slots (sc, en->src_gen.src_after_test, NULL, NULL, &ign); + /* after test of an end node is done together with the precode above */ if (en->src_gen.src_after_test && en->src_gen.src_after_code) { dk_set_t save = sc->sc_vec_pred; @@ -4271,7 +4285,7 @@ sqlg_vec_qns (sql_comp_t * sc, data_source_t * qn, dk_set_t prev_nodes) else if (IS_QN (qn, outer_seq_end_input) || (IS_QN (qn, select_node_input_subq) && ((select_node_t *)qn)->sel_subq_inlined)) prev_nodes = sc->sc_vec_pred; - if (IS_QN (qn, gs_union_node_input)) + else if (IS_QN (qn, gs_union_node_input)) qn = qn_next (qn); t_set_push (&prev_nodes, (void *) qn); sc->sc_vec_pred = prev_nodes; diff --git a/libsrc/Wi/sqlver.h b/libsrc/Wi/sqlver.h index 642982cef6..d3e41fb2d2 100644 --- a/libsrc/Wi/sqlver.h +++ b/libsrc/Wi/sqlver.h @@ -35,7 +35,7 @@ #define DBMS_SRV_NAME PRODUCT_DBMS " Universal Server" #define DBMS_SRV_VER_ONLY "07.20" #define DBMS_SRV_GEN_MAJOR "32" -#define DBMS_SRV_GEN_MINOR "37" +#define DBMS_SRV_GEN_MINOR "38" #define DBMS_SRV_VER DBMS_SRV_VER_ONLY "." \ DBMS_SRV_GEN_MAJOR DBMS_SRV_GEN_MINOR diff --git a/libsrc/Wi/sqlview.c b/libsrc/Wi/sqlview.c index dd785aeebf..316550a57e 100644 --- a/libsrc/Wi/sqlview.c +++ b/libsrc/Wi/sqlview.c @@ -539,6 +539,13 @@ void sqlc_union_constants (ST * sel) { int inx; + if (ST_P (sel, UNION_ALL_ST) || ST_P (sel, UNION_ST)) + { + sqlc_union_constants (sel->_.bin_exp.left); + return; + } + if (!ST_P(sel, SELECT_STMT)) + return; DO_BOX (ST *, tree, inx, sel->_.select_stmt.selection) { if (ST_P (tree, BOP_AS) && SQLC_IS_LIT (tree->_.as_exp.left)) diff --git a/libsrc/Wi/sqlvnode.c b/libsrc/Wi/sqlvnode.c index 4bbe887075..a07ced0e4c 100644 --- a/libsrc/Wi/sqlvnode.c +++ b/libsrc/Wi/sqlvnode.c @@ -141,6 +141,7 @@ select_node_input_subq_vec (select_node_t * sel, caddr_t * inst, caddr_t * state bits = sel_extend_bits (sel, inst, set_no, &bits_max); bits[set_no >> 3] |= 1 << (set_no & 7); } + return; } else if (SEL_VEC_SCALAR == sel->sel_vec_role && sel->sel_scalar_ret) { @@ -158,6 +159,7 @@ select_node_input_subq_vec (select_node_t * sel, caddr_t * inst, caddr_t * state dc_assign_copy (inst, sel->sel_scalar_ret, ext_set_no, sel->sel_out_slots[0], row); } } + return; } else if (SEL_VEC_DT == sel->sel_vec_role) { @@ -576,6 +578,9 @@ set_ctr_vec_input (set_ctr_node_t * sctr, caddr_t * inst, caddr_t * state) } memzero (bits, box_length (bits)); SRC_IN_STATE (sctr, inst) = inst; + /* reset outer's results as they will be never run, but filled further */ + if (ose->src_gen.src_pre_reset) + dc_reset_array (inst, (data_source_t *)ose, ose->src_gen.src_pre_reset, n_sets); } QST_INT (inst, sctr->src_gen.src_out_fill) = 0; DC_CHECK_LEN (dc, n_sets - 1); @@ -660,7 +665,7 @@ sqs_out_sets (subq_source_t * sqs, caddr_t * inst) QST_INT (inst, sqs->src_gen.src_out_fill) = 0; for (inx = 0; inx < n_res; inx++) { - int set = qst_vec_get_int64 (inst, sel->sel_set_no, inx); + int set = sel->sel_set_no ? qst_vec_get_int64 (inst, sel->sel_set_no, inx) : 0; qn_result ((data_source_t *) sqs, inst, set); } } @@ -705,7 +710,6 @@ subq_node_vec_input (subq_source_t * sqs, caddr_t * inst, caddr_t * state) qi->qi_set_mask = NULL; qi->qi_n_sets = set_nos->dc_n_values; err = subq_next (sqs->sqs_query, inst, flag); - flag = CR_OPEN; if (IS_BOX_POINTER (err)) sqlr_resignal (err); if ((caddr_t) SQL_NO_DATA_FOUND == err) @@ -713,6 +717,7 @@ subq_node_vec_input (subq_source_t * sqs, caddr_t * inst, caddr_t * state) SRC_IN_STATE (sqs, inst) = NULL; return; } + flag = CR_OPEN; if (uni) { int nth = unbox (qst_get (inst, uni->uni_nth_output)) - 1; @@ -722,7 +727,7 @@ subq_node_vec_input (subq_source_t * sqs, caddr_t * inst, caddr_t * state) QST_INT (inst, sqs->src_gen.src_out_fill) = 0; for (inx = 0; inx < n_res; inx++) { - int set = qst_vec_get_int64 (inst, sel->sel_set_no, inx); + int set = sel->sel_set_no ? qst_vec_get_int64 (inst, sel->sel_set_no, inx) : 0; qn_result ((data_source_t *) sqs, inst, set); } if (QST_INT (inst, sqs->src_gen.src_out_fill)) @@ -769,7 +774,7 @@ outer_seq_end_vec_input (outer_seq_end_node_t * ose, caddr_t * inst, caddr_t * s if (!out) continue; out_dc = QST_BOX (data_col_t *, inst, ssl->ssl_index); - shadow_dc = QST_BOX (data_col_t *, inst, ose->ose_out_shadow[inx]->ssl_index); + shadow_dc = QST_BOX (data_col_t *, inst, out->ssl_index); len = dc_elt_size (out_dc); dc_reset (shadow_dc); if (shadow_dc->dc_dtp != out_dc->dc_dtp) diff --git a/libsrc/Wi/sqlvrun.c b/libsrc/Wi/sqlvrun.c index 6efe85a448..a0018b0dee 100644 --- a/libsrc/Wi/sqlvrun.c +++ b/libsrc/Wi/sqlvrun.c @@ -3840,6 +3840,19 @@ vec_fref_group_result (fun_ref_node_t * fref, table_source_t * ts, caddr_t * ins int set_in_sctr = agg_set_no ? qst_vec_get_int64 (inst, agg_set_no, set) : set; ((query_instance_t *) branch)->qi_set = set_in_sctr; fref_setp_trace (fref, branch); + DO_SET (setp_node_t *, setp, &fref->fnr_setps) + { + hash_area_t * ha = setp->setp_ha; + if (HA_GROUP != ha->ha_op) + continue; + if (1 == n_sets && (tree = (index_tree_t*) (SSL_REF == ha->ha_tree->ssl_type || SSL_VEC == ha->ha_tree->ssl_type ? sslr_qst_get (branch, (state_slot_ref_t*)ha->ha_tree, 0) : qst_get (branch, ha->ha_tree)))) + { + if (tree->it_hi && tree->it_hi->hi_chash) + chash_to_memcache (inst, tree, ha); + } + } + END_DO_SET(); + fref_setp_flush (fref, branch); qi->qi_set = set_in_sctr; DO_SET (setp_node_t *, setp, &fref->fnr_setps) diff --git a/libsrc/Wi/srvstat.c b/libsrc/Wi/srvstat.c index de01d597d6..2ec5fafac3 100644 --- a/libsrc/Wi/srvstat.c +++ b/libsrc/Wi/srvstat.c @@ -1360,6 +1360,7 @@ status_report (const char * mode, query_instance_t * qi) st_started_since_year, st_started_since_month, st_started_since_day, st_started_since_hour, st_started_since_minute, dt_local_tz_for_logs / 60); } + rep_printf ("CPU: %.02f%% RSS: %ldMB\n", curr_cpu_pct, curr_mem_rss); if (!gen_info) return; if (lite_mode) diff --git a/libsrc/Wi/url_rewrite.sql b/libsrc/Wi/url_rewrite.sql index 18c2ffd144..7cfa054955 100644 --- a/libsrc/Wi/url_rewrite.sql +++ b/libsrc/Wi/url_rewrite.sql @@ -907,7 +907,7 @@ create procedure DB.DBA.URLREWRITE_CALC_QS (in accept varchar, in s_accept varch else { declare qtok varchar; - tmp := split_and_decode (q, 0, '\0\0='); + tmp := split_and_decode (trim(q), 0, '\0\0='); qtok := null; if (isvector (tmp) and 0 = mod (length(tmp), 2)) qtok := get_keyword ('q', tmp); diff --git a/libsrc/Wi/vec.c b/libsrc/Wi/vec.c index ebe4c9f4c9..688a3b31f7 100644 --- a/libsrc/Wi/vec.c +++ b/libsrc/Wi/vec.c @@ -497,17 +497,29 @@ dc_append_null (data_col_t * dc) } +/* + * deserialize and eventually re-use the same box or even box itself, + * very dangerous since it is used often via ssl_box_index could make a big confusion + * esp. if single ssl has cast to two distinct cast ssls think about that + */ caddr_t box_deserialize_reusing (db_buf_t string, caddr_t box) { boxint n; iri_id_t iid; int len, head_len; - dtp_t old_dtp; + dtp_t old_dtp, dtp, flags = 0; if (!IS_BOX_POINTER (box)) return box_deserialize_string ((caddr_t) string, INT32_MAX, 0); old_dtp = box_tag (box); - switch (string[0]) + dtp = *string; + if (DV_BOX_FLAGS == dtp) + { + flags = LONG_REF_NA(string + 1); + string += 5; + dtp = *string; + } + switch (dtp) { case DV_SINGLE_FLOAT: if (DV_SINGLE_FLOAT == old_dtp) @@ -585,6 +597,7 @@ box_deserialize_reusing (db_buf_t string, caddr_t box) { box_reuse (box, (caddr_t) string + head_len, len + 1, DV_STRING); box[len] = 0; + box_flags (box) = flags; return box; } goto no_reuse; @@ -615,6 +628,8 @@ box_deserialize_reusing (db_buf_t string, caddr_t box) /* read first so that there's no ref to freed if throw from read */ caddr_t x = box_deserialize_string ((caddr_t) string, INT32_MAX, 0); dk_free_tree (box); + if (flags && NULL != x) + box_flags (x) = flags; return x; } } diff --git a/libsrc/Wi/vecins.c b/libsrc/Wi/vecins.c index ebdcc68791..b207a6df6b 100644 --- a/libsrc/Wi/vecins.c +++ b/libsrc/Wi/vecins.c @@ -586,7 +586,7 @@ dc_mp_insert_copy_any (mem_pool_t * mp, data_col_t * dc, int inx, dbe_column_t * db_buf_t rdf_id = mp_dv_rdf_to_db_serial (mp, dv); return (caddr_t) rdf_id; } - if ((DV_STRING == dv[0] || DV_SHORT_STRING_SERIAL == dv[0] || DV_DB_NULL == dv[0] || + if ((DV_STRING == dv[0] || DV_SHORT_STRING_SERIAL == dv[0] || DV_DB_NULL == dv[0] || DV_BIN == dv[0] || DV_UNAME == dv[0] || DV_SYMBOL == dv[0] || DV_BOX_FLAGS == dv[0] || IS_WIDE_STRING_DTP (dv[0])) && col && 'O' == col->col_name[0] && tb_is_rdf_quad (col->col_defined_in) && !f_read_from_rebuilt_database) { diff --git a/libsrc/Wi/virtual_dir.sql b/libsrc/Wi/virtual_dir.sql index fd70e1b840..20c4097132 100644 --- a/libsrc/Wi/virtual_dir.sql +++ b/libsrc/Wi/virtual_dir.sql @@ -1475,54 +1475,41 @@ create procedure DB.DBA.VHOST_DUMP_SQL ( ; -- /* get a header field based on max of quality value */ -create procedure DB.DBA.HTTP_RDF_GET_ACCEPT_BY_Q ( - in accept varchar, - in mask any := null) +create procedure DB.DBA.HTTP_RDF_GET_ACCEPT_BY_Q (in accept varchar, in mask any := null) { - declare format, item varchar; - declare arr, arr2, arr3 any; - declare i, l, j, k integer; + declare format, item, qstr varchar; + declare mime_vec, vec any; + declare pos integer; declare q, q_best double precision; q := 0; q_best := 0; format := null; - arr := split_and_decode (accept, 0, '\0\0,'); - l := length (arr); - for (i := 0; i < l; i := i + 1) - { - arr2 := split_and_decode (trim (arr[i]), 0, '\0\0;'); - k := length (arr2); - if (k > 0) + mime_vec := split_and_decode (accept, 0, '\0\0,'); + foreach (varchar mime in mime_vec) do { - item := trim (arr2[0]); - q := 1.0; - for (j := 1; j < k; j := j + 1) - { - arr3 := split_and_decode (trim (arr2[j]), 0, '\0\0='); - if (length (arr3) = 2) - { - if (trim (arr3[0]) = 'q') - { - q := atof (arr3[1]); - goto _break; - } - else if (trim (arr3[0]) = 'level') - { - q := atof (arr3[1]); - } - } - } - _break:; + item := mime := trim(mime); + vec := split_and_decode (mime, 0, '\0\0;'); + -- known mime types default's to 1, unknown are minimal + if (not isnull(http_sys_find_best_sparql_accept(item, 0)) or not isnull(http_sys_find_best_sparql_accept(item, 1))) + q := 1.0; + else + q := 0.01; + if (length (vec) > 1) + { + item := trim (aref(vec,0)); + qstr := regexp_match('q=[0-9\\.]+', mime); + if (qstr is not null) + q := q * atof (subseq (qstr, 2)); + } if (q_best < q) - { - q_best := q; - format := item; - } + { + q_best := q; + format := item; + } + if (q = q_best and mask is not null and item like mask) + format := item; } - if (q = q_best and mask is not null and item like mask) - format := item; - } return format; } ;