Here is how to query a person:
<where>
<eq>
<fieldref name="PersonFieldName"/>
<value type="User">User Display Name</value>
</eq>
</where>
Replace PersonFieldName with the internal Name of the Field.
The two important things here: Value Type is “User”, and the String to
search for is the Display Name. So if you have a user called “John Doe”
whose login is “mydomain\jdoe”, you have to search for “John Doe”, not
for “mydomain\jdoe”.
There is an obvious drawback to this: What if you have two users called John Doe?
There are two workarounds. The first one: Go to the properties of the
field in the list, and at the bottom you can change “Show Field” to
“Account”.
This has the advantage that you can use the “domain\username” Syntax
now. The drawback: The field looks bad in the list as it does now show
the Login, not the Display Name with the neat presence status.
The second workaround: Use the undocumented LookupId property and search for the numeric ID:
<where>
<eq>
<fieldref name="PersonFieldName" LookupId="TRUE"/>
<value type="int">UserID</value>
</eq>
</where>
The UserID is not the “domain\username”, but the numeric internal ID
(SPUser.ID). When used in a workflow, you can easily access this
through workflowProperties.OriginatorUser.ID. In a Web Part, SPContext.Current.Web.CurrentUser.ID does the trick.