Explain the SQL expression - sql

I'm going through the spring-security samples on GitHub and found a class, which is a repository itself, where we use a #Query annotation.
Database used: HSQL
I don't clearly understand the contents of the query, particularly what does m mean and this part m.to_id = ?#{principal?.id } as well. This symbol is being underlined with red line and the following message is shown: Cannot resolve symbol 'm'
Code:
/**
* A repository that integrates with Spring Security for accessing {#link Message}s.
*/
#Repository
public interface SecurityMessageRepository extends MessageRepository {
#Query("SELECT m FROM Message WHERE m.to_id = ?#{principal?.id }")
List<Message> findAll();
}
Here's my data.sql file used to populate the initial data (taken from the example):
insert into user(id,email,password,firstName,lastName) values (0,'rob#example.com','password','Rob','Winch');
insert into user(id,email,password,firstName,lastName) values (1,'luke#example.com','password','Luke','Taylor');
insert into message(id,created,to_id,summary,text) values (100,'2023-01-05 10:00:00',0,'Hello Rob','This message is for Rob');
insert into message(id,created,to_id,summary,text) values (101,'2023-01-05 11:00:00',0,'How are you Rob?','This message is for Rob');
insert into message(id,created,to_id,summary,text) values (102,'2023-01-05 12:00:00',0,'Is this secure?','This message is for Rob');
insert into message(id,created,to_id,summary,text) values (110,'2023-01-05 10:00:00',1,'Hello Luke','This message is for Luke');
insert into message(id,created,to_id,summary,text) values (111,'2023-01-05 10:00:00',1,'Greetings Luke','This message is for Luke');
insert into message(id,created,to_id,summary,text) values (112,'2023-01-05 10:00:00',1,'Is this secure?','This message is for Luke');
Could you explain what does mean that SQL expression or provide a link to some article explaining this? (because I can't even figure out how to google it correctly to find the answer quickly).

this SQL will work, m is not a column in your table so you can't select it.
* will get all columns. And m is used as an alias for Message, so it will be resolved with the m.to_id column.
SELECT * FROM Message m WHERE m.to_id = ?#{principal?.id }

Related

How to resolve this sql error of schema_of_json

I need to find out the schema of a given JSON file, I see sql has schema_of_json function
and something like this works flawlessly
> SELECT schema_of_json('[{"col":0}]');
ARRAY<STRUCT<`col`: BIGINT>>
But if I query for my table name, it gives me the following error
>SELECT schema_of_json(Transaction) as json_data from table_name;
Error in SQL statement: AnalysisException: cannot resolve 'schemaofjson(`Transaction`)' due to data type mismatch: The input json should be a string literal and not null; however, got `Transaction`.; line 1 pos 7;
The Transaction is one of the columns in my table and after checking it manually I can attest that it is of String type(json).
The SQL statement has it to give me the schema of the JSON, how to do it?
after looking further into the documentation that it is clear that the word foldable means that of the static one, and a column from a table JSON won't work
for minimal reroducible example here you go:
SELECT schema_of_json(CAST('{ "a": "b" }' AS STRING))
As soon as the cast is introduced in the above statement, the schema_of_json will fail......... It needs a static JSON as it's input

Modify select identifiers in Sql Query using calcite

I want to modify a SQL query using Calcite. For example
SELECT values FROM data to
SELECT values as v FROM data
I could access SqlNode of select identifier using SqlVisiter implementation.
public Object visit(SqlCall sqlCall) {
SqlNodeList selectList = ((SqlSelect) sqlCall).getSelectList();
for (SqlNode sqlNode : selectList) {
System.out.println(sqlNode.toString());
}
Now what should I do to update SqlNode?
The SqlNode objects in the select list will be instances of SqlIdentifier in this case. So you'll have to cast sqlNode to a SqlIdentifier and then you can call .setName(0, "NEW_NAME"). After this, you call unparse on the original root node to get the new query back.

Inserting default values if column value is 'None' using slick

My problem is simple.
I have a column seqNum: Double which is NOT NULL DEFAULT 1 in CREATE TABLE statement as follows:
CREATE TABLE some_table
(
...
seq_num DECIMAL(18,10) NOT NULL DEFAULT 1,
...
);
User can enter a value for seqNum or not from UI. So the accepting PLAY form is like:
case class SomeCaseClass(..., seqNum: Option[Double], ...)
val secForm = Form(mapping(
...
"seqNum" -> optional(of[Double]),
...
)(SomeCaseClass.apply)(SomeCaseClass.unapply))
The slick Table Schema & Objects looks like this:
case class SomeSection (
...
seqNum: Option[Double],
...
)
class SomeSections(tag: Tag) extends Table[SomeSection](tag, "some_table") {
def * = (
...
seqNum.?,
...
) <> (SomeSection.tupled, SomeSection.unapply _)
...
def seqNum = column[Double]("seq_num", O.NotNull, O.Default(1))
...
}
object SomeSections {
val someSections = TableQuery[SomeSections]
val autoInc = someSections returning someSections.map(_.sectionId)
def insert(s: someSection)(implicit session: Session) = {
autoInc.insert(s)
}
}
When I'm sending seqNum from UI, everything is works fine but when None is there, it breaks saying that cannot insert NULL in NOT NULL column which is correct. This question explains why.
But how to solve this problem using slick? Can't understand where should I check about None? I'm creating & sending an object of SomeSection to insert method of SomeSections Object.
I'm using sql-server, if it matters.
Using the default requires not inserting the value at all rather than inserting NULL. This means you will need a custom projection to insert to.
people.map(_.name).insert("Chris") will use defaults for all other fields. The limitations of scala's native tuple transformations and case class transformations can make this a bit of a hassle. Things like Slick's HLists, Shapeless, Scala Records or Scala XR can help, but are not trivial or very experimental at the moment.
Either you enforce the Option passed to Slick by suffixing it with a .getOrElse(theDefault), or you make the DB accepts NULL (from a None value) and defaults it using some trigger.

Multiple parameter values

I have a problem with BIRT when I try to pass multiple values from report parameter.
I'm using BIRT 2.6.2 and eclipse.
I'm trying to put multiple values from cascading parameter group last parameter "JDSuser". The parameter is allowed to have multiple values and I'm using list box.
In order to be able to do that I'm writing my sql query with where-in statement where I replace text with javascript. Otherwise BIRT sql can't get multiple values from report parameter.
My sql query is
select jamacomment.createdDate, jamacomment.scopeId,
jamacomment.commentText, jamacomment.documentId,
jamacomment.highlightQuote, jamacomment.organizationId,
jamacomment.userId,
organization.id, organization.name,
userbase.id, userbase.firstName, userbase.lastName,
userbase.organization, userbase.userName,
document.id, document.name, document.description,
user_role.userId, user_role.roleId,
role.id, role.name
from jamacomment jamacomment left join
userbase on userbase.id=jamacomment.userId
left join organization on
organization.id=jamacomment.organizationId
left join document on
document.id=jamacomment.documentId
left join user_role on
user_role.userId=userbase.id
right join role on
role.id=user_role.roleId
where jamacomment.scopeId=11
and role.name in ( 'sample grupa' )
and userbase.userName in ( 'sample' )
and my javascript code for that dataset on beforeOpen state is:
if( params["JDSuser"].value[0] != "(All Users)" ){
this.queryText=this.queryText.replaceAll('sample grupa', params["JDSgroup"]);
var users = params["JDSuser"];
//var userquery = "'";
var userquery = userquery + users.join("', '");
//userquery = userquery + "'";
this.queryText=this.queryText.replaceAll('sample', userquery);
}
I tryed many different quote variations, with this one I get no error messages, but if I choose 1 value, I get no data from database, but if I choose at least 2 values, I get the last chosen value data.
If I uncomment one of those additional quote script lines, then I get syntax error like this:
The following items have errors:
Table (id = 597):
+ An exception occurred during processing. Please see the following message for details: Failed to prepare the query execution for the
data set: Organization Cannot get the result set metadata.
org.eclipse.birt.report.data.oda.jdbc.JDBCException: SQL statement does not return a ResultSet object. SQL error #1:You have an error in
your SQL syntax; check the manual that corresponds to your MySQL
server version for the right syntax to use near 'rudolfs.sviklis',
'sample' )' at line 25 ;
com.mysql.jdbc.exceptions.jdbc4.MySQLSyntaxErrorException: You have an error in your SQL syntax; check the manual that corresponds to
your MySQL server version for the right syntax to use near
'rudolfs.sviklis', 'sample' )' at line 25
Also, I should tell you that i'm doing this by looking from working example. Everything is the same, the previous code resulted to the same syntax error, I changed it to this script which does the same.
The example is available here:
http://developer.actuate.com/community/forum/index.php?/files/file/593-default-value-all-with-multi-select-parsmeter/
If someone could give me at least a clue to what I should do that would be great.
You should always use the value property of a parameter, i.e.:
var users = params["JDSuser"].value;
It is not necessary to surround "userquery" with quotes because these quotes are already put in the SQL query arround 'sample'. Furthermore there is a mistake because userquery is not yet defined at line:
var userquery = userquery + users.join("', '");
This might introduce a string such "null" in your query. Therefore remove all references to userquery variable, just use this expression at the end:
this.queryText=this.queryText.replaceAll('sample', users.join("','"));
Notice i removed the blank space in the join expression. Finally once it works finely, you probably need to make your report input more robust by testing if the value is null:
if( params["JDSuser"].value!=null && params["JDSuser"].value[0] != "(All Users)" ){
//Do stuff...
}

How does hibernate use an empty string for an equality restriction?

I have a column that potentially has some bad data and I can't clean it up, so I need to check for either null or empty string. I'm doing a Hibernate Criteria query so I've got the following that returns incorrectly right now:
Session session = getSessionFactory().openSession();
Transaction tx = session.beginTransaction();
Criteria myCriteria = session.createCriteria(Object);
...
myCriteria.add(Restrictions.or(Restrictions.isNull("stringColumn"),
Restrictions.eq("stringColumn", "")));
List<Objects> list = myCriteria.list();
I can't get it to properly return the results I'd expect. So as an experiment I changed the second restriction to read:
Restrictions.eq("stringColumn", "''")
And it started returning the expected results, so is hibernate incorrectly translating my empty string (e.g. "") into a SQL empty string (e.g. ''), or am I just doing this wrong?
With HSQL (and Derby) and the following values:
insert into FOO values (1, 'foo');
insert into FOO values (2, 'bar');
insert into FOO values (3, NULL);
insert into FOO values (4, '');
You criteria query
Criteria crit = session.createCriteria(Foo.class);
crit.add(Restrictions.or(Restrictions.isNull("name"),
Restrictions.eq("name", "")));
crit.list();
returns:
Foo [id=3, name=null]
Foo [id=4, name=]
As expected.
What database are you using? Could it be Oracle?
It seems like you're doing it wrong. null in Java maps to NULL in SQL, and empty String ("") in Java maps to empty string in SQL ('')