Oracle Text query rewrite template not working - oracle

Why are the two last rewrite rules in the example from Oracle documentation not working?
Source http://docs.oracle.com/cd/B28359_01/text.111/b28303/query.htm#i1007557
Query applications sometimes parse end user queries, interpreting a
query string in one or more ways using different operator
combinations. For example, if a user enters a query of kukui nut, your
application might enter the queries {kukui nut} and {kukui or nut} to
increase recall.
The query rewrite feature enables you to submit a single query that
expands the original query into the rewritten versions. The results
are returned with no duplication.
You specify your rewrite sequences with the query template feature.
The rewritten versions of the query are executed efficiently with a
single call to CONTAINS or CATSEARCH.
The following template defines a query rewrite sequence. The query of
{kukui nut} is rewritten as follows:
{kukui} {nut}
{kukui} ; {nut}
{kukui} AND {nut}
{kukui} ACCUM {nut}
The query rewrite template for these transformations is as follows:
select id from docs where CONTAINS (text,
'<query>
<textquery lang="ENGLISH" grammar="CONTEXT"> kukui nut
<progression>
<seq><rewrite>transform((TOKENS, "{", "}", " "))</rewrite></seq>
<seq><rewrite>transform((TOKENS, "{", "}", " ; "))</rewrite></seq>
<seq><rewrite>transform((TOKENS, "{", "}", "AND"))</rewrite></seq>
<seq><rewrite>transform((TOKENS, "{", "}", "ACCUM"))</rewrite></seq>
</progression>
</textquery>
<score datatype="INTEGER" algorithm="COUNT"/>
</query>')>0;

There's an error in the example provided by Oracle. It is essential that the query operators are separated with spaces:
<seq><rewrite>transform((TOKENS, "{", "}", " AND "))</rewrite></seq>
<seq><rewrite>transform((TOKENS, "{", "}", " ACCUM "))</rewrite></seq>
so " AND " and " ACCUM " instead of "AND" and "ACCUM" as in the documentation.

Related

Does flowgrounds JSONata expressions support regex?

I'm trying to build a fairly complex expression with a CBR where I try to identify if a string contains another string. In order to do so I need to manipulate the second string and use a little bit of regex magic but it doesn't seem to work. Could anyone confirm if the JSONata implementation of flowground support regex inside a "contains" operation? The expression I am using right now is the following:
$not($contains(elements[0].attribs.content,"/" & $replace(elasticio."step_1".body.issue.fields."customfield_22519"[0],"-"," ") &"/i"))
RegEx and $contains are working correctly in combination.
The reason for your not working expression is that the second parameter of $contains is a string (something like "/xyz/i"). This string is not being interpreted as a regex.
your expression: $contains( "abc", "/" & "X" & "/i")
to change in: $contains( "abc", $eval("/" & "B" & "/i") )

Why is my simple SQL grammar failing to parse in Brag?

I am trying to create a parser for a simple subset of SQL using a grammar written with BNF in Brag. My Brag code looks like this:
#lang brag
statement : "select" fields "from" source joins* filters*
fields : field ("," field)*
field : WORD
source : WORD
joins : join*
join : "join" source "on" "(" condition ")"
filters : "where" condition ("and" | "or" condition)*
condition : field "=" field
But when I attempt to use that grammar to parse a basic SQL statement, I run into the following error:
> (parse-to-datum "select * from table")
Encountered unexpected token of type "s" (value "s") while parsing 'unknown [line=#f, column=#f, offset=#f]
I'm a total beginner to grammars and brag. Any ideas what I'm doing incorrectly?
You need to lex/tokenize the string first. The input to parse/parse-to-datum should be a list of tokens. Also, brag is case sensitive, meaning that the input should be select rather than SELECT. After you do that, it should work:
> (parse-to-datum (list "select"
(token 'WORD "foo")
"from "
(token 'WORD "bar")
" "
" "))
'(statement "select" (fields (field "foo")) "from " (source "bar") " " " ")
For the case sensitivity issue, this is fact not a problem, as you can perform normalization during the tokenization phase.
Your grammar looks weird, however. You probably should not deal with whitespaces. Instead, the whitespace should similarly be dealt with in the tokenization phase.
See https://beautifulracket.com/bf/the-tokenizer-and-reader.html for more information about tokenization.
An alternative possibility is to use other parsers. https://docs.racket-lang.org/megaparsack/index.html, for instance, can parse a string to a datum (or syntax datum) right away, though it uses some advanced concept in functional programming, so in a way it might be more difficult to use.

Why is layout around optional parts of a production causing ambiguity?

In Rascal, why is it that when there is layout at the position of an optional part of a production, this causes ambiguity? E.g. "{ }" is ambiguous as Start1, while it parses fine as Start2 from the following grammar, which I would have expected to be exactly identical.
layout Layout = " "?;
start syntax Start1 = "{" "c"? "}";
start syntax Start2 = "{" "c" "}"
| "{" "}";
In addition, I would like to know if there is another way to represent Start2 without duplication than Start1, that does not cause the same ambiguity.
Obviously there is no large amount of duplication in this code and Start2 is a good option here, but this is just an example. I am working with a grammar with many productions that contain three or four optional parts and in the last case the notation displayed in Start2 already requires duplicating the not-optional parts of the production 2^4=16 times, which really is troublesome in my opinion.
Your grammar is first extended before a parser is generated to something similar to this:
layout Layout = " "?;
syntax " "? = | " ";
syntax Start1 = "{" Layout "c"? Layout "}";
syntax "c"? = | "c";
lexical " " = [\ ];
lexical "c" = [c];
lexical "{" = [{];
lexical "}" = [}];
syntax Start2 = "{" Layout "c" Layout "}"
| "{" Layout "}";
syntax start[Start1] = Layout Start1 Layout;
syntax start[Start2] = Layout Start2 Layout;
So for an input like { } (space between the curlies), the space can be derived by the first instance of Layout in the right-hand side of the Start1 rule, or by the second instance of Layout. Since the parser produces all derivation trees, both in this case, the parse is ambiguous so to say.
Typically the ambiguity is solved by introducing greediness using a follow restriction like so:
layout Layout = " "? !>> " "
or (equivalently) like so:
layout Layout = " "? !>> [\ ]
The restriction acts as a constraint on the Layout rule: it will not derive anything (not even the empty string) if there is a space following it. This makes only the first derivation valid then, where the space goes inside the first Layout instance of Start1. After this there is } which satisfies the constraint and the parse is unambiguous.

Select Case search options

I have an ASP query form that among other things includes a text box which allows the user to enter some text which can be searched for in a database. Unfortunately, the search only returns a result when there is a match for the exact string that was entered. Is there a way to change this so as to return a result for partial matches as well, or if what's in the DB includes all or part of the search string?
The code is below and the Case in question is the one titled "Nam". Note that I have sort of gotten around this issue by adding an asterix wild card feature, but I'd really just prefer to avoid using the asterixes altogether. I chose to leave the extra code for the wildcards out so as not to complicate things.
Select Case strOption
Case "Nam"
strSelect = strSelect & " Nam='" & UCase(strNam) & "'"
Case "Location"
strSelect = strSelect & " Location='" & UCase(strLocation) & "'"
Case "Typ"
strSelect = strSelect & " Typ='" & UCase(strTyp) & "'"
Case "Season"
strSelect = strSelect & " Season='" & UCase(strSeason) & "'"
Case "Duration"
strSelect = strSelect & " Duration='" & UCase(strDuration) & "'"
Case "Yr"
strSelect = strSelect & " Yr='" & UCase(strYr) & "'"
End Select
It's more about SQL than VBScript. According the Operators docs, any of comparison and logical operators return a Boolean data type with a value of TRUE, FALSE, or UNKNOWN. More important could be reading about building a search condition (a combination of one or more predicates) using operators in question; in brief:
= (equal to) is the operator used to test the equality between two expressions;
LIKE indicates that the subsequent character string is to be used with pattern matching and returns TRUE if the operand matches a pattern (more on valid syntax, escaping etc.); a pattern can include the following valid wildcard characters:
% Any string of zero or more characters;
_ (underscore) Any single character;
[] Any single character within the specified range ([a-f]) or set ([abcdef]);
[^] Any single character not within the specified range ([^a-f]) or set ([^abcdef]).
Thus, you could formulate a predicate on Nam in your search condition (in terms of VBScript) as follows:
strSelect = strSelect & " Nam LIKE '%" & UCase(strNam) & "%'"

Multi-value optional filters with the usage of wildcard in SSRS 2005

I have asked this question before but there are no solution to it. I have created a multivalue filter with the following data-set.
SELECT PASS_M, ENTRY_DT, EXIT_DT, WORKED_HRS, ACCESS_LOCATION_X, IC_N, COMPANY_M, CONSECUTIVE_D
FROM TEMP_TARGET
WHERE (CONSECUTIVE_D >= #consecDays) AND (ENTRY_DT BETWEEN #startDate AND #endDate) AND
(ACCESS_LOCATION_X LIKE #accessVar) AND
(IC_N LIKE #icVAr)
It would be relatively easy if the value of my accessVar does not use wildcard but i needed that. So there will be 5 values possible in accessVar:
%(means all), 'At%', 'Bet%', 'Co%' and 'Dea%'
I am unable to use In operator with wildcard. Secondly, can i make this kind of dropdown filters optional? if nth is selected, just query all.
What other options do i have?
You want to use LIKE and multi-value parameters together, which isn't going to work. However, Reporting Services gives us the ability to do almost anything we want. The solution is to use custom code and expressions. First, we change your SQL statement into an expression, like so:
="SELECT PASS_M, ENTRY_DT, EXIT_DT, WORKED_HRS, ACCESS_LOCATION_X, IC_N, "
&"COMPANY_M, CONSECUTIVE_D "
&"FROM TEMP_TARGET "
&"WHERE (CONSECUTIVE_D >= #consecDays) "
&"AND (ENTRY_DT BETWEEN #startDate AND #endDate) "
&"AND ((#accessvar IS NULL) OR (ACCESS_LOCATION_X LIKE #accessVar)) "
&"AND ((#icVar IS NULL) OR (IC_N LIKE #icVAr)) "
So now the SQL statement is actually a string expression that will evaluate to a SQL expression which will execute.
Next we need to convert your multi-value parameter into a series of LIKE statements, which we can do with custom code. Add the following custom code to your report (right-click report, select Properties and click the Code tab):
Function AccessLocations (ByVal parameter As Parameter) AS String
Dim Result As String
If parameter.IsMultiValue then
Result = "AND ( "
For i as integer = 0 to parameter.Count-1
Result = Result + "(ACCESS_LOCATION LIKE '" + CStr(parameter.Value(i)) + "') OR "
Next
Result = Left(Result, Result.Length - 3) +") "
Else
Result = "AND (ACCESS_LOCATION LIKE '" + CStr(parameter.Value) + "') "
End If
Return Result
End Function
Then we call this function as part of the SQL statement:
Code.AccessLocations(Parameters!accessvar)
So your full SQL is:
="SELECT PASS_M, ENTRY_DT, EXIT_DT, WORKED_HRS, ACCESS_LOCATION_X, IC_N, "
&"COMPANY_M, CONSECUTIVE_D "
&"FROM TEMP_TARGET "
&"WHERE (CONSECUTIVE_D >= #consecDays) "
&"AND (ENTRY_DT BETWEEN #startDate AND #endDate) "
& Code.AccessLocations(Parameters!accessvar)
&"AND ((#icVar IS NULL) OR (IC_N LIKE #icVAr)) "
If your parameter has the % wildcard in it then this will work; otherwise add the wildcard to the function.

Resources