Spacing Issue when using fmt.Sprintf to create a command

I am basically dealing with GOLang and C code, i have created the below command and passing that
as an argument to C code with proper C to GO command, C.CString(sqlcmd). The C code does the concatenation of select frm table_name and other things required to form the complete query.
In the GOLang code i just need to create the required conditions for sql command.

But am facing an issue in this.
I have created a sql command using fmt.Sprintf as follows

sqlcmd = fmt.Sprintf("WHERE date=‘%s’ AND division=‘%s’ AND flag=‘%s’ AND block_no=‘%s’ AND case_no=‘%s’ frame_time||frame_division >= ‘%s’||‘%s’ ", date, division, flag, Block_no, Case_no, frame_time, frame_division)

When i print this command it gets printed as below

fmt.Printf(“sqlcmd:%s”)
sqlcmd: WHERE onair_date=20171002 AND service_division=‘SV01 ’ AND test_flag=’ ’ AND block_no=’ ’ AND case_no=‘00’

when i pass sqlcmd as argument and code gets executed i gives the below error

sh: -c: line 0: unexpected EOF while looking for matching `''
sh: -c: line 1: Syntax error: End of unexpected file
sh: -c: line 0: unexpected EOF while looking for matching `''
sh: -c: line 1: Syntax error: End of unexpected file

For debugging purpose,

i hard coded the same output command to sqlcmd and passed it as arguments and it works perfectly fine without any problem, even the DB query works perfectly and displays as per the created request.

sqlcmd = “WHERE onair_date=20171002 AND service_division=‘SV01 ’ AND test_flag=’ ’ AND block_no=’ ’ AND case_no=‘00’”

But when ever i pass the sqlcmd directly as argument i get the above error.

I checked for spaces in the hard coded query and and the query generated from fmt.Sprintf i didn’t fine any.
Can anyone give any help or the correct method to frame the command.

This is a very bad idea, it opens your code to SQL Injection (see xkcd: Exploits of a Mom for the results).

Use placeholders as described for database/sql.

My entire code base is in C, and am converting to GOLang systematically, i have a wrapper function which accepts this arguments and i am bound to do this way can you please suggest how to go about this issue and why i get

sh: -c: line 0: unexpected EOF while looking for matching `''
sh: -c: line 1: Syntax error: End of unexpected file
sh: -c: line 0: unexpected EOF while looking for matching `''
sh: -c: line 1: Syntax error: End of unexpected file

The above errors when i pass the sqlcmd from the output of fmt,Sprintf directly, but when i send the same command hard coded i don’t get this error and also the DB executed the command perfectly and gives the output as expected.

It is hard to tell what is going on without a Short, Self Contained, Correct (Compilable), Example. The error looks like you are using sh to execute some script(?). How do you do that?
With what arguments?

Could you please make runnable example of your Go code at https://play.golang.org/?

1 Like

You miss some apostrophes here.

@geosoft1 : yeah i have missed apostrophes.

@lutzhorn :Here is the code that will explain the issue that i am facing, i have simulated the same in this code.

The GOlang code goes as follows.

type Edu_db struct {
    School [4 + 1]byte
    PU     [3 + 1]byte
    BE     [3 + 1]byte
    Mtech  [31 + 1]byte
    }

func info_filling () {
	school := "LFPS"
    pu := "PES"
    engg := "BNM"
    mtech := "Manipal Institute of technology"
    copy(db.School[:], school)
    copy(db.PU[:], pu)
    copy(db.BE[:], engg)
    copy(db.Mtech[:], mtech)

//db_str := fmt.Sprintf("School='%s' AND PU='%s' AND Engg='%s' AND Mtech='%s'", db.School, db.PU, db.BE, db.Mtech)
 fmt.Println("db_str:", db_str)
C.info_fromGO(C.CString(db_str))

}

The o/p in golang code is:

db_str: School=‘ABC’ AND PU=‘EFG’ AND Engg=‘HIJ’ AND Mtech=‘Manipal Institute of technology’

Now this is passed to C code,

C.info_fromGO(C.CString(db_str))

and my C code is as follows

void info_fromGO(char *str) {
	printf("str:%s\n", str);
}

The o/p of C code is :

str: School='ABC

What am expecting is :

School=‘ABC’ AND PU=‘EFG’ AND Engg=‘HIJ’ AND Mtech=‘Manipal Institute of technology’

This is the issue am facing when ever i send a string which is created in GOlang to C code, it sees an ‘\0’
which is end of string and stops at that point.

Where as if i hard code db_str in Golang and send the same string to C

db_str = “School=‘ABC’ AND PU=‘EFG’ AND Engg=‘HIJ’ AND Mtech=‘Manipal Institute of technology’”

The o/p in C code is :

School=‘ABC’ AND PU=‘EFG’ AND Engg=‘HIJ’ AND Mtech=‘Manipal Institute of technology’

since C will send the end of string ‘\0’ just before ending of double quotes,
can any one suggest any alternate method to achieve the same without using fmt.Sprintf so that my C code will print

School=‘ABC’ AND PU=‘EFG’ AND Engg=‘HIJ’ AND Mtech=‘Manipal Institute of technology’

Is there any other way to concatenate these structure elements and i cannot change data types of the GOlang Structure elements

Your code is very, very strange. Maybe because you are converting it from C. To begin with,

type Edu_db struct {
    School [4 + 1]byte
    PU     [3 + 1]byte
    BE     [3 + 1]byte
    Mtech  [31 + 1]byte
}

This is not how things are done in Go. You might want byte slices ([]byte), probably actually strings but certainly not byte arrays. You appear to add an extra byte for zero termination? Strings are not zero terminated in Go.

Then,

school := "LFPS"
copy(db.School[:], school)

Your db.School is now {'L', 'F', 'P', 'S', \0} because it’s a [5]byte, initialized to all zeroes, and you copied in four bytes.

Then,

db_str := fmt.Sprintf("School='%s' ...", db.School)

which becomes School='LFPS\0' ... because of the above and of course breaks in C land.

In short, try this:

type Edu_db struct {
    School string
    PU     string
    BE     string
    Mtech  string
}

And, more importantly, make sure to actually learn Go before trying to interface it with C. There is trickiness in the interface, and it depends on the implementation details of both C and Go. You need to understand both.

2 Likes

This topic was automatically closed 90 days after the last reply. New replies are no longer allowed.