SQL simulator on Prolog - sql

i need to do a SQL simulator on Prolog. i need to simulate some functions like create_table, insert, delete, update_table, select_table, drop_table, show_table, etc. I am learning how to do asserts and retracts but im getting some errors in my first function create_table(N,A) where N is the name of the table and A a list with the atributtes
An example is create_table("student",["name","lastname","age"]). This will create my table named "student" with the atributes ["name","lastname","age"].
I was searching how to work with assert and i see i need to do dynamic before making assert, then my code is.
len([],0).
len([_|T],N) :- len(T,X), N is X+1.
create_table(_, []):-!.
create_table(N, Atributos):- len(Atributos, L), dynamic N/L, assert(N(Atributos)).
But i get this error :7: Syntax error: Operator expected on this line
create_table(N, Atributos):- len(Atributos, L), dynamic N/L, assert(N(Atributos)).
What im doing wrong? excuse me, i dont speak good english.

From the error message, seems you're using SWI-Prolog....
Your code could be (note that len/2 can be replaced by the builtin length/2)
create_table(N, Atributos):-
length(Atributos, L),
dynamic(N/L),
T =.. [N|Atributos], % this missing 'constructor' was the cause of the error message
assert(T). % this is problematic
There is an important 'design' problem: the CREATE TABLE SQL statement works at metadata level.
If you do, for instance,
?- assertz(student('Juan', 'Figueira', 20)).
pretending that the predicate student/3 holds table data, you're overlapping data and metadata

using dynamic/1 and assert is a tricky non-logical aspect of Prolog, and dynamically creating dynamic predicates is really unusual. Fundamentally you cannot have a Prolog query with the predicate name as a variable e.g.
query(N,X) :- N=student, N(X).
My suggestion is you remove a layer of complexity and have one dynamic predicate 'table', and assert your SQL tables as new 'table' clauses i.e.
:- dynamic table/2.
:- assertz(table(student,['Joe','Young',18])).
query(N,X) :- table(N,X).
:- query(student,[Name,Lastname,Age]).

Related

Understanding the "Not found: Dataset ### was not found in location US" error

I know this topic has come up many times but still here I am. Data processing location seems consistent (dataset, US; query: US) and I am using backticks & long format in the FROM clause
Below are two sequences of code. The first one works perfectly:
SELECT station_id
FROM `bigquery-public-data.austin_bikeshare.bikeshare_stations`
Whereas the following returns an error message:
SELECT bikeshare_stations.station_id
FROM `bigquery-public-data.austin_bikeshare`
Not found: Dataset glassy-droplet-347618:bigquery-public-data was not found in location US
My question, thus, is why do the first lines of text work while the second doesn't?
You need to understand the different parts of the backticks:
bigquery-public-data is the name of the project;
austin_bikeshare is the name of the schema (aka dataset in BQ); and
bikeshare_stations is the name of the table/view.
Therefore, the shorter format you are looking for is: austin_bikeshare.bikeshare_stations (instead of bigquery-public-data.austin_bikeshare).
Using bigquery-public-data.austin_bikeshare means that you have a schema called bigquery-public-data that contains a table called austin_bikeshare , when this is not true.

PyPika control order of with clauses

I am using PyPika (version 0.37.6) to create queries to be used in BigQuery. I am building up a query that has two WITH clauses, and one clause is dependent on the other. Due to the dynamic nature of my application, I do not have control over the order in which those WITH clauses are added to the query.
Here is example working code:
a_alias = AliasedQuery("a")
b_alias = AliasedQuery("b")
a_subq = Query.select(Term.wrap_constant("1").as_("z")).select(Term.wrap_constant("2").as_("y"))
b_subq = Query.from_(a_alias).select("z")
q = Query.with_(a_subq, "a").from_(a_alias).select(a_alias.y)
q = q.with_(b_subq, "b").from_(b_alias).select(b_alias.z)
sql = q.get_sql(quote_char=None)
That generates a working query:
WITH a AS (SELECT '1' z,'2' y) ,b AS (SELECT a.z FROM a) SELECT a.y,b.z FROM a,b
However, if I add the b WITH clause first, then since a is not yet defined, the resulting query:
WITH b AS (SELECT a.z FROM a), a AS (SELECT '1' z,'2' y) SELECT a.y,b.z FROM a,b
does not work. Since BigQuery does not support WITH RECURSIVE, that is not an option for me.
Is there any way to control the order of the WITH clauses? I see the _with list in the QueryBuilder (the type of variable q), but since that's a private variable, I don't want to rely on that, especially as new versions of PyPika may not operate the same way.
One way I tried to do this is to always insert the first WITH clause at the beginning of the _with list, like this:
q._with.insert(0, q._with.pop())
Although this works, I'd like to use a PyPika supported way to do that.
In a related question, is there a supported way within PyPika to see what has already been added to the select list or other parts of the query? I noticed the q.selects member variable, but selects is not part of the public documentation. Using q.selects did not actually work for me when using our project's Python version (3.6) even though it did work in Python 3.7. The code I was trying to use is:
if any(field.name == "date" for field in q.selects if isinstance(field, Field))
The error I got was as follows:
def __getitem__(self, item: slice) -> "BetweenCriterion":
if not isinstance(item, slice):
> raise TypeError("Field' object is not subscriptable")
Thank you in advance for your help.
I could not figure out how to control the order of the WITH clauses after calling query.with_() (except for the hack already noted). As a result, I restructured my application to get around this problem. I am now calling query.with_() before building up the rest of the query.
This also made my related question moot, because I no longer need to see what I've already added to the query.

Select last 30 days rows from MARA using SSIS

I'm trying to select rows for last date change = 30 days.
I tried LAEDA = ( sy-datum -30 ) in where clause, but it always generated error.I connect to sap Abap database.
The message error:
[EIS-Material 1] Error: ERPConnect.ERPException: Error while
receiving function return values: SYSTEM_FAILURE An error has occurred
while parsing a dynamic entry. at
ERPConnect.RFCAPI.ReceiveFunctionResults(UInt32 connectionHandle,
RFC_PARAMETER[] importing, RFC_PARAMETER[] changing, RFC_TABLE[]
tables, Encoding apiEncoding) at
ERPConnect.RFCFunction.ReceiveFunctionArguments(RFC_TABLE[]&
apiTables) at ERPConnect.RFCFunction.CallClassicAPI() at
ERPConnect.RFCFunction.ExecuteRFC(Byte[] tid) at
XtractKernel.Extractors.TableExtractor.GetPackage(RFCFunction& func)
at XtractKernel.Extractors.TableExtractor.Extract() at
XtractKernel.Extractors.ExtractorBase`1.Extract(ProcessResultCallback
processResult) at XtractIS.XtractSourceTable.PrimeOutput(Int32
outputs, Int32[] outputIDs, PipelineBuffer[] buffers) at
Microsoft.SqlServer.Dts.Pipeline.ManagedComponentHost.HostPrimeOutput(IDTSManagedComponentWrapper100
wrapper, Int32 outputs, Int32[] outputIDs, IDTSBuffer100[] buffers,
IntPtr ppBufferWirePacket)
So you are using a third party tool to extract data from an SAP system. According to the error message, the toole makes a Remote Function Call (RFC) and handing the SQL to the ABAP backend. Then your where condition must be valid ABAP/Open SQL syntax, regardless of the database behind.
Your call (simplified) would look like this in ABAP (with new #-syntax):
DATA(lf_dat) = sy-datum - 30.
SELECT matnr
FROM mara
WHERE laeda >= #lf_dat
INTO TABLE #DATA(lt_matnr)
.
The problem is, that you are not allowed to make this calculation within the the statement, as far as I know, so you have to use a variable. But since your third party tool only allows you to write a where condition I see no way to handle this, except with a static date in the condition:
laeda >= '20190106' "YYYYMMDD
You can add the ABAP tag to your question to attract more specialists on this ABAP specific topic.
I see in the Xtract IS online help that there's a custom function module named Z_THEO_READ_TABLE installed at ABAP side, which executes the SQL sent by Xtract IS. The module is provided in 2 flavors, one being for ABAP >= 740 SP 5, so I guess it's a version for ABAP SQL Strict Mode.
So, I thought that maybe you could write this ABAP-like Where Clause by using a "host expression", which is valid in ABAP SQL Strict Mode :
LAEDA = #( sy-datum - 30 )
Based on the error message you have, "An error has occurred while parsing a dynamic entry", I guess that this function module does something like SELECT (dyn-columns) FROM (dyn-table) WHERE (dyn-condition), i.e. all elements are dynamically defined at run time.
Unfortunately, the "ABAP documentation sql_cond - (cond_syntax) says that "Host expressions are not allowed in dynamic logical expressions."
So long, impossible to make a where clause as you wish.
There are probably many ways to get around this limit (like creating a SAPquery or BAPI in SAP and calling it from Xtract IS, etc.) but that's another question.
In mySQL / MariaDB, this works:
select ...
from ...
where date >= DATE_ADD(CURDATE(), INTERVAL -30 DAY)
but we need to know what database you are working with.
You may try it, if you use SQL database:
Select DATEADD(Month, -1, getdate())
You cannot specify ABAP formula like that through SAP Open SQL.
Not to directly resolve your challenge (as you have product limitation), here is how dynamic filter is achieved through AecorSoft tool:
(DT_WSTR, 4)(DATEPART("yy" , GETDATE())) + RIGHT("0" + (DT_WSTR, 4)DATEPART("mm" , GETDATE()),2) + RIGHT("0" + (DT_WSTR, 4)DATEPART("dd" , GETDATE()),2)
For complete use case, you can check the blog SAP Table Delta Extract Made Easy through Dynamic Filters

Endeca UrlENEQuery java API search

I'm currently trying to create an Endeca query using the Java API for a URLENEQuery. The current query is:
collection()/record[CONTACT_ID = "xxxxx" and SALES_OFFICE = "yyyy"]
I need it to be:
collection()/record[(CONTACT_ID = "xxxxx" or CONTACT_ID = "zzzzz") and
SALES_OFFICE = "yyyy"]
Currently this is being done with an ERecSearchList with CONTACT_ID and the string I'm trying to match in an ERecSearch object, but I'm having difficulty figuring out how to get the UrlENEQuery to generate the or in the correct fashion as I have above. Does anyone know how I can do this?
One of us is confused on multiple levels:
Let me try to explain why I am confused:
If Contact_ID and Sales_Office are different dimensions, where Contact_ID is a multi-or dimension, then you don't need to use EQL (the xpath like language) to do anything. Just select the appropriate dimension values and your navigation state will reflect the query you are trying to build with XPATH. IE CONTACT_IDs "ORed together" with SALES_OFFICE "ANDed".
If you do have to use EQL, then the only way to modify it (provided that you have to modify it from the returned results) is via string manipulation.
ERecSearchList gives you ability to use "Search Within" functionality which functions completely different from the EQL filtering, though you can achieve similar results by using tricks like searching only specified field (which would be separate from the generic search interface") I am still not sure what's the connection between ERecSearchList and the EQL expression above?
Having expressed my confusion, I think what you need to do is to use String manipulation to dynamically build the EQL expression and add it to the Query.
A code example of what you are doing would be extremely helpful as well.

ActiveRecord where clause error

I'm a newbie to rails.I have a model called OfflineExport. In the table I have data like this
#<OfflineExport id: 2,
parameters:
{"project_id"=>"3",
"type"=>"submissions",
"filters"=>{"task_type"=>"",
"corrections"=>"", "grade"=>"",
"min_duration"=>"", "after"=>"",
"max_duration"=>"", "reviews"=>"",
"before"=>""},
"send_email"=>"true",
"options"=>{"offline_record_id"=>2}}>
Am trying to fetch parameters["project_id"] in where clause like
OfflineExport.where("parameters[project_id] = '3'")
But am getting error like:
ActiveRecord::StatementInvalid: PGError: ERROR: cannot subscript type text because it is not an array
can anyone help me in solving this?
It seems that you have a serialized column in your model. Something like this: serialize :parameters. This means the data is stored in the database not in an easily readable format, which leads that you can not query on it. Same as here.
Solution: extract the field you want to query on, and make a column for it.