Calling `and` on a list of arguments - racket

Is there a way to call and or or to a list of arguments? Like
(and (list #t #t #f))
?
I tried writing (apply and (list #t #t #f)) but that didn't work.

Try ormap and andmap
(ormap values (list #t #t #f))
(andmap values (list #t #t #f))
where values is essentially an identity function in this context.
The reason (apply and (list #t #t #f)) doesn't work is that and is not a function. It's a macro, which is necessary because (and #f (error 'foo)) should short-circuit (evaluate to #f). If it were a function, it would cause the error.

You could use any? and all? from the relation library (disclosure: I'm the author):
(require relation)
(any? (list #t #t #f)) ;=> #t
(all? (list #t #t #f)) ;=> #f

To build on a previous answer. A poor man's way of doing it would be.
> (ormap (lambda (x) (not (false? x))) (list #t #t #f))
## #t
> (andmap (lambda (x) (not (false? x))) (list #t #t #f))
## #f

Related

Replace spaces in bracketed text only in Postgresql by regexp_replace function

I need to replace all spaces in bracketed text only
"Describe what you (tried and) what (you expected) to happen"
with commas like this:
"Describe what you (tried,and) what (you,expected) to happen"
Please advise how to do it correctly using function regexp_replace.
Thanks in advance.
Not so easy to do with a simple regexp_replace function ...
If you have a maximum of two words in brakets then you can do :
SELECT string_agg (r.res, ' ')
FROM ( SELECT CASE
WHEN elt ~ '^\(' THEN elt || ',' || lead(elt) OVER ()
WHEN elt ~ '\)$' THEN ''
ELSE elt
END AS res
FROM regexp_split_to_table('Describe what you (tried and) what (you expected) to happen', ' ') as elt
) AS r
WHERE r.res <> ''
If you have two or more words inside the brakets then you have to create your own aggregate function :
CREATE OR REPLACE FUNCTION replace(x text, y text, old text, new text) RETURNS text LANGUAGE sql AS $$
SELECT replace(COALESCE(x,y), old, new) ; $$ ;
CREATE OR REPLACE AGGREGATE replace_agg (text, text, text)
( stype = text
, sfunc = replace
)
And the query is :
SELECT replace_agg('Describe what you (tried and) what (you expected) to happen', elt[1], replace(elt[1], ' ', ','))
FROM regexp_matches('Describe what you (tried and) what (you expected) to happen', '\([^\)]*\)', 'g') AS elt
see the test in dbfiddle

"bigint out of range" when computing factorial function in PostgresSQL

As part of an intro to databases class, we've been told to create a function using PL/pgSQL that gives out a factorial of a number. Now since x! increases rapidly as a function, we've decided to return a bigint due to it being a large range integer.
CREATE OR REPLACE FUNCTION getBigFactorial(fn bigint) RETURNS bigint as $$
DECLARE
product bigint;
minus1 int;
BEGIN
if (fn > 21) then
RAISE EXCEPTION 'Error: computing factorial; numeric value out of range';
return NULL;
elsif (fn < 1) then
RAISE EXCEPTION 'Error: Argument less than 1!';
return NULL;
end if;
minus1 := fn - 1;
if (minus1 > 0) then
product := fn * getBigFactorial(minus1);
return product;
end if;
return fn;
END;
$$ language plpgsql;
For this function, we've been told to create some sort of validation for the number entered.
The one for (fn < 1) worked flawlessly, however, the one which is (fn > 21) is giving some problems.
When the following is entered:
SELECT getBigFactorial(21);
We get:
ERROR: bigint out of range
CONTEXT: PL/pgSQL function getbigfactorial(integer) line 17 at assignment
SQL state: 22003
rather than getting the desired output. Line 17 corresponds to this line:
if (minus1 > 0) then
When we entered 22 instead of 21, we had the desired error output.
Any help in finding out what causes this?
TIA
Your conditional check should be inclusive of 21:
if (fn >= 21) then
-- ...
since for an input of 21, the factorial of 21 (fn * getBigFactorial(minus1), where fn = 21, and minus1 = fn - 1), which is an integer out of range for a bigint, is assigned to product, a bigint.

replace all alphanumeric characters tsql

I need to replace all alphanumeric characters with in the input with 'x'.
'12 34 - a'
becomes 'xx xx - x'. I tried to use
patindex
with [^a-zA-Z0-9], but after the first replacement still the same alphanumeric is found. looks that patindex works only when removing chars
can someone advice a solution for the issue
try this:
DECLARE #t VARCHAR(max) = '12 34 - a'
DECLARE #Keep VARCHAR(50)
SET #Keep = '%[a-vyz0-9]%'
WHILE PATINDEX(#Keep, #t) >0
Set #t = Stuff(#t, PatIndex(#Keep, #t), 1, 'x')
SELECT #t

How to specify column types for CTE (Common Table Expressions) in PostgreSQL?

Consider
WITH t (f0, f1) as (
values
(1, 10),
(2, 20)
)...
How do I specify that f0 and f1 are of type bigint?
I think you'd have to specify the types inside the VALUES expression in your case:
WITH t (f0, f1) as (
values
(1::bigint, 10::bigint),
(2, 20)
)...
You only need the types on the first set of values, PostgreSQL can infer the rest.
For example, suppose we have two functions:
create function f(bigint, bigint) returns bigint as $$
begin
raise notice 'bigint';
return $1 * $2;
end;
$$ language plpgsql;
create function f(int, int) returns int as $$
begin
raise notice 'int';
return $1 * $2;
end;
$$ language plpgsql;
Then
WITH t (f0, f1) as (
values
(1, 10),
(2, 20)
)
select f(f0, f1) from t;
will give you two int notices whereas
WITH t (f0, f1) as (
values
(1::bigint, 10::bigint),
(2, 20)
)
select f(f0, f1) from t;
would give you two bigint notices.
I don't know if this will work for you, but casting the column you want to specify worked for me in DB2
WITH CTE AS (
SELECT
'Apple' AS STRING1
,CAST('Orange' AS VARCHAR(10000)) AS STRING2
FROM SYSIBM . SYSDUMMY1)
SELECT * FROM CTE

"EXEC(columnname)" for each row in a SELECT, and get return value

What would be the best solution, if i have a table like this:
Value Formular
12 'SELECT Value+5 AS result'
15 'SELECT 4/Value+3 AS result'
16 'SELECT 5 AS result'
So, there are SQL-Statemants (as nvarchar(max)) in the Formular-Column. Now i need to calc for each row the result.
Current approach is a WHILE with cursor and handle each row for itself.
We need to use a temp-table for each row, because we were unable to find a better solution, how to get the result from the exec. Like:
declare #Value decimal(18,4);
create table #t(val decimal(18,4))
insert into #t exec(#formular)
select val from #t
We have >100'000 such rows, and this takes about ~2h do compute. (The formulas and values of course complexer, than in the example given)
Is there any possibility to get something like
SELECT Value, exec(Formular) as result FROM calctable
Thanks
EDIT:
Okay, sofar I found atleast a workaround for the EXEC() and temptable:
declare #formular as nvarchar(max)
declare #r_value decimal(18,4);
set #formular='....'
set #formular='select #r_value = Value FROM (' + #formular + ')dt'
EXEC sp_executesql #formular, N'#r_value DECIMAL(18,4) OUTPUT', #r_value OUTPUT
UPDATE Result_Values SET [Value]=#r_value WHERE ID=#calc_id;
This example can be executed:
Creating a table like your calctable, you can omit this part.
create table calctable(value int)
insert calctable values(1)
insert calctable values(3)
Populating a temp table, you can replace this with your own table.
declare #t table(value int, Formular varchar(50))
insert #t values(12,'Value+5 AS result' )
insert #t values(15,'4/Value+3 AS result')
insert #t values(16,'5 AS result')
This is the syntax you need:
declare #sql varchar(max)
select #sql = coalesce(#sql +' union all ', '') + 'select ' + cast(value as varchar(16)) +' value,'+formular+' from calctable' from #t
exec (#sql)
Result:
value result
12 6
12 8
15 7
15 4
16 5
16 5