count(*) type compatibility error with Database.PostgreSQL.Simple? - postgresql

The error is
*** Exception: Incompatible {errSQLType = "int8", errHaskellType = "Int", errMessage = "types incompatible"}
It looks like any value returned by count(*) in the query must be converted into Integer rather than Int. If I change those specific variables to type Integer, the queries work.
But this error wasn't being raised on another machine with the same exact code. The first machine was 32 bit and this other one 64-bit. That's the only difference I could discern.
Does anyone have any insight into what is going on?

The PostgreSQL count() functions returns a Bigint type, see
http://www.postgresql.org/docs/9.2/static/functions-aggregate.html
Bigint are 8 bytes
see http://www.postgresql.org/docs/9.2/static/datatype-numeric.html
Haskell int is ~ 2**29 which implies it a 4 byte integer.
http://www.haskell.org/ghc/docs/latest/html/libraries/base/Data-Int.html
Then its normal that PostgreSQL or its API will not do an implicit downwards conversion in precision.
So use a Haskell int64 type or cast count(*) to integer.

As documented in the FromField module, postgresql-simple will only do client-side conversions between numerical types when there isn't any possibility of overflow or loss of precision. Note especially the list of types in the haddocks for the instance FromField Int: "int2, int4, and if compiled as 64-bit code, int8 as well. This library was compiled as 32-bit code." The latter part of that comment is of course specific to the build that hackage itself performs.
On 32-bit platforms, Int is a 32-bit integer, and on 64-bit platforms, Int is a 64-bit integer. If you use Int32 you'll get the same exception. You can use Int64 or the arbitrary-precision Integer type to avoid this problem on both kinds of platform.

Related

Dart equivalent of long? [duplicate]

This question already has answers here:
How do I declare 64bit unsigned int in dart/flutter?
(2 answers)
Closed 3 years ago.
What is the equivalent of java's long datatype in dart ? should int or long be used?
In Java:
long: The long data type is a 64-bit two's complement integer. The signed long has a minimum value of -2^63 and a maximum value of 2^63-1. In Java SE 8 and later, you can use the long data type to represent an unsigned 64-bit long, which has a minimum value of 0 and a maximum value of 2^64-1. Use this data type when you need a range of values wider than those provided by int. The Long class also contains methods like compareUnsigned, divideUnsigned etc to support arithmetic operations for unsigned long.
In Dart:
int
Integer values no larger than 64 bits, depending on the platform. On the Dart VM, values can be from -2^63 to 2^63 - 1. Dart that’s compiled to JavaScript uses JavaScript numbers, allowing values from -2^53 to 2^53 - 1.
So, you can exactly use int in Dart for the equivalent of long in Java. But beware of the caveat when compiled to JavaScript.

Precondition failed: Negative count not allowed

Error:
Precondition failed: Negative count not allowed: file /BuildRoot/Library/Caches/com.apple.xbs/Sources/swiftlang/swiftlang-900.0.74.1/src/swift/stdlib/public/core/StringLegacy.swift, line 49
Code:
String(repeating: "a", count: -1)
Thinking:
Well, it doesn't make sense repeating some string a negative number of times. Since we have types in Swift, why not use an UInt?
Here we have some documentation about it.
Use UInt only when you specifically need an unsigned integer type with
the same size as the platform’s native word size. If this isn’t the
case, Int is preferred, even when the values to be stored are known to
be nonnegative. A consistent use of Int for integer values aids code
interoperability, avoids the need to convert between different number
types, and matches integer type inference, as described in Type Safety
and Type Inference.
Apple Docs
Ok that Int is preferred, therefore the API is just following the rules, but why the Strings API is designed like that? Why this constructor is not private and the a public one with UInt ro something like that? Is there a "real" reason? It this some "undefined behavior" kind of thing?
Also: https://forums.developer.apple.com/thread/98594
This isn't undefined behavior — in fact, a precondition indicates the exact opposite: an explicit check was made to ensure that the given count is positive.
As to why the parameter is an Int and not a UInt — this is a consequence of two decisions made early in the design of Swift:
Unlike C and Objective-C, Swift does not allow implicit (or even explicit) casting between integer types. You cannot pass an Int to function which takes a UInt, and vice versa, nor will the following cast succeed: myInt as? UInt. Swift's preferred method of converting is using initializers: UInt(myInt)
Since Ints are more generally applicable than UInts, they would be the preferred integer type
As such, since converting between Ints and UInts can be cumbersome and verbose, the easiest way to interoperate between the largest number of APIs is to write them all in terms of the common integer currency type: Int. As the docs you quote mention, this "aids code interoperability, avoids the need to convert between different number types, and matches integer type inference"; trapping at runtime on invalid input is a tradeoff of this decision.
In fact, Int is so strongly ingrained in Swift that when Apple framework interfaces are imported into Swift from Objective-C, NSUInteger parameters and return types are converted to Int and not UInt, for significantly easier interoperability.

c cast and deference a pointer strict aliasing

In http://blog.regehr.org/archives/1307, the author claims that the following snippet has undefined behavior:
unsigned long bogus_conversion(double d) {
unsigned long *lp = (unsigned long *)&d;
return *lp;
}
The argument is based on http://port70.net/~nsz/c/c11/n1570.html#6.5p7, which specified the allowed access circumstances. However, in the footnote(88) for this bullet point, it says this list is only for checking aliasing purpose, so I think this snippet is fine, assuming sizeof(long) == sizeof(double).
My question is whether the above snippet is allowed.
The snippet is erroneous but not because of aliasing. First there is a simple rule that says to deference a pointer to object with a different type than its effective type is wrong. Here the effective type is double, so there is an error.
This safeguard is there in the standard, because the bit representation of a double must not be a valid representation for unsigned long, although this would be quite exotic nowadays.
Second, from a more practical point of view, double and unsigned long may have different alignment properties, and accessing this in that way may produce a bus error or just have a run time penalty.
Generally casting pointers like that is almost always wrong, has no defined behavior, is bad style and in addition is mostly useless, anyhow. Focusing on aliasing in the argumentation about these problems is a bad habit that probably originates in incomprehensible and scary gcc warnings.
If you really want to know the bit representation of some type, there are some exceptions of the "effective type" rule. There are two portable solutions that are well defined by the C standard:
Use unsigned char* and inspect the bytes.
Use a union that comprises both types, store the value in there and read it with the other type. By that you are telling the compiler that you want an object that can be seen as both types. But here you should not use unsigned long as a target type but uint64_t, since you have to be sure that the size is exactly what you think it is, and that there are no trap representations.
To illustrate that, here is the same function as in the question but with defined behavior.
unsigned long valid_conversion(double d) {
union {
unsigned long ul;
double d;
} ub = { .d = d, };
return ub.ul;
}
My compiler (gcc on a Debian, nothing fancy) compiles this to exactly the same assembler as the code in the question. Only that you know that this code is portable.

What to_unsigned does?

Could someone please explain me how VHDL's to_unsigned works or confirm that my understanding is correct?
For example:
C(30 DOWNTO 0) <= std_logic_vector (to_unsigned(-30, 31))
Here is my understanding:
-30 is a signed value, represented in bits as 1111111111100010
all bits should be inverted and to it '1' added to build the value of C
0000000000011101+0000000000000001 == 0000000000011111
In IEEE package numeric_std, the declaration for TO_UNSIGNED:
-- Id: D.3
function TO_UNSIGNED (ARG, SIZE: NATURAL) return UNSIGNED;
-- Result subtype: UNSIGNED(SIZE-1 downto 0)
-- Result: Converts a non-negative INTEGER to an UNSIGNED vector with
-- the specified SIZE.
You won't find a declared function to_unsigned with an argument or size that are declared as type integer. What is the consequence?
Let's put that in a Minimal, Complete, and Verifiable example:
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
entity what_to_unsigned is
end entity;
architecture does of what_to_unsigned is
signal C: std_logic_vector (31 downto 0);
begin
C(30 DOWNTO 0) <= std_logic_vector (to_unsigned(-30, 31));
end architecture;
A VHDL analyzer will give us an error:
ghdl -a what_to_unsigned.vhdl
what_to_unsigned.vhdl:12:53: static constant violates bounds
ghdl: compilation error
And tell us -30 (line 12:character 53) has a bounds violation. Meaning in this case the numerical literal converted to universal_integer doesn't convert to type natural in the function to_unsigned.
A different tool might tell us a bit more graphically:
nvc -a what_to_unsigned.vhdl
** Error: value -30 out of bounds 0 to 2147483647 for parameter ARG
File what_to_unsigned.vhdl, Line 12
C(30 DOWNTO 0) <= std_logic_vector (to_unsigned(-30, 31));
^^^
And actually tells us where in the source code the error is found.
It's safe to say what you think to_unsigned does is not what the analyzer thinks it does.
VHDL is a strongly typed language, you tried to provide a value to place where that value is out of range for the argument ARG in function TO_UNSIGNED declared in IEEE package numeric_std.
The type NATURAL is declared in package standard and is made visible by an inferred declaration library std; use std.standard.all; in the context clause. (See IEEE Std 1076-2008, 13.2 Design libraries):
Every design unit except a context declaration and package STANDARD is
assumed to contain the following implicit context items as part of its
context clause:
library STD, WORK; use STD.STANDARD.all;
The declaration of natural found in 16.3 Package STANDARD:
subtype NATURAL is INTEGER range 0 to INTEGER'HIGH;
A value declared as a NATURAL is a subtype of INTEGER that has a constrained range excluding negative numbers.
And about here you can see you have the ability to answer this question with access to a VHDL standard compliant tool and referencing the IEEE Std 1076-2008, IEEE Standard VHDL Language Reference Manual.
The TL:DR; detail
You could note that 9.4 Static expressions, 9.4.1 General gives permission to evaluate locally static expressions during analysis:
Certain expressions are said to be static. Similarly, certain discrete ranges are said to be static, and the type marks of certain subtypes are said to denote static subtypes.
There are two categories of static expression. Certain forms of expression can be evaluated during the analysis of the design unit in which they appear; such an expression is said to be locally static.
Certain forms of expression can be evaluated as soon as the design hierarchy in which they appear is elaborated; such an expression is said to be globally static.
There may be some standard compliant tools that do not evaluate locally static expressions during analysis. "can be" is permissive not mandatory. The two VHDL tools demonstrated on the above code example take advantage of that permission. In both tools the command line argument -a tells the tool to analyze the provided file which is if successful, inserted into the current working library (WORK by default, see 13.5 Order of analysis, 13.2 Design libraries).
Tools that evaluate bounds checking at elaboration for locally static expressions are typically purely interpretive and even that can be overcome with a separate analysis pass.
The VHDL language can be used for formal specification of a design model used in formal proofs within the bounds specified by Annex D Potentially nonportable constructs and when relying on pure functions only (See 4.Subprograms and packages, 4.1 General).
VHDL compliant tools are guaranteed to give the same results, although there is no standardization of error messages nor limitations placed on tool implementation methodology.
to_unsigned is for converting between different types:
signal i : integer := 2;
signal u : unsigned(3 downto 0);
...
u <= i; -- Error, incompatible types
u <= to_unsigned(i, 4); -- OK, conversion function does the right thing
If you try to convert a negative integer, this is an error.
u <= to_unsigned(-2, 4); -- Error, does not work with negative numbers
If you simply want to invert an integer, i.e. 2 becomes -2, 5 becomes -5, just use the - operator:
u <= to_unsigned(-i, 4); -- OK as long as `i` was negative or zero
If you want the absolute value, a function for this is provided by the numeric_std library.
u <= to_unsigned(abs(i), 4);

Is there a way to disable function overloading in Postgres

My users and I do not use function overloading in PL/pgSQL. We always have one function per (schema, name) tuple. As such, we'd like to drop a function by name only, change its signature without having to drop it first, etc. Consider for example, the following function:
CREATE OR REPLACE FUNCTION myfunc(day_number SMALLINT)
RETURNS TABLE(a INT)
AS
$BODY$
BEGIN
RETURN QUERY (SELECT 1 AS a);
END;
$BODY$
LANGUAGE plpgsql;
To save time, we would like to invoke it as follows, without qualifying 1 with ::SMALLINT, because there is only one function named myfunc, and it has exactly one parameter named day_number:
SELECT * FROM myfunc(day_number := 1)
There is no ambiguity, and the value 1 is consistent with SMALLINT type, yet PostgreSQL complains:
SELECT * FROM myfunc(day_number := 1);
ERROR: function myfunc(day_number := integer) does not exist
LINE 12: SELECT * FROM myfunc(day_number := 1);
^
HINT: No function matches the given name and argument types.
You might need to add explicit type casts.
When we invoke such functions from Python, we use a wrapper that looks up functions' signatures and qualifies parameters with types. This approach works, but there seems to be a potential for improvement.
Is there a way to turn off function overloading altogether?
Erwin sent a correct reply. My next reply is related to possibility to disable overloading.
It is not possible to disable overloading - this is a base feature of PostgreSQL function API system - and cannot be disabled. We know so there are some side effects like strong function signature rigidity - but it is protection against some unpleasant side effects when function is used in Views, table definitions, .. So you cannot to disable it.
You can simply check if you have or have not overloaded functions:
postgres=# select count(*), proname
from pg_proc
where pronamespace <> 11
group by proname
having count(*) > 1;
count | proname
-------+---------
(0 rows)
This is actually not directly a matter of function overloading (which would be impossible to "turn off"). It's a matter of function type resolution. (Of course, that algorithm could be more permissive without overloaded functions.)
All of these would just work:
SELECT * FROM myfunc(day_number := '1');
SELECT * FROM myfunc('1'); -- note the quotes
SELECT * FROM myfunc(1::smallint);
SELECT * FROM myfunc('1'::smallint);
Why?
The last two are rather obvious, you mentioned that in your question already.
The first two are more interesting, the explanation is buried in the Function Type Resolution:
unknown literals are assumed to be convertible to anything for this purpose.
And that should be the simple solution for you: use string literals.
An untyped literal '1' (with quotes) or "string literal" as defined in the SQL standard is different in nature from a typed literal (or constant).
A numeric constant 1 (without quotes) is cast to a numeric type immediately. The manual:
A numeric constant that contains neither a decimal point nor an
exponent is initially presumed to be type integer if its value fits in
type integer (32 bits); otherwise it is presumed to be type bigint if
its value fits in type bigint (64 bits); otherwise it is taken to be
type numeric. Constants that contain decimal points and/or exponents
are always initially presumed to be type numeric.
The initially assigned data type of a numeric constant is just a
starting point for the type resolution algorithms. In most cases the
constant will be automatically coerced to the most appropriate type
depending on context. When necessary, you can force a numeric value to
be interpreted as a specific data type by casting it.
Bold emphasis mine.
The assignment in the function call (day_number := 1) is a special case, the data type of day_number is unknown at this point. Postgres cannot derive a data type from this assignment and defaults to integer.
Consequently, Postgres looks for a function taking an integer first. Then for functions taking a type only an implicit cast away from integer, in other words:
SELECT casttarget::regtype
FROM pg_cast
WHERE castsource = 'int'::regtype
AND castcontext = 'i';
All of these would be found - and conflict if there were more than one function. That would be function overloading, and you would get a different error message. With two candidate functions like this:
SELECT * FROM myfunc(1);
ERROR: function myfunc(integer) is not unique
Note the "integer" in the message: the numeric constant has been cast to integer.
However, the cast from integer to smallint is "only" an assignment cast. And that's where the journey ends:
No function matches the given name and argument types.
SQL Fiddle.
More detailed explanation in these related answers:
PostgreSQL ERROR: function to_tsvector(character varying, unknown) does not exist
Generate series of dates - using date type as input
Dirty fix
You could fix this by "upgrading" the cast from integer to smallint to an implicit cast:
UPDATE pg_cast
SET castcontext = 'i'
WHERE castsource = 'int'::regtype
AND casttarget = 'int2'::regtype;
But I would strongly discourage tampering with the default casting system. Only consider this if you know exactly what you are doing. You'll find related discussions in the Postgres lists. It can have all kinds of side effects, starting with function type resolution, but not ending there.
Aside
Function type resolution is completely independent from the used language. An SQL function would compete with PL/perl or PL/pgSQL or "internal" functions just the same. The function signature is essential. Built-in functions only come first, because pg_catalog comes first in the default search_path.
There are plenty of in built functions that are overloaded, so it simply would not work if you turned off function overloading.