Numbers in XText not accepted - grammar

I have the following rule:
terminal MIDI_VALUE:
( '0'..'9') |
( '1'..'9' '0'..'9') |
('1' '0'..'1' '0'..'9') |
('1' '2' '0'..'7');
This rule is meant to read values from [0..127].
However, it does not accept values from [1..16], while 0 and 17 to 127 is accepted.
When I hover over the error I get:
mismatched input: '16' expecting RULE_MIDI_VALUE.
How can I fix this?
2nd Example
This example is maybe even more trivial:
DmxDelayTimeSubCommand:
'DelayTime' time=Time;
Time:
time=INT type=('ms' | 's' );
While the input
AllFrontBlue AllGroupsAll Mode loop DelayTime 255 ms;
Shows an error over 255 showing when hovering over it:
Mismatched input '255' expecting RULE_INT
While RULE_INT is a predefined terminal:
terminal INT returns ecore::EInt: ('0'..'9')+;
I get this error for all values below 256 (all values from [0..255]).

the rules MIDI_VALUE and INT
overlap with each other.
possible solutions
use INT + validator (for all of them)
use a datatyperule like MIDI_CHANNEL: INT (no terminal keyword) + a valueconverter
use terminal rules that dont overlap and datatype rules MIDI_CHANNEL: TERMINAL1|TERMINAL2| ....

Related

sap hana placeholders pass * parameter with arrow notation

Trying to pass a star (*) in a sql Hana place holder with an arrow notation
The following works OK:
Select * FROM "table_1"
( PLACEHOLDER."$$IP_ShipmentStartDate$$" => '2020-01-01',
PLACEHOLDER."$$IP_ShipmentEndDate$$" => '2030-01-01' )
In the following, when trying to pass a *, i get a syntax error:
Select * FROM "table1"
( PLACEHOLDER."$$IP_ShipmentStartDate$$" => '2020-01-01',
PLACEHOLDER.'$$IP_ItemTypecd$$' => '''*''',
PLACEHOLDER."$$IP_ShipmentEndDate$$" => '2030-01-01' )
The reason i am using the arrow notation, is since its the only way i know that allows passing parameters as in the example bellow: (as in linked post)
do begin
declare lv_param nvarchar(100);
select max('some_date')
into lv_param
from dummy /*your_table*/;
select * from "_SYS_BIC"."path.to.your.view/CV_TEST" (
PLACEHOLDER."$$P_DUMMY$$" => :lv_param
);
end;
There's a typo in your code. You need to use double quotes around parameter name, but you have a single quote. It should be: PLACEHOLDER."$$IP_ItemTypecd$$".
When you pass something to Calculation View's parameter, you already have a string, that will be treated as string and have quotes around it where they needed, so no need to add more. But if you really need to pass some quotes inside the placeholder's value you also need to escape them with backslash complementary to doubling them (it was found by doing data preview on calculation view and entering '*' as a value of input parameter, then you'll find valid SQL statement in the log of preview):
do
begin
select *
from "_SYS_BIC"."ztest/CV_TEST_PERF"(
PLACEHOLDER."$$P_DUMMY$$" => '''*'''
);
end;
/*
SAP DBTech JDBC: [339]: invalid number: : line 3 col 3 (at pos 13): invalid number:
not a valid number string '' at function __typecast__()
*/
/*And in trace there's no more information, but interesting part
is preparation step, not an execution
w SQLScriptExecuto se_eapi_proxy.cc(00145) : Error <exception 71000339:
not a valid number string '' at function __typecast__()
> in preparation of internal statement:
*/
do
begin
select *
from "_SYS_BIC"."ztest/CV_TEST_PERF"(
PLACEHOLDER."$$P_DUMMY$$" => '\'*\''
);
end;
/*
SAP DBTech JDBC: [257]: sql syntax error: incorrect syntax near "\": line 5 col 38 (at pos 121)
*/
But this is ok:
do
begin
select *
from "_SYS_BIC"."ztest/CV_TEST_PERF"(
PLACEHOLDER."$$P_DUMMY$$" => '\''*\'''
);
end;
LOG_ID | DATUM | INPUT_PARAM | CUR_DATE
--------------------------+----------+-------------+---------
8IPYSJ23JLVZATTQYYBUYMZ9V | 20201224 | '*' | 20201224
3APKAAC9OGGM2T78TO3WUUBYR | 20201224 | '*' | 20201224
F0QVK7BVUU5IQJRI2Q9QLY0WJ | 20201224 | '*' | 20201224
CW8ISV4YIAS8CEIY8SNMYMSYB | 20201224 | '*' | 20201224
What about the star itself:
As #LarsBr already said, in SQL you need to use LIKE '%pattern%' to search for strings contains parretn in the middle, % is equivalent for ABAP's * (but as far as I know * is more verbose placeholder in non-SQL world). So there's no out-of-the-box conversion of FIELD = '*' to FIELD like '%' or something similar.
But there's no LIKE predicate in Column Engine (in filter or in calculated column).
If you really need LIKE functionality in filter or calculated column, you can:
Switch execution engine to SQL
Or use match(arg, pattern) function of Column Engine, which now dissapeared from the pallete and is hidden quite well in the documentation (here, at the very end of the page, after digging into the description field of the last row in the table, you'll find the actual syntax for it. Damn!).
But here you'll meet another surprise: as long as Column Engine has different operators than SQL (it is more internal and more close to the DB core), it uses star (*) for wildcard character. So for match(string, pattern) you need to use a star again: match('pat string tern', 'pat*tern').
After all the above said: there are cases where you can really want to search for data with wildcards and pass them as parameter. But then you need to use match and pass the parameter as plain text without tricks on star (*) or something (if you want to use officially supported features, not trying to exploit some internals).
After adding this filter to RSPCLOGCHAIN projection node of my CV from the previous thread, it works this way:
do
begin
select *
from "_SYS_BIC"."ztest/CV_TEST_PERF"(
PLACEHOLDER."$$P_DUMMY$$" => 'CW*'
);
end;
LOG_ID | DATUM | INPUT_PARAM | CUR_DATE
--------------------------+----------+-------------+---------
CW8ISV4YIAS8CEIY8SNMYMSYB | 20201224 | CW* | 20201224
do
begin
select *
from "_SYS_BIC"."ztest/CV_TEST_PERF"(
PLACEHOLDER."$$P_DUMMY$$" => 'CW'
);
end;
/*
Fetched 0 row(s) in 0 ms 0 µs (server processing time: 0 ms 0 µs)
*/
The notation with triple quotation marks '''*''' is likely what yields the syntax error here.
Instead, use single quotation marks to provide the '*' string.
But that is just half of the challenge here.
In SQL, the placeholder search is done via LIKE and the placeholder character is %, not *.
To mimic the ABAP behaviour when using calculation views, the input parameters must be used in filter expressions in the calculation view. And these filter expressions have to check for whether the input parameter value is * or not. If it is * then the filter condition needs to be a LIKE, otherwise an = (equal) condition.
A final comment: the PLACEHOLDER-syntax really only works with calculation views and not with tables.

Xargs, sqlplus and quote nightmare?

I have one big file containing data, for example :
123;test/x/COD_ACT_008510/descr="R08-Ballon d''eau"
456;test/x/COD_ACT_008510/descr="R08-Ballon d''eau"
In reality, there is much more column but I simplified here.
I want to treat each line, and do some sqlplus treatment with them.
Let say that I have one table, with two column, with this :
ID | CONTENT
123 | test/x/COD_ACT_333/descr="Test 1"
456 | test/x/COD_ACT_444/descr="Test 2"
Let say I want to update the two lines content value to have that :
ID | CONTENT
123 | test/x/COD_ACT_008510/descr="R08-Ballon d''eau"
456 | test/x/COD_ACT_008510/descr="R08-Ballon d''eau"
I have a lot of data and complex request to execute in reality, so I have to use sqlplus, not tools like sqlloader.
So, I treat the input file on 5 multi thread, one line at each time, and define "\n" like separator to evict quote conflict :
cat input_file.txt | xargs -n 1 -P 5 -d '\n' ./my_script.sh &
In "my_script.sh" I have :
#!/bin/bash
line="$1"
sim_id=$(echo "$line" | cut -d';' -f1)
content=$(echo "$line" | cut -d';' -f2)
sqlplus -s $DBUSER/$DBPASSWORD#$DBHOST:$DBPORT/$DBSCHEMA #updateRequest.sql "$id" "'"$content"'"
And in the updateRequest.sql file (just containing a test) :
set heading off
set feed off
set pages 0
set verify off
update T_TABLE SET CONTENT = '&2' where ID = '&1';
commit;
And in result, I have :
01740: missing double quote in identifier
If I put “verify” parameter to on in the sql script, I can see :
old 1: select '&2' from dual
new 1: select 'test/BVAL/COD_ACT_008510/descr="R08-Ballon d'eau"' from dual
It seems like one of the two single quotes (used for escape the second quote) is missing...
I tried everything, but each time I have an error with quote or double quote, either of bash side, or sql side... it's endless :/
I need the double quote for the "descr" part, and I need to process the apostrophe (quote) in content.
For info, the input file is generated automatically, but I can modify his format.
With GNU Parallel it looks like this:
dburl=oracle://$DBUSER:$DBPASSWORD#$DBHOST:$DBPORT/$DBSCHEMA
cat big |
parallel -j5 -v --colsep ';' -q sql $dburl "update T_TABLE SET CONTENT = '{=2 s/'/''/g=}' where ID = '{1}'; commit;"
But only if you do not have ; in the values. So given this input it will do the wrong thing:
456;test/x/COD_ACT_008510/descr="semicolon;in;value"

Create table name in Hive using variable subsitution

I'd like to create a table name in Hive using variable substitution.
E.g.
SET market = "AUS";
create table ${hiveconf:market_cd}_active as ... ;
But it fails. Any idea how it can be achieved?
You should use backtrics (``) for name for that, like:
SET market=AUS;
CREATE TABLE `${hiveconf:market}_active` AS SELECT 1;
DESCRIBE `${hiveconf:market}_active`;
Example run script.sql from beeline:
$ beeline -u jdbc:hive2://localhost:10000/ -n hadoop -f script.sql
Connecting to jdbc:hive2://localhost:10000/
...
0: jdbc:hive2://localhost:10000/> SET market=AUS;
No rows affected (0.057 seconds)
0: jdbc:hive2://localhost:10000/> CREATE TABLE `${hiveconf:market}_active` AS SELECT 1;
...
INFO : Dag name: CREATE TABLE `AUS_active` AS SELECT 1(Stage-1)
...
INFO : OK
No rows affected (12.402 seconds)
0: jdbc:hive2://localhost:10000/> DESCRIBE `${hiveconf:market}_active`;
...
INFO : Executing command(queryId=hive_20190801194250_1a57e6ec-25e7-474d-b31d-24026f171089): DESCRIBE `AUS_active`
...
INFO : OK
+-----------+------------+----------+
| col_name | data_type | comment |
+-----------+------------+----------+
| _c0 | int | |
+-----------+------------+----------+
1 row selected (0.132 seconds)
0: jdbc:hive2://localhost:10000/> Closing: 0: jdbc:hive2://localhost:10000/
Markovitz's criticisms are correct, but do not produce a correct solution. In summary, you can use variable substitution for things like string comparisons, but NOT for things like naming variables and tables. If you know much about language compilers and parsers, you get a sense of why this would be true. You could construct such behavior in a language like Java, but SQL is just too crude.
Running that code produces an error, "cannot recognize input near '$' '{' 'hiveconf' in table name".(I am running Hortonworks, Hive 1.2.1000.2.5.3.0-37).
I spent a couple hours Googling and experimenting with different combinations of punctuation, different tools ranging from command line, Ambari, and DB Visualizer, etc., and I never found any way to construct a table name or a field name with a variable value. I think you're stuck with using variables in places where you need a string literal, like comparisons, but you cannot use them in place of reserved words or existing data structures, if that makes sense. By example:
--works
drop table if exists user_rgksp0.foo;
-- Does NOT work:
set MY_FILE_NAME=user_rgksp0.foo;
--drop table if exists ${hiveconf:MY_FILE_NAME};
-- Works
set REPORT_YEAR=2018;
select count(1) as stationary_event_count, day, zip_code, route_id from aaetl_dms_pub.dms_stationary_events_pub
where part_year = '${hiveconf:REPORT_YEAR}'
-- Does NOT Work:
set MY_VAR_NAME='zip_code'
select count(1) as stationary_event_count, day, '${hiveconf:MY_VAR_NAME}', route_id from aaetl_dms_pub.dms_stationary_events_pub
where part_year = 2018
The qualifies should be removed
You're using the wrong variable name
SET market=AUS; create table ${hiveconf:market}_active as select 1;

matching subsequent space separated numbers as different tokens

In a flat file,for which i'm trying to write a parser, there is a line like this:
//TN PN RO
0 5 3
TN,PN and RO are the parameter names (i have added here the line starting with "//" for better understanding. The actual file does not have it).
The ranges for each of these parameters are different.
TN can be 0 or 1, PN 0-7 and RO 0-3.
I understand why the following grammar does not work (0 and 1 matched by all lexer rules, 2 and 3 are matched by the PN and RO rules) but is there a way to achieve what i'm trying to do here.
grammar PARAM;
parameters: TN PN RO;
TN: [0-1];
RN: [0-7];
RO: [0-3];
WS : [ \r\t\n]+ -> skip ;
I like to match these overlapping numbers as different tokens. Otherwise i have to change my grammar to this and then in the the Java side check the ranges manually.
grammar PARAM;
parameters: DIGIT DIGIT DIGIT;
DIGIT: [0-7];
WS : [ \r\t\n]+ -> skip ;
Thanks.
Since the lexer does not know the context / number position on line (unless hacked by some custom code), it does not know whether to match 0 as TN, RN or RO. The right place to make this distinction is the parser.
You could do this to avoid checking the ranges in Java (although I would personally check them in Java rather than do this):
parameters: tn_param rn_param ro_param;
tn_param: TN_DIGIT;
rn_param: TN_DIGIT | RO_DIGIT | RN_DIGIT;
ro_param: TN_DIGIT | RO_DIGIT;
TN_DIGIT: [0-1];
RO_DIGIT: [2-3];
RN_DIGIT: [4-7];

Prolog, working with capital letter

I am working on database project in SWI-Prolog. Problem is that i want to work with names of Sportsmen which i read from input. I need to save their names with capital letters, but prolog interprets these as variables. Any ideas how to fix this?
I would use code_type/2 to ensure that any entered name starts with a capital letter.
Since you want to allow a user to enter a name with a letter that is either lower- or uppercase, I do the case conversion on the codes list that I read with read_line_to_codes/2.
Since you want to store the names in a database, I use dynamic/1 to declare that I will be adding some sportsname/1 entries, and I use assert/1 to add a specific name to the database.
Here is the code:
:- dynamic(sportsname/1).
:- initialization(input).
input:-
repeat,
format(user_output, 'Please enter a name (or type `quit`):\n', []),
read_line_to_codes(user_input, Codes1),
(
atom_codes(quit, Codes1)
->
!, true
;
capitalize(Codes1, Codes2)
->
atom_codes(Name, Codes2),
assert(sportsname(Name)),
format(current_output, 'Sportsname ~a writen to database.\n', [Name]),
fail
;
fail
).
capitalize([], []).
capitalize([H1|T], [H2|T]):-
code_type(H2, to_upper(H1)).
Example of use:
$ swipl sport_names.pl
Please enter a name (or type `quit`):
|: john
Sportsname John writen to database.
Please enter a name (or type `quit`):
|: James
Sportsname James writen to database.
Please enter a name (or type `quit`):
|: suzan
Sportsname Suzan writen to database.
Please enter a name (or type `quit`):
|: quit
?- sportsname(X).
X = 'John' ;
X = 'James' ;
X = 'Suzan'.
Hope this helps!
Use either quoted atoms...
?- atom('X').
true.
?- 'X' = 'Y'.
false.
... or strings:
?- X = "Foo!".
X = [70, 111, 111, 33].
(strings are represented as lists of codepoints, in this case ASCII ones). Quoted atoms are much easier to work with.
I don't know how implementation independent this code is, but this works for me in SWI-Prolog:
read_string(String) :-
current_input(Input),
read_line_to_codes(Input, Codes),
string_codes(String, Codes).
Sample input and output:
?- read_string(X).
|: Test!
X = "Test!".
Just quote any string that need to be read by Prolog, regardless to the case you find in the database... Beware to escaping: for instance
?- write('O\'Neal').
O'Neal
?- read(X).
|: 'O\'Neal'.
X = 'O\'Neal'.